Skip to content

fix(client): activate the shadcn colour tokens - #4279

Merged
gilgardosh merged 1 commit into
mainfrom
fix/client-activate-shadcn-color-tokens
Aug 24, 2026
Merged

fix(client): activate the shadcn colour tokens#4279
gilgardosh merged 1 commit into
mainfrom
fix/client-activate-shadcn-color-tokens

Conversation

@gilgardosh

Copy link
Copy Markdown
Collaborator

What

components.json declared cssVariables: false and pointed at tailwind.config.cjs — a file that does not exist anywhere in the monorepo. It was deleted during the Tailwind v3 → v4 migration and the theme layer was never ported to v4's CSS-first @theme, so --color-card, --color-muted-foreground, --color-destructive and the rest were never registered, and Tailwind never generated the utilities that reference them.

Roughly 380 usages across ~100 files were compiling to nothing. Verified against two independent build outputs (one from Aug 23, one from Aug 17):

class rules before rules after
text-muted-foreground 0 9
bg-card 0 3
border-border 0 5
text-destructive 0 2
bg-muted 0 11
bg-accent 0 9
bg-gray-900 (control) 25 5

So secondary text rendered at full-strength body colour, bg-muted / bg-accent / bg-card were transparent, and error text rendered black instead of red.

How

src/index.css now defines the token set in @theme on shadcn's gray base (per components.json), with .dark overrides in @layer base.

Two deliberate choices worth reviewing:

  • Plain @theme, not @theme inline. Inline substitutes the literal value into each utility, which would make the .dark overrides below it dead code.
  • Literal oklch() values rather than var(--color-gray-500) references. Tailwind v4 only emits the default palette variables it sees used, so referencing one that happens to be unused elsewhere would resolve to nothing.

Tokens that stand in for an existing default were given that default's value, so classes that were previously no-ops stay visually unchanged: background/card are white (already the page background), foreground is gray-950 (already the inherited text colour), border is gray-200 to match the border-color compatibility rule already in the base layer.

The visible changes are the genuinely broken cases:

  • muted text now reads gray-500 instead of near-black
  • text-destructive reads red-600 instead of black
  • muted / accent / secondary backgrounds gain their light tint

Also fixed

business/client/charts-section.tsx set its axis ticks with hsl(var(--muted-foreground)). That is v3 syntax — the v4 token is --color-muted-foreground and holds a colour, not an HSL triplet, so the hsl() wrapper produced an invalid value and the ticks silently fell back to Recharts' default. Its hsl(var(--chart-N)) siblings are correct and unchanged; that family really is stored as triplets.

Verification

tsc clean, eslint clean, prettier clean. 3596 unit tests pass — the single failure is the pre-existing packages/migrations/rls-all-tables test, which needs DB-create privileges and is unrelated.

Driven live against the mock server (yarn mock:client), confirming GraphQL hit localhost:4000 and not production. Computed styles read off the running app:

token computed
text-muted-foreground oklch(0.551 0.027 264.364) = gray-500
text-foreground oklch(0.13 0.028 261.692) = gray-950
bg-card / bg-background rgb(255,255,255)
bg-muted / bg-accent / bg-secondary oklch(0.967 0.003 264.542) = gray-100
text-destructive / bg-destructive oklch(0.577 0.245 27.325) = red-600
border-border / border-input oklch(0.928 0.006 264.531) = gray-200
ring-ring/40 #99a1af66 = gray-400 @ 40%

All 19 tokens are defined and every utility the codebase actually writes resolves. (bg-popover and bare ring-ring are written nowhere in source, so Tailwind correctly never generates them — the variables are there for when something does.)

Screens walked and eyeballed: /securities, /businesses/ledger, /tags, /sort-codes, /tax-categories, /reports, /reports/annual-revenue, /. No lost contrast, no illegible text, no layout shift.

What to look at

This is an app-wide appearance change, which is exactly why it is split out from the charges work that needs it. The thing worth your eye is whether muted text reading gray-500 and error text reading red-600 is the intended look on the screens you know best — the heaviest consumers are the 60 files using text-muted-foreground.

Dark mode

Still inert. next-themes is installed but no ThemeProvider is mounted (root-layout.tsx mounts MUI's), so nothing ever puts .dark on an ancestor. The overrides are defined so the ~425 dark: utilities already in the codebase are correct when that switch is wired — activating it is a separate change.

🤖 Generated with Claude Code

`components.json` declared `cssVariables: false` and pointed at `tailwind.config.cjs`, a file that
does not exist anywhere in the monorepo — it was deleted during the Tailwind v3 → v4 migration and
the theme layer was never ported to v4's CSS-first `@theme`. So `--color-card`,
`--color-muted-foreground`, `--color-destructive` and the rest were never registered, and Tailwind
never generated the utilities that reference them.

Roughly 380 usages across ~100 files were inert. Verified against two independent build outputs:
`text-muted-foreground`, `bg-card`, `border-border` and `text-destructive` each emitted zero rules,
while `bg-gray-900` emitted 25. Secondary text rendered at full-strength body colour, `bg-muted` /
`bg-accent` / `bg-card` were transparent, and error text rendered black rather than red.

Define the full token set in `@theme` on shadcn's `gray` base, with `.dark` overrides in
`@layer base`. Plain `@theme` rather than `@theme inline`, since inline substitutes literals into
each utility and would make the dark overrides dead code. Values are literal `oklch()` rather than
`var(--color-gray-500)` references, because v4 only emits the default palette variables it sees
used — referencing an otherwise-unused one would resolve to nothing.

Tokens standing in for an existing default take that default's value, so previously-inert classes
stay visually unchanged: background/card are white (already the page background), foreground is
gray-950 (already the inherited text colour), border is gray-200 to match the `border-color`
compatibility rule already in the base layer. The visible changes are the genuinely broken cases —
muted text now reads gray-500, `text-destructive` reads red-600, and muted/accent/secondary
backgrounds gain their light tint.

Also fix `business/client/charts-section.tsx`, which set axis ticks with
`hsl(var(--muted-foreground))`. That is v3 syntax: the v4 token holds a colour, not an HSL triplet,
so the wrapper produced an invalid value and the ticks fell back to Recharts' default. Its
`hsl(var(--chart-N))` siblings are correct and unchanged — that family really is stored as triplets.

Dark mode stays inert: `next-themes` is installed but no `ThemeProvider` is mounted, so nothing puts
`.dark` on an ancestor. The overrides are defined so the ~425 `dark:` utilities already in the
codebase are correct when that switch is wired.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gilgardosh
gilgardosh temporarily deployed to accounter-fullstack August 24, 2026 10:34 — with GitHub Actions Inactive
@gilgardosh
gilgardosh temporarily deployed to accounter-fullstack August 24, 2026 10:34 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@accounter/client 0.1.0-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/green-invoice-graphql 0.8.7-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/hashavshevet-mesh 0.2.13-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/israeli-vat-scraper 0.1.13-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/modern-poalim-scraper 0.11.0-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/payper-mesh 0.2.13-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/scraper-app 0.0.3-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/server 0.2.0-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/shaam-uniform-format-generator 0.2.7-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎
@accounter/shaam6111-generator 0.1.9-alpha-20260824103610-d60c0c36ce983038dc9276b5c6ec04edf7d7c115 npm ↗︎ unpkg ↗︎

@gilgardosh gilgardosh self-assigned this Aug 24, 2026
@gilgardosh
gilgardosh requested review from TuvalSimha and a lite review from Copilot August 24, 2026 10:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It introduces app-wide theme token behavior changes that can have broad UI/contrast impact and warrants final human visual verification across key screens/browsers.

Pull request overview

Activates shadcn/ui color tokens in the client by defining the Tailwind v4 @theme token set (plus dark overrides) so utilities like text-muted-foreground, bg-card, border-border, and text-destructive stop compiling to no-ops across the app.

Changes:

  • Define shadcn/ui color tokens via Tailwind v4 @theme in src/index.css, with .dark overrides in @layer base.
  • Fix Recharts axis tick colors to reference the v4 token (--color-muted-foreground) directly.
  • Update shadcn components.json to enable CSS variables and remove the stale Tailwind config path.
File summaries
File Description
packages/client/src/index.css Adds the shadcn color token set in @theme and dark-mode overrides so token-based utilities generate correctly.
packages/client/src/components/business/client/charts-section.tsx Fixes chart axis tick fill to use the v4 token variable (--color-muted-foreground).
packages/client/components.json Enables cssVariables and clears the non-existent Tailwind config path to match the CSS-first v4 setup.
.changeset/activate-shadcn-color-tokens.md Documents the patch release and the rationale/impact of activating the tokens.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@gilgardosh
gilgardosh merged commit 42e0182 into main Aug 24, 2026
12 checks passed
@gilgardosh
gilgardosh deleted the fix/client-activate-shadcn-color-tokens branch August 24, 2026 11: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.

2 participants