feat(design): hold the token catalogue to the stylesheet - #544
Merged
Conversation
CLAUDE.md names `design-system.md` as the single source of truth for the tokens, which means contributors read it instead of `index.css`. Nothing checked that the two said the same thing, and they did not. A token table and a `:root` block are never in the same diff, and both look right on their own — the same shape as hardening rule #2, where the same vocabulary in two places needs a parity assertion or each side stays green while the pair drifts. `tokenDocParity.test.ts` checks three directions, none of them redundant: doc -> css a documented token must exist and hold the documented value css -> doc a token in a family this project owns (risk, status, brand, topbar) must be documented EN <-> KO the mirrors must carry identical token tables Prose stays out of scope. Holding translated sentences to equality would make the gate argue about wording, and a gate that argues about wording gets switched off. What the first run found: - `--muted-foreground` documented as `#71717a` when the stylesheet had moved to `#6c6c75` — a W11 accessibility fix the doc never heard about. The contrast figures published beside it (4.63:1, 4.83:1) were the old colour's; the real ones are 4.98:1 and 5.20:1. - `--border` and `--input` documented two channels off (`#e5e5ea` for a value that renders `#e7e7e9`), the stale hex repeated in the stylesheet's own comment. - `--destructive` claiming `#dc2626`, which `0 72% 51%` does not produce — it renders `#dc2828`. The doc and CLAUDE.md both state this token equals `--risk-critical`, and the status-surface section says in as many words that a red meaning "this went badly" should not be a second, slightly different red. It was one. The lightness now carries a decimal (50.6%), which is `#dc2626` exactly, so the claim holds instead of being repeated. Docs move toward the code in the first two cases and the code moves toward the documented design in the third, which is the distinction the gate cannot make for us: it reports that two things disagree, and a person decides which one was the intention. A fourth check guards the hex comments beside HSL triples, since a reader scanning the block trusts them and a stale one is worse than none.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
G0-8 of the differentiation plan. CLAUDE.md names
design-system.mdas the single source of truth for the tokens, which means contributors read it instead ofindex.css. Nothing checked that the two said the same thing, and they did not.A token table and a
:rootblock are never in the same diff, and both look right on their own — the same shape as hardening rule #2, where the same vocabulary in two places needs a parity assertion or each side stays green while the pair drifts.The gate
tokenDocParity.test.tschecks three directions, none of them redundant:--risk-*-foregroundtokens listed as though they had shipped in G0-1, never declaredA fourth check holds the
/* #xxxxxx */comments beside HSL triples to the values they annotate — a reader scanning the block trusts them, so a stale one is worse than none.Prose stays out of scope; only tables are parsed. Holding translated sentences to equality would make the gate argue about wording, and a gate that argues about wording gets switched off.
What the first run found
--muted-foregrounddocumented as#71717awhen the stylesheet had moved to#6c6c75— a W11 accessibility fix the doc never heard about. The contrast figures published beside it (4.63:1, 4.83:1) were the old colour's; the real ones are 4.98:1 and 5.20:1.--border/--inputdocumented two channels off (#e5e5eafor a value that renders#e7e7e9), with the stale hex repeated in the stylesheet's own comment.--destructiveclaiming#dc2626, which0 72% 51%does not produce — it renders#dc2828. The doc and CLAUDE.md both state this token equals--risk-critical, and the status-surface section says in as many words that a red meaning "this went badly" should not be a second, slightly different red. It was one.Docs move toward the code in the first two cases; the code moves toward the documented design in the third. That is the distinction the gate cannot make for us — it reports that two things disagree, and a person decides which one was the intention.
--destructiverenders differently now0 72% 51%→0 72% 50.6%, which is#dc2626on the nose. Two channels, so no screen changes perceptibly, but the destructive button's label contrast goes from 4.60:1 to the 4.63:1 the doc has been publishing. Ifui-gatesreports a pixel diff, the baselines need a refresh rather than an argument.Verification
vitest run— 1670 passed (86 of them this gate's)tsc -b --noEmitclean ·npm run lint0 errors ·token:lint123 unchanged ·ko-style --fail-on S20 findings