What design tokens are
A token is a named value that stands in for a primitive. Instead of typing #0a0e1a in fifteen places, we define --foreground once and let every component reference it. When the brand evolves, we update the token; the system follows.
Tokens have two layers. Primitives are raw values (HSL triples, rem sizes, ms durations). Semantic tokens name a role (--background, --muted-foreground) and reference a primitive. Components only consume semantic tokens.
Categories
- Color — surfaces, text, borders, status. Documented at Color.
- Typography — font families, sizes, line heights, letter spacing. Documented at Typography.
- Space— 4pt scale: 4, 8, 12, 16, 24, 32, 48, 64, 96. Tailwind's default spacing scale, used as-is.
- Radius —
--radiusbase of 0.5rem, with derivedsm,md,lg,xlsteps. - Motion — durations and easings. Documented at Motion.
Where they live
Token primitives are CSS variables defined in packages/ui/src/styles/tokens.css on :root (and again under .darkwhen dark mode lands). The portal's apps/portal/app/globals.css imports them and exposes them as Tailwind theme variables via @theme inline.
packages/ui/src/styles/tokens.css
:root {
--background: 0 0% 100%;
--foreground: 222 47% 11%;
--muted: 210 40% 96%;
--muted-foreground: 215 16% 47%;
--border: 214 32% 91%;
--radius: 0.5rem;
}apps/portal/app/globals.css
@theme inline {
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-muted: hsl(var(--muted));
}Consuming a token
From a Tailwind class:
tsx
<div className="bg-card text-foreground border-border">
<p className="text-muted-foreground">Quiet text.</p>
</div>From inline styles:
tsx
<span style={{ background: "hsl(var(--muted))" }}>…</span>Do
Always reach for a semantic token before a primitive. If the right token doesn't exist, propose one rather than reaching for an arbitrary value.
Naming rules
- Role, not value.
--muted-foregroundtells you what it's for.--gray-500doesn't. - Lowercase, kebab-case. No camelCase, no SCREAMING_SNAKE.
- No numeric suffixeson semantic tokens. Numbers go on primitives, if at all (we mostly skip them — Tailwind's spacing scale is enough).
- Pair foregrounds with backgrounds. Every surface token has a matching
-foregroundsibling so contrast pairs are explicit.