| 94 |
94 |
|
|
| 95 |
95 |
|
| Pair | vs sunken | vs page | vs raised | vs overlay |
|
| 96 |
96 |
|
|---|---:|---:|---:|---:|
|
| 97 |
|
- |
| `content.primary` | 11.19 | 14.38 | 16.74 | 18.06 |
|
| 98 |
|
- |
| `content.secondary` | 8.96 | 11.51 | 13.39 | 14.45 |
|
| 99 |
|
- |
| `content.muted` | 3.72 | 4.78 | 5.56 | 6.00 |
|
|
97 |
+ |
| `content.primary` | 11.42 | 14.68 | 17.08 | 18.43 |
|
|
98 |
+ |
| `content.secondary` | 9.25 | 11.88 | 13.83 | 14.92 |
|
|
99 |
+ |
| `content.muted` | 3.85 | 4.95 | 5.76 | 6.21 |
|
| 100 |
100 |
|
|
| 101 |
101 |
|
`primary` and `secondary` are AAA on every tier. `muted` is AA-text everywhere but the sunken well, where it holds AA-UI, which is what a deliberately recessive tone is for.
|
| 102 |
102 |
|
|
| 104 |
104 |
|
|
| 105 |
105 |
|
| Pair | vs page | vs raised | vs overlay |
|
| 106 |
106 |
|
|---|---:|---:|---:|
|
| 107 |
|
- |
| `border-strong` (derived) | 6.34 | 7.38 | 7.96 |
|
|
107 |
+ |
| `border-strong` (derived) | 6.34 | 7.37 | 7.95 |
|
| 108 |
108 |
|
| `line.border` | 3.11 | 3.62 | 3.90 |
|
| 109 |
109 |
|
| `border-subtle` (derived) | 1.37 | 1.59 | 1.72 |
|
| 110 |
110 |
|
|
| 128 |
128 |
|
|
| 129 |
129 |
|
| Pair | vs sunken | vs page | vs raised | vs overlay |
|
| 130 |
130 |
|
|---|---:|---:|---:|---:|
|
| 131 |
|
- |
| `content.primary` | 16.68 | 14.29 | 11.90 | 10.15 |
|
| 132 |
|
- |
| `content.secondary` | 12.81 | 10.97 | 9.14 | 7.79 |
|
| 133 |
|
- |
| `content.muted` | 5.96 | 5.10 | 4.25 | 3.63 |
|
|
131 |
+ |
| `content.primary` | 17.05 | 14.60 | 12.16 | 10.37 |
|
|
132 |
+ |
| `content.secondary` | 13.10 | 11.22 | 9.34 | 7.97 |
|
|
133 |
+ |
| `content.muted` | 6.09 | 5.22 | 4.35 | 3.71 |
|
| 134 |
134 |
|
|
| 135 |
135 |
|
**Borders on surfaces:**
|
| 136 |
136 |
|
|
| 137 |
137 |
|
| Pair | vs page | vs raised | vs overlay |
|
| 138 |
138 |
|
|---|---:|---:|---:|
|
| 139 |
|
- |
| `border-strong` (derived) | 10.77 | 8.97 | 7.65 |
|
|
139 |
+ |
| `border-strong` (derived) | 11.03 | 9.19 | 7.83 |
|
| 140 |
140 |
|
| `line.border` | 4.33 | 3.61 | 3.08 |
|
| 141 |
141 |
|
| `border-subtle` (derived) | 2.33 | 1.94 | 1.65 |
|
| 142 |
142 |
|
|
| 160 |
160 |
|
|
| 161 |
161 |
|
The consequence to know about: on a light theme a lavender legible as text has to be a deep violet (`#5a41a2`), not the pale tint the word "lavender" suggests. A pale lavender is available to a consumer as a *surface* tint via `mix(surface.page, action.primary, ...)`; it is not what the ink can be.
|
| 162 |
162 |
|
|
|
163 |
+ |
## Why the ink is a greyscale
|
|
164 |
+ |
|
|
165 |
+ |
`content.primary` is `#111111` on the light theme and `#f0f0f0` on the dark, and both are neutral: no warmth is carried in the ink even though every surface under it is warm.
|
|
166 |
+ |
|
|
167 |
+ |
This is the other half of the accent rule. Colour on text has to *mean* something — a severity, a syntax class, a category — and an ink tinted toward the theme's own hue spends that channel on nothing. Neutralising it costs no contrast (the light ink went from 14.38:1 to 14.68:1 against the page) and it makes the warm ground read as ground rather than as a wash over everything. `alloy_tui`'s `text::action` is the one accent-on-text use that is not a severity, and it survives for the reason its own docs give: a key hint *is* the actionable element.
|
|
168 |
+ |
|
|
169 |
+ |
`content.secondary` and `content.muted` are tonal steps of that ink toward the page, so they do pick up a trace of the ground as they recede. That is the ramp working, not a tint: light `muted` lands at `#615f5c`, which is three points off neutral.
|
|
170 |
+ |
|
|
171 |
+ |
Pure black is available and is the wrong choice. The tonal steps are derived by mixing toward the page until they clear a contrast floor against the ink, and from `#000000` that scan lands `muted` at 7.66:1 against the page instead of the ramp's usual ~4.9 — muted text that does not recede. `#111111` keeps the ramp intact.
|
|
172 |
+ |
|
| 163 |
173 |
|
## Why bright red is no longer the accent
|
| 164 |
174 |
|
|
| 165 |
175 |
|
ANSI slot 9 used to resolve to `action.primary`, on the reasoning that the accent was a warm orange-red and so was bright red. That held only while the accent happened to be warm; pointed at a violet it turns every `\e[91m` in the terminal purple. Slot 9 is now `status.danger`, the same relationship slots 10, 11 and 12 have with their normal-intensity counterparts. A program painting an error in bright red is naming red, not naming the theme's accent.
|