System health
How well the CSS follows the system, measured on every release. Each number has a ceiling; a release that makes one worse doesn't ship.
A rule nobody checks is a suggestion. These numbers are the parts of the system a machine can check, read straight from the game's CSS by npm run ds:audit on every build of this page.
The numbers
| Measure | Now | Ceiling |
|---|---|---|
| Hardcoded colours literals in component CSS; each one can't follow the mode swap | 21 | 21 |
| Legacy token names references to retired aliases | 372 | 372 |
| Font sizes distinct sizes; no type scale yet | 28 | 28 |
| Corner radii distinct values | 21 | 21 |
| Durations distinct motion timings | 31 | 31 |
| Faint text rules using --fg-faint as text (fails AA) | 3 | 3 |
| Unused CSS rules styling classes nothing renders | 122 | 122 |
| Long clues over 80 characters | 20 | 20 |
From npm run ds:audit at 3.25.7. A release that raises any number past its ceiling is stopped by the release check; a release that lowers one lowers the ceiling with it.
How the ceiling works
This is a ratchet, not a target. The ceilings started at the measured values in 3.23.6, so the system was allowed to be exactly as untidy as it already was, and no more. Each fix moves a ceiling down, and the check then holds it there. The point isn't a clean score on day one; it's that the score can only move one way.
Contrast, live
| Token | Dark · ground | Dark · card | Light · ground | Light · card |
|---|---|---|---|---|
--fgbody text | 12.70AAA | 10.14AAA | 12.70AAA | 13.75AAA |
--fg-softsecondary text | 6.36AA | 5.07AA | 4.78AA | 5.17AA |
--fg-fainttertiary | 3.19UI only | 2.55decorative | 2.29decorative | 2.48decorative |
--earnedearned (green) | 8.98AAA | 7.17AAA | 5.71AA | 6.18AA |
--dangerrefused (rose) | 8.52AAA | 6.80AA | 7.54AAA | 8.16AAA |
--focusfocus ring | 5.27AA | 4.21UI only | 5.38AA | 5.82AA |
WCAG contrast, computed from the tokens on every build. AA needs 4.5:1 for text, 3:1 for large text and UI.
Body text, secondary text and both semantic hues pass AA on the ground and on cards, in both modes. --fg-faint is below the text floor and is for non-text only; three rules still use it as text (the first item below).
What's next
From the 3.23.6 audit, in the order they'll ship. Each step lowers numbers in the table above.
| Release | Work | Moves |
|---|---|---|
| 3.23.7 (patch) | The tile's highlight fades over 0.5s instead of 0.08s (see Tile); faint text becomes --fg-soft; the overlay follows light mode; the pale blue maps to existing roles; one focus colour; "Clear" gets a 44px target; "Play again" and "Next round" lose the replay glyph, so primaries are text only | hardcoded colours, faint text |
| Next feature release | Rename every legacy token name to its canonical role (identical values, no visual change), then delete the aliases; delete the unused CSS after a visual pass | legacy names, unused CSS |
| After that | Scales as tokens, one family per release, each mocked first: type, corner radius, spacing, motion | font sizes, radii, durations |
Where the audit stands
On a 0 to 4 maturity scale the system is a working library (stage 2): tokens, components, docs, a changelog and decision records. Two things separate it from a managed system:
- Scales. Type, spacing, radius and motion are values today, not tokens, so changing one means finding every use.
- Finished deprecations. The alias layer and the unused CSS are still in the file. They're harmless to players and expensive to everyone who reads the code.
The full report, with every finding and how it was measured, is design-system/audits/2026-10-12-audit-3.23.6.md in the repo.