Themes

Every component follows a light or dark theme. Themes are CSS variables: the neutral scale (--n-*) and the semantic tokens mirror the Figma Colors variables (bg-primary, text-primary, border-primary …) and are re-mapped when data-theme is dark.

import<html data-theme="dark">

Switching themes

Set data-theme on <html>. Persist the choice yourself (the playbook uses localStorage and a pre-paint script to avoid a flash).

Toggle to preview this page in the other theme.

Components in both themes

ActiveFailed

Neutral scale

The scale is inverted in dark mode, so anything written with var(--n-*) adapts automatically. Avoid hard-coded hex colours in components.

TokenLightDarkUse
--n-0#ffffff#0a0a0aPage and surface background (bg-primary)
--n-50#fafafa#121212Subtle fill, hover (bg-secondary)
--n-100#f5f5f5#1a1a1aMuted fill, chips (bg-tertiary)
--n-200#e5e5e5#262626Dividers, secondary border
--n-300#d4d4d4#3a3a3aDefault border (--border)
--n-400#a3a3a3#8a8a8aPlaceholder, disabled text, icons
--n-500#737373#a3a3a3Tertiary text
--n-600#525252#bdbdbdSecondary text
--n-700#404040#d4d4d4Body text, labels
--n-800#171717#edededPrimary text
--n-900#0f0f0f#fafafaHeadings, highest contrast

Props

PropTypeDefaultDescription
--bg-primary / --bg-secondary / --bg-tertiarytoken—Surface levels (map to --n-0 / --n-50 / --n-100)
--text-primary / --text-secondary / --text-tertiary / --text-disabledtoken—Text levels (map to --n-800 / 600 / 500 / 400)
--border-primary / --border-secondarytoken—Borders (--n-300 / --n-200)
--brand / --brand-hover / --brand-subtle / --brand-texttoken—Brand; subtle and text are re-tinted for dark. Switch brands with data-brand
--ring-subtletoken—Hairline for image and card edges (black 10% in light, white 12% in dark)
--color-<hue>-50 / 100 / 200 / 700token—Pastel status tints (red, green, amber, blue …) become translucent fills with light text in dark
.light-scopeclass—Restores the light neutral scale inside always-dark blocks such as code samples and device frames
dark:Tailwind variant—dark:* utilities apply when an ancestor has data-theme="dark"