Foundations

Color

39 colour tokens in the base theme. Components only use these semantic roles, never the raw palettes underneath, which is what lets a brand or dark mode change every component at once. The swatches are painted from the live CSS variables, light on the left and dark on the right.

Tokens

Neutral scale

The gray ramp the other colour roles resolve to. It flips in dark mode, so 50 is always the page and 900 always the strongest contrast.

TokenPreviewLightDarkUsed by
--color-neutral-50#FAFAFA#171717—
--color-neutral-100#F5F5F5#262626—
--color-neutral-200#E5E5E5#404040—
--color-neutral-300#D4D4D4#525252—
--color-neutral-400#A3A3A3#737373—
--color-neutral-500#737373#A3A3A3—
--color-neutral-600#525252#D4D4D4—
--color-neutral-700#404040#E5E5E5—
--color-neutral-800#262626#F5F5F5—
--color-neutral-900#171717#FAFAFA—

Surface

Background layers, from the page itself to raised containers, plus an inverse surface for dark-on-light moments.

TokenPreviewLightDarkUsed by
--color-surface-primary#FAFAFA#171717Card, Dialog, Drawer, Menu and 8 more
--color-surface-secondary#F5F5F5#262626Card, Menu, NavigationMenu, Accordion and 13 more
--color-surface-tertiary#E5E5E5#404040Dialog, Drawer, Table, Switch
--color-surface-inverse#171717#FAFAFATooltip

Text

Primary for body copy and headings, secondary for supporting text, inverse for text on an inverse surface.

TokenPreviewLightDarkUsed by
--color-text-primary#0A0A0A#FAFAFADialog, Drawer, Menu, NavigationMenu and 17 more
--color-text-secondary#525252#D4D4D4Card, Dialog, Drawer, Menu and 21 more
--color-text-inverse#FAFAFA#171717Tooltip

Accent

Primary actions and selected states. In base it’s near-black; a brand changes these three to put its own colour on actions.

TokenPreviewLightDarkUsed by
--color-accent-default#262626#F5F5F5Card, Pagination, Table, Tabs and 7 more
--color-accent-hover#171717#FAFAFAButton, Link
--color-accent-foreground#FFFFFF#171717Pagination, Button, Checkbox, SkipLink and 2 more

Border

Dividers and outlines, the focus ring, and the curtain colour used by route transitions.

TokenPreviewLightDarkUsed by
--color-border-default#E5E5E5#404040Card, Dialog, Drawer, Menu and 13 more
--color-border-strong#A3A3A3#737373Card, Checkbox, Input, Radio and 3 more
--color-border-focus#0A0A0A#FAFAFAAlert, Card, Dialog, Drawer and 19 more
--color-curtain#D4D4D4#525252—

Feedback

Error, success, warning and info. Each state has a background, a foreground and a border, used together by Alert, Toast and form errors.

TokenPreviewLightDarkUsed by
--color-feedback-error#c0392b#f87171Menu, Input, Label, Textarea
--color-feedback-error-background#FEF2F2#262626Alert, Menu, Badge
--color-feedback-error-foreground#a93226#f87171Alert, Toast, Badge
--color-feedback-error-border#c0392b#f87171Alert, Toast, Badge
--color-feedback-success-background#F0FDF4#262626Alert, Badge
--color-feedback-success-foreground#15803D#f0fdf4Alert, Toast, Badge
--color-feedback-success-border#16A34A#4ade80Alert, Toast, Badge
--color-feedback-warning-background#FFFBEB#262626Alert, Badge
--color-feedback-warning-foreground#B45309#fffbebAlert, Toast, Badge
--color-feedback-warning-border#D97706#fcd34dAlert, Toast, Badge
--color-feedback-info-background#EFF6FF#262626Alert, Badge
--color-feedback-info-foreground#1D4ED8#eff6ffAlert, Toast, Badge
--color-feedback-info-border#2563EB#60a5faAlert, Toast, Badge

Skeleton

The two colours a loading skeleton pulses between.

TokenPreviewLightDarkUsed by
--color-skeleton-base#E5E5E5#404040Skeleton
--color-skeleton-highlight#F5F5F5#262626Skeleton

Usage

Reach for the role, not the shade. A surface token on a background, a text token on text.

css
.notice {
  background: var(--color-surface-secondary);
  color: var(--color-text-primary);
  border: var(--border-width-default) solid var(--color-border-default);
}

.notice__meta {
  color: var(--color-text-secondary);
}

/* Dark mode needs no extra CSS: the same tokens
   resolve to dark values under [data-mode="dark"]. */

Do and don’t

Do

  • Use --color-text-secondary for supporting text, so it stays readable in both modes.
  • Pair each feedback background with its own foreground and border.
  • Pair colour with text or an icon when it carries meaning, like an error.

Don’t

  • Write a hex value. The linter rejects it in component CSS, and it won’t follow dark mode.
  • Use a neutral step for a role that has its own token, like --color-neutral-200 for a border.
  • Use the accent for decoration. It marks the main action.