Per review on #7009: the contrast check was warn-only and opt-in, so it would
never catch regressions. Enforce it here (the follow-up PR):
- theme-lint.mjs `contrast` mode now exits non-zero on any sub-floor pair
- wired into `task frontend:lint:colors` (runs in the blocking lint gate)
- fixed the two failing pairs: --c-text-subtle on dark/portal-dark surfaces
(3.36/3.67 → 4.74/5.18) by adding --p-zinc-250 and pointing dark subtle at it
All text-on-surface / on-primary pairs now clear WCAG AA per theme.
Add a blocking 'code-colors' mode to theme-lint: default-deny with layered
exemptions (structural; var()/readColor/canvas/pdf-lib contexts; a
// theme-allow-color opt-out; exempt paths for rendering/vendor/config/
illustration areas). File list from 'git ls-files' (no directory walk).
Wired into 'task frontend:lint:colors'; README + script header updated.
Also removes the temporary color-migration-audit.md scratch file.
Add a blocking 'css-colors' mode to theme-lint that flags any hardcoded
colour in source .css under editor/src (primitives.css + generated
output.css exempt). File list is sourced from 'git ls-files' rather than a
directory walk, so there's no readdir→readFile path; comments and structural
black/white/transparent are ignored. Wired into 'task frontend:lint:colors'.
Update theme README + script header for the expanded palette and the now
app-wide enforcement.
Migrated all remaining legacy-alias consumers (incl. stories/tests) to --c-*
(199 refs / 58 files), promoted the computed aliases to first-class tokens
(--c-accent-fg made universal on :root; --c-primary-tint / --c-primary-border
added), then removed compat.css, its @import, and its linter entry. No legacy
colour-alias layer remains; build + theme-lint green.
The larger theme.css/tokens.css legacy definition files are a separate cleanup.
Static scanners (Aikido) flag the directory-listing→file-read flow as a
file-inclusion risk. Read a fixed THEME_FILES list via constant paths instead
(matching the other unflagged scripts); readdir is now only used to fail if a
new theme .css isn't registered, so coverage still can't lapse.