MVP UI

Theming

Design tokens, color palette, and semantic aliases — how appearance is defined and overridden.

Token system

All visual decisions are CSS custom properties defined in packages/tokens. Components reference semantic aliases — never raw palette values — so swapping a theme only requires reassigning root variables.

Brand palette

Untitled UI purple. brand-600 is the default action color. Raw scale classes (bg-brand-*) are allowed in components only for mode-independent fills annotated with // dark-ok.

brand
25
50
100
200
300
400
500
600
700
800
900
950

Gray palette

Warm-tinted neutral (zinc-based). Semantic aliases map to this scale and flip between light and dark automatically.

gray
25
50
100
200
300
400
500
600
700
800
900
950

State palettes

success
50
100
200
300
400
500
600
700
warning
50
100
200
300
500
600
700
error
50
100
200
300
500
600
700

Semantic tokens — surfaces

Use these for bg-*. They flip automatically in dark mode — the swatches below reflect the current theme.

--color-bgPage / panel surface
--color-bg-secondarySecondary surface
--color-bg-tertiaryTertiary / hover surface

Semantic tokens — text

Use these for text-*. Live samples below show each foreground color on the current surface.

--color-fgPrimary text
--color-fg-secondarySecondary text
--color-fg-tertiaryTertiary / hint text
--color-fg-brandBrand text / icon fill
--color-fg-errorError text / icon fill
--color-fg-successSuccess text / icon fill

Semantic tokens — borders

--color-borderDefault border
--color-border-secondarySubtle separator
--color-border-brandBrand focus ring
--color-border-errorError state border
--color-border-successSuccess state border

Semantic tokens — action

Primary fill colors for interactive elements. Use bg-primary, bg-primary-hover, and text-primary-fg on buttons and focus indicators.

Primary
Hover
Active

Semantic tokens — status

Subtle surface triads for badges and alerts. Each set — bg, border, fg — flips in dark mode (e.g. brand-50 brand-950).

Info
Success
Warning
Error
Neutral

Forbidden patterns

Never use raw numbered scale values (gray-900, brand-600) on component bg, text, or border utilities. These do not flip under [data-theme="dark"]. Use the semantic aliases above. The pnpm lint:dark check enforces this at CI.