Skip to content

Declare the primary colour scale where Tailwind v4 reads it - #3

Merged
capazme merged 3 commits into
mainfrom
fix/tailwind-primary-scale
Aug 29, 2026
Merged

Declare the primary colour scale where Tailwind v4 reads it#3
capazme merged 3 commits into
mainfrom
fix/tailwind-primary-scale

Conversation

@capazme

@capazme capazme commented Aug 29, 2026

Copy link
Copy Markdown
Owner

The defect

frontend/tailwind.config.js is a Tailwind v3-style config. The project runs
Tailwind v4 (@import "tailwindcss" + @theme in src/index.css) and v4
only reads a JS config when the stylesheet asks for it with @config. There is
no such directive, so that file never reaches the build.

Consequence: every primary-<number> class in the app generated no CSS at
all
— 568 occurrences across 60 files. Among them:

  • 38 buttons across 28 files carry text-white over a bg-primary-600 that
    paints nothing: white text on a white surface. The Forum alone holds 12 of
    those files; also CommandPalette, HistoryView, AddToDossierPopover,
    CompareView, StudyMode, Layout, and five modals.
  • 51 focus rings (focus:ring-primary-500, focus-visible:ring-primary-500)
    — including the one CLAUDE.md prescribes as the accessibility convention for
    keyboard-reachable collapsibles. It has never been drawn.
  • 46 text-primary-600, 32 bg-primary-50, and a long tail of borders and
    hover states.

No build error, no lint warning, no runtime warning. An undeclared token is
indistinguishable from a typo.

The fix

Eleven tokens in the @theme block — the only place v4 reads. Values are
Tailwind's own blue, byte-identical to what the config already declared, so
nothing is redesigned; the classes the app already wrote simply start resolving.

--color-primary is deliberately untouched. It is a different token, fed by
hsl(var(--primary)), and bg-primary has 213 call sites. Loading the JS
config with @config would have put both at risk: that file declares primary
as a scale with no DEFAULT, and redeclares the semantic aliases without their
hsl() wrapper (background: 'var(--background)' against --background: 0 0% 100%). Adding the scale to @theme avoids the question entirely.

The other 563 call sites are not edited. The token was missing; the classes were
always right.

Guarding it

src/theme.test.ts compiles the real index.css through PostCSS and asserts
every step of the scale resolves — and, in the same breath, that bg-primary,
ring-ring and bg-background still do. Written before the fix and watched
fail. This is the test that would have caught the bug when it was introduced.

tailwind.config.js keeps a header saying it is not loaded. It is not deleted:
its fate is a separate decision. What it still declares and still cannot apply —
font-sans/font-serif/font-mono (whose fonts are never fetched anyway),
shadow-glow, shadow-glass-lg, animate-shimmer — is 4 call sites in total.

Verification

  • npx vitest run src/theme.test.ts — red before the change, green after
  • npm run test 189 passed · npm run build clean · npm run lint clean
  • Built CSS now contains bg-primary-600, text-primary-600,
    ring-primary-500 (×16), bg-primary-50 (×24), border-primary-200
  • Built CSS still resolves --color-primary: hsl(var(--primary))
  • Before/after compared by rendering the same markup against both real builds

Note for the reviewer

~59 files change appearance at once — in the direction of something missing
becoming visible
, not the reverse. A pass over search, dossier, workspace and
especially the Forum is worth doing after merge.

🤖 Generated with Claude Code

capazme and others added 3 commits August 29, 2026 16:50
tailwind.config.js is a v3-style config and v4 never loads it: there is no
@config directive in index.css. Every `primary-<number>` class the app wrote
therefore generated no CSS at all — 568 across 60 files, including 38 buttons
carrying text-white over a bg-primary-600 that painted nothing, and the
focus-visible:ring-primary-500 CLAUDE.md prescribes for accessibility.

Move the scale into the @theme block, which is the only place v4 reads. The
values are Tailwind's own blue, unchanged. `--color-primary` is a separate
token and is untouched: bg-primary has 213 call sites and must keep working.

The failure was silent — no build error, no lint warning — so theme.test.ts
compiles the real stylesheet and fails if a step stops resolving.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@capazme
capazme merged commit a9c5161 into main Aug 29, 2026
7 checks passed
@capazme
capazme deleted the fix/tailwind-primary-scale branch August 29, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant