Using Design Tokens
This guide shows developers how to consume and extend the design–token system shipped with the Astro Performance Starter.
1. Quick recap
Section titled “1. Quick recap”Token sources live in tokens/:
| File | Purpose |
|---|---|
base.json | Atomic design tokens (color, fontFamily, fontSize, spacing, borderRadius, shadow, motion) |
semantic.json | Role-based semantic aliases with light/dark values (background, surface, foreground, border, …) |
dist/ | Build output – do not edit directly (gitignored) |
The build script (pnpm run tokens:build, scripts/src/build-tokens.ts) generates:
tokens/dist/tokens.css– CSS variables in two blocks::root(light values) and.dark(dark overrides). Imported bysrc/styles/global.cssand mapped to Tailwind utilities via@theme inline(Tailwind is CSS-first here — there is notailwind.config.*).tokens/dist/tailwind-tokens.json– a JSON export of the token scales for tooling.
Tokens compile automatically before pnpm run dev (predev) and as part of pnpm run build. Manual compilation (rarely needed): pnpm run tokens:build.
2. In templates/components
Section titled “2. In templates/components”Tailwind utilities
Section titled “Tailwind utilities”<div class="bg-background text-foreground p-4 rounded-lg shadow-md transition duration-fast"> …</div>bg-background/text-foreground– map to the semantic role tokens (semantic.background,semantic.foreground), exposed as--color-background/--color-foregroundvia@theme inline.shadow-md– from theshadowscale in base tokens.duration-fast– motion tokens (--duration-fast/base/slow, plusease-in/ease-out/ease-in-out);transitionitself is Tailwind’s built-in utility.- All color tokens use the
--color-prefix for consistency.
CSS/SCSS
Section titled “CSS/SCSS”.card { background-color: hsl(var(--color-background)); color: hsl(var(--color-foreground)); border-radius: var(--border-radius-lg);}- Access any token via CSS custom property – wrap color tokens with
hsl()(they are stored as raw HSL channels). - All color variables use the
--color-prefix (e.g.,--color-primary-500,--color-background). - Dark mode is handled automatically: the
.darkblock intokens.cssoverrides the semantic variables.
3. Adding / updating tokens
Section titled “3. Adding / updating tokens”- Edit
tokens/base.jsonortokens/semantic.json. - Run
pnpm run tokens:buildto regenerate outputs (predevandbuilddo this for you). - Commit only the source files —
tokens/dist/is gitignored and regenerated on every dev/build.
Tip: keep scales consistent — spacing steps of
0.25rem(4px), and motion durations on the existingfast/base/slowsteps rather than ad-hoc values.
4. Naming conventions
Section titled “4. Naming conventions”JSON tokens (source)
Section titled “JSON tokens (source)”- Base tokens: camelCase in JSON (
borderRadius.lg,color.slate.500— the base palette isslate,violet,rose,amber,green,spaceCadet,white,charcoal). - Semantic tokens: flat, role-based names per ADR-047 (
background,surface,surfaceRaised,foreground,mutedForeground,borderEmphasis,link,success).
CSS variables (generated)
Section titled “CSS variables (generated)”- All color tokens:
--color-prefix for consistency.- Base:
--color-slate-500,--color-violet-600 - Semantic:
--color-primary-500,--color-surface,--color-foreground
- Base:
- Non-color tokens: category prefix (
--spacing-4,--border-radius-lg,--motion-duration-fast).
Tailwind utilities
Section titled “Tailwind utilities”- Match CSS variable names:
bg-primary-500,text-foreground,bg-surface,border-border-emphasis. - Dark mode: handled automatically via the
.darkclass (no manualdark:variants needed for semantic tokens).
5. Dark mode
Section titled “5. Dark mode”Dark mode ships with the template (ADR-032) — you don’t build it. The default is dark-first: the OS prefers-color-scheme setting does not pick the theme.
src/components/ThemeSetup.astroruns an inline script before paint. IflocalStoragehas an explicitthemeoflightordark, it applies that; otherwise it applies dark. It sets the.darkclass and thedata-themeattribute on<html>, re-applies after Astro view transitions, and syncs the choice across tabs.src/components/atoms/ThemeToggle.astrocycles light → dark → system. “System” clears the stored choice, which under the dark-first rule renders dark.tokens/dist/tokens.cssonly contains:rootand.darkblocks — there is noprefers-color-schememedia query. Tailwind’sdark:variants activate via@variant dark (&:where(.dark, .dark *))insrc/styles/global.css; semantic role tokens flip automatically, so components using them need nodark:variants at all.
6. Lint & validation
Section titled “6. Lint & validation”pnpm run design:validate– ensures WCAG-AA contrast for semantic pairs.- CI fails if new tokens break contrast budgets.
Need help? Check the Design System implementation guide, the Design System Changelog, or open an issue.