Accessibility
This is the floor, not the ceiling.
| Requirement | Detail |
|---|---|
| Targets ≥ 24×24px | WCAG 2.2 SC 2.5.8。Check the width too, because icon-only buttons are square. Where something is deliberately shorter (a slider rail, a checkbox glyph), grow the hit area rather than shrink the target |
| Verify contrast pair by pair | Never by assumption. Recompute every key pairing each time the ramp changes, including the worst case of a small size on a light background |
| Full keyboard coverage | Everything the mouse can reach, in a visible order. Trap focus while a dialog is open and return it to the trigger on close |
[hidden] Must be restored | Any component that sets display:flex or grid overrides the browser's default [hidden]{display:none}. Put it back in the base stylesheet [hidden]{display:none !important}——Off-screen panels leaking into view is exactly how this goes wrong |
| Meaning never rests on colour alone | A red stroke needs a message; a spinner needs text; a selected state needs a checkmark |
Measured key pairings
| Pairing | Measured | Threshold | Result |
|---|---|---|---|
Value / body 900 on white |
17.74:1 | 4.5 | Pass |
Field label 600 on white |
7.56:1 | 4.5 | Pass |
Field label 600 on the pill fill |
6.87:1 | 4.5 | Pass |
Helper text 500 on white |
4.83:1 | 4.5 | Pass |
Helper text 500 on the board |
4.71:1 | 4.5 | Pass |
| White on the primary button | 17.74:1 | 4.5 | Pass |
| White on the emphasis red | 5.27:1 | 4.5 | Pass |
| Filled vs unfilled track | 12.04:1 | 3 | Pass |
| Focus ring on white (the adjacent colour after a 2px offset) This is where the offset carries the load: with it, the ring's adjacent colour is the panel's white; without it, the ring sits against a near-black fill and drops to 2.92:1. |
6.08:1 | 3 | Pass |
Known, deliberately accepted deviations
A spec should record its own debts rather than pretend it has none.
| Item | Measured | Threshold | Why |
|---|---|---|---|
stroke-default as an overlay's only boundary | 1.24:1 | 3:1 | Overlays also carry a shadow, so the boundary doesn't rest on the stroke alone |
stroke-input as an input's only boundary | 1.47:1 | 3:1 | The main source of the overall feel. Meeting the bar would mean darkening it to around #949ba5 , which makes edges visibly heavier — ship an override step instead; it is one token |
| Ruler numbers | 2.47:1 | 4.5:1 | Instrument markings are not content, and the board's dimensions are stated as numbers in the results column |