fix(ui): restore dark mode token values in globals.css
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:
| Pair | Ratio | AA (4.5:1) |
|---|---|---|
| foreground / background | 16.79 | PASS |
| card-foreground / card | 16.06 | PASS |
| popover-foreground / popover | 16.06 | PASS |
| secondary-foreground / secondary | 13.50 | PASS |
| accent-foreground / accent | 13.02 | PASS |
| muted-foreground / background | 7.45 | PASS |
| warning-foreground / warning | 7.39 | PASS |
| ring / background | 7.29 | PASS |
| primary-foreground / primary | 7.29 | PASS (was 2.57, FAIL) |
| muted-foreground / muted | 5.99 | PASS |
| destructive-foreground / destructive | 4.59 | PASS |
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/backgroundis 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-editoroverride — now redundant, left in place rather than removed in the same PR. - Hardcoded hexes in components —
toast.tsx:106usestext-[#878787]where--muted-foregroundexists;toaster.tsx:30,32hardcode#0064D9and#FF3638;time-range-input.tsxrepeats#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-foregroundis now0 0% 7%instead of0 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,--bordercontrast at 1.38:1, the now-redundant override inapps/framework-editor/styles/globals.css, and hardcoded hexes intoast.tsx,toaster.tsx, andtime-range-input.tsxunchanged.