Is `--color-on-*` defined against the fill or the muted fill? The bundled themes disagree
- Dominant language
- TypeScript
- Stars
- 13.1k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 687
Description
Building the contrast-pair check in #5281 turned up a question the check cannot answer, because we have not decided it: **is `--color-on-error` defined against `--color-error`, or against `--color-error-muted`?**
The defaults say the former. `--color-on-error` is `#FFFFFF` and `--color-error` is `#E3193B`; white on that fill is 4.70:1, which is only a meaningful number if the label sits on the fill. #5019 is about the dark half of that same pair.
`stone` reads it the other way, deliberately and with comments:
```ts
// Text on top of matching status surface (badge fill, banner content).
'--color-on-error': ['#58413e', '#f9dcd7'], // Red T30 / T90
// Status / Sentiment — T50 from palette for icons/borders (visible color)
'--color-error': ['#58413e', '#dcc0bc'], // Red T30 / T80
'--color-error-muted': ['#f9dcd7', '#dcc0bc'], // Red T90 / T80
```
In light mode `--color-on-error` and `--color-error` are the **same colour**, `#58413e` — 1:1. Nothing is broken on screen, because stone puts the label on `--color-error-muted` (`#f9dcd7`, a fine ratio) and uses `--color-error` for icons and borders. But under the defaults' reading, stone ships an invisible error label.
I measured every bundled theme against the defaults' reading. All seven fail something:
| theme | findings | example |
|---|---|---|
| neutral | 3 | control boundary 1.48:1 light |
| stone | 8 | on-error == error in light (1:1) |
| y2k | 1 | control boundary 1.71:1 dark |
| butter | 1 | control boundary 1.75:1 light |
| chocolate | 5 | white on `#FD0000` error fill, 4.06:1 |
| gothic | 2 | control boundary 2.28:1 both modes |
| matcha | 7 | success label 3.58:1 light |
Some of these are certainly real — chocolate's pure-red error fill with a white label is a near-miss under any reading, and `--color-border-emphasized` under 3:1 is a 1.4.11 problem regardless of what the neighbouring token means. Others are stone-style role disagreements.
I did not touch any of them, and I narrowed #5281 to pairs where a theme hand-wrote exactly one side, so it is silent on all seven. That keeps the tool honest but leaves the real question open:
1. **Decide the contract.** Which token is the fill a `--color-on-*` label sits on? Write it into `astryx docs color` either way — right now a theme author has to guess, and stone and the defaults guessed differently.
2. Then the both-sides-authored case becomes checkable, and #5281 can widen to it.
3. Independently of (1): the `--color-border-emphasized` findings do not depend on the contract. Those look like straightforward bugs in four themes.
Happy to take any of these once (1) is settled — it is a design call, not a tooling one.
Contributor guide
Research direction
Start at the `astryx docs color` entry point and review the defaults, stone theme comments, and findings listed here. Decide and document whether `--color-on-*` is measured against the fill or muted fill; done means the contract is explicit and #5281 can be revisited without guessing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- design, documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100