fix(ui): restore dark mode token values in globals.css

WE
2mo ago
+18-18

What

The .dark block in packages/ui/src/globals.css is currently identical to :root all 33 tokens carry their light values, so applying the dark class changes nothing that depends on a semantic token. This restores real dark palette.

Why

apps/framework-editor/styles/globals.css already documents this and worked around it locally:

"Real dark-mode palette (FRAME-5). @trycompai/ui ships a .dark block whose values are identical to light, so without this, toggling the dark class changes nothing."

Since @trycompai/ui is published, consumers following the dark-mode setup in the package README get a theme that does nothing. Inside the monorepo the impact is narrower — apps/app and apps/portal take their tokens from @trycompai/design-system — but framework-editor is carrying the override, and the published package is affected.

What changed

The palette is FRAME-5's, upstreamed unchanged, with one exception.

--primary-foreground was 0 0% 98%. Near-white on the dark-mode primary (165 70% 42%) measures 2.57:1, below WCAG AA for normal text and below AA-large. Setting it to 0 0% 7% gives 7.29:1 while leaving the brand's teal untouched.

Contrast for every pair in the block:

PairRatioAA (4.5:1)
foreground / background16.79PASS
card-foreground / card16.06PASS
popover-foreground / popover16.06PASS
secondary-foreground / secondary13.50PASS
accent-foreground / accent13.02PASS
muted-foreground / background7.45PASS
warning-foreground / warning7.39PASS
ring / background7.29PASS
primary-foreground / primary7.29PASS (was 2.57, FAIL)
muted-foreground / muted5.99PASS
destructive-foreground / destructive4.59PASS

Deliberately out of scope

  • --chart-* tokens — still light values inside the dark block; several are low-contrast on a dark ground. Would love to follow up separately.
  • border / background is 1.38:1 — not text, so AA doesn't apply, but WCAG 1.4.11 suggests 3:1 for meaningful UI boundaries. Left as-is; your call whether it should move. My judgement is it should to mantain visual legibility and UI rythm.
  • The framework-editor override — now redundant, left in place rather than removed in the same PR.
  • Hardcoded hexes in components — toast.tsx:106 uses text-[#878787] where --muted-foreground exists; toaster.tsx:30,32 hardcode #0064D9 and #FF3638; time-range-input.tsx repeats #878787. These can't respond to any theme — same root cause seen from the component side. Not touched here.

Note: CONTRIBUTING.md says PRs should target dev, but that branch no longer exists, so this targets main. Happy to open a separate PR fixing that line if useful.


Summary by cubic

Restores the dark-mode palette in packages/ui/src/globals.css so the dark class now actually changes semantic token values instead of mirroring light values.

  • Applies the FRAME-5 dark palette with one correction: --primary-foreground is now 0 0% 7% instead of 0 0% 98%, raising contrast on the brand teal from 2.57:1 to 7.29:1 (passes WCAG AA).
  • Leaves --chart-* tokens at light values, --border contrast at 1.38:1, the now-redundant override in apps/framework-editor/styles/globals.css, and hardcoded hexes in toast.tsx, toaster.tsx, and time-range-input.tsx unchanged.