Context
tests/contrast.spec.ts (from #755) enforces the palette in two ways: it checks token-pair contrast ratios parsed live out of app/globals.css, and it scans every .tsx under components/ and app/ for measured-failing raw greys.
The second half only holds where components actually use the tokens. Today the coverage is lopsided:
- Tokenized —
app/layout.tsx, app/page.tsx, the whole app/docs/** tree, components/layout/*, components/landing/*, components/docs/*
- Still raw Tailwind greys and blues —
components/offramp/* (~15 files; ScorecardCard.tsx ~43 occurrences, RateTable.tsx and ExecuteDrawer.tsx ~34 each, AnchorProfile.tsx ~28), app/anchors/standings/page.tsx (~21), app/admin/disputes/page.tsx (~9)
The guard keeps those files from using known-bad greys, but nothing ties them to the palette. A theme change reaches half the app and stops.
Requirements
- Replace raw
text-gray-* / bg-gray-* / text-blue-* / border-gray-* with the token classes (text-primary-text, text-secondary-text, bg-bg-subtle, border-control-border, text-accent, …) across components/offramp/*, app/anchors/**, app/admin/**
- Shrink the
EXEMPT list in tests/contrast.spec.ts as files are converted — the spec already self-checks that every exemption is still needed, so a stale entry fails
- No visual redesign. This is a substitution pass; anything that looks different afterward is a bug in the substitution
Verification
npx vitest run tests/contrast.spec.ts, then npm run dev and compare /offramp, /anchors/standings, /admin/disputes in both themes against main.
Notes
Deliberately kept out of the palette-swap PR (#749): ~250 occurrences across 17 files would make a palette regression indistinguishable from a substitution error.
Context
tests/contrast.spec.ts(from #755) enforces the palette in two ways: it checks token-pair contrast ratios parsed live out ofapp/globals.css, and it scans every.tsxundercomponents/andapp/for measured-failing raw greys.The second half only holds where components actually use the tokens. Today the coverage is lopsided:
app/layout.tsx,app/page.tsx, the wholeapp/docs/**tree,components/layout/*,components/landing/*,components/docs/*components/offramp/*(~15 files;ScorecardCard.tsx~43 occurrences,RateTable.tsxandExecuteDrawer.tsx~34 each,AnchorProfile.tsx~28),app/anchors/standings/page.tsx(~21),app/admin/disputes/page.tsx(~9)The guard keeps those files from using known-bad greys, but nothing ties them to the palette. A theme change reaches half the app and stops.
Requirements
text-gray-*/bg-gray-*/text-blue-*/border-gray-*with the token classes (text-primary-text,text-secondary-text,bg-bg-subtle,border-control-border,text-accent, …) acrosscomponents/offramp/*,app/anchors/**,app/admin/**EXEMPTlist intests/contrast.spec.tsas files are converted — the spec already self-checks that every exemption is still needed, so a stale entry failsVerification
npx vitest run tests/contrast.spec.ts, thennpm run devand compare/offramp,/anchors/standings,/admin/disputesin both themes againstmain.Notes
Deliberately kept out of the palette-swap PR (#749): ~250 occurrences across 17 files would make a palette regression indistinguishable from a substitution error.