Introduction
The current token source lives in tokens/core.tokens.json. npm run tokens:build uses Style Dictionary to generate assets/css/generated/tokens.css; Hugo bundles that generated file before assets/css/site.css, so the active site reads its foundation variables from the token output.
Use Token architecture for the canonical technical model: source ownership, theme collections, generated artifacts, consumers, and validation. This page remains the foundation-level introduction.
Current groups#
| Group | Purpose | Generated reference |
|---|---|---|
| Colour | Core brand and interface colours | Colour tokens |
| Font | Self-hosted font stacks | Typography tokens |
| Type scale | Fluid text sizes used across page hierarchy | Typography tokens |
| Space | Fluid spacing values for layout rhythm | Space tokens |
| Layout | Page-level constraints | Layout tokens |
The category reference pages are generated from data/brand/tokens.yml, which is generated from token metadata in tokens/core.tokens.json. The Markdown pages only decide the URL, title, and surrounding context.
Changelog
Most recent check of all entries: August 17, 2026
- Generated token reference data and category pages from token metadata, with
npm run tokens:checkenforcing data drift. - Accepted ADR 0005: token category documentation must be generated from token metadata or Style Dictionary output, not maintained as manual tables.
- Expanded Foundations > Tokens into a small section with Introduction, Types of tokens, Naming, Pipeline, and Generated categories.
- Activated generated token CSS in the Hugo stylesheet bundle and added
npm run tokens:checkto guard generated output and CSS references. - Added
npm run tokens:updateas the safe token workflow: rebuild generated CSS, then verify it.
- Generated token reference data and category pages from token metadata, with
- Added the dormant Style Dictionary pipeline: source tokens, generated CSS output, and
npm run tokens:build.
- Added the dormant Style Dictionary pipeline: source tokens, generated CSS output, and
How a token becomes a pixel#
One source file, tokens/core.tokens.json, feeds two generators and a checker that keeps
them honest. Below is the actual mechanism in this repo — not the generic Style Dictionary
story, this repo’s wiring.
1. Source → generated output → rendered page#
npm run tokens:update runs three steps against the same JSON file. The last one,
tokens:check, doesn’t touch the committed files — it rebuilds into a temp directory and
diffs, so a stale tokens.css or tokens.yml fails CI instead of silently drifting.
flowchart TD
JSON["tokens/core.tokens.json<br/>DTCG $value + $type + governance metadata"]
subgraph GEN["npm run tokens:update"]
direction LR
SD["style-dictionary.config.mjs<br/>tokens:build"]
TD["scripts/token-data.mjs<br/>tokens:data"]
end
CSS["assets/css/generated/tokens.css<br/>--color-ink: #101010;"]
YML["data/brand/tokens.yml<br/>Hugo data file"]
CHK["scripts/check-style-dictionary.mjs<br/>tokens:check"]
JSON --> SD --> CSS
JSON --> TD --> YML
CHK -.diffs against a fresh rebuild.-> CSS
CHK -.diffs against a fresh regenerate.-> YML
CHK -."scans for raw #hex &<br/>ungoverned Tailwind colour".-> SITE
SITE["assets/css/site.css<br/>hand-written, var(--…) only"]
BASEOF["layouts/_default/baseof.html<br/>resources.Concat + fingerprint"]
SHORT["token-table.html shortcode"]
DOCS["content-brand/docs/foundations/tokens/*.md"]
BROWSER(("Browser"))
CSS --> BASEOF
SITE --> BASEOF
BASEOF -->|site-bundle.css| BROWSER
YML --> SHORT
DOCS -->|"{{< token-table category='color' >}}"| SHORT
SHORT -->|rendered table| BROWSER
classDef source fill:transparent,stroke:#e6461a,stroke-width:2px;
classDef check stroke-dasharray:4 3;
class JSON source
class CHK checkFig. 1. The dashed arrows are tokens:check, not data flow: it never writes to
tokens.css or tokens.yml, it only rejects a commit where either has fallen out of sync
with the source JSON, or where site.css reaches for a raw hex value instead of a generated
variable.
2. What one token entry actually carries#
kind (primitive / scale / semantic / component) is a label for documentation grouping;
it is not an alias. Values use the DTCG $value field, and an exact reference such as
{color.palette.signal-orange} is an alias that resolves to another token. foreground
is a separate reference used only to enforce contrast.
flowchart LR
subgraph T["color.accent"]
direction TB
VAL["$value: {color.palette.signal-orange}"]
KIND["kind: semantic"]
DESC["description.en / .fr"]
WEBM["web: group focus,<br/>foreground color.ink"]
brandMetadata["brand: group accent,<br/>foreground color.ink"]
end
PALETTE["color.palette.signal-orange<br/>$value: #e6461a<br/>visibility: internal"]
INK["color.ink<br/>$value: {color.palette.near-black}"]
WEBM -."contrastRatio() ≥ WCAG,<br/>checked at build time".-> INK
brandMetadata -."same check,<br/>brand palette view".-> INK
VAL -->|"name/path-kebab-preserve-negative<br/>transform"| cssVariable["--color-accent"]
VAL -->|"resolves alias"| PALETTE
KIND -->|"groups the row"| ROW["token-table.html<br/>Kind column"]
WEBM -->|"web palette view"| SW1["Colour swatch — web"]
brandMetadata -->|"brand palette view"| SW2["Colour swatch — brand"]
classDef ref fill:transparent,stroke:#e6461a,stroke-width:2px,stroke-dasharray:4 3;
class WEBM,brandMetadata refFig. 2. $value aliases form the CSS token chain. foreground is a distinct
cross-token reference used only for contrast. scripts/token-data.mjs resolves both before
calculating a real WCAG contrast ratio, so hex and oklch() values are checked consistently.
Public API and implementation primitives.
color.palette.*tokens are markedvisibility: internal. They remain in generated CSS because semantic aliases need them, but do not appear in the public reference table or generated Tailwind theme. Authors use semantic tokens such ascolor.accent, whose table row shows both its$valuealias and its resolved literal.
Source: tokens/core.tokens.json, style-dictionary.config.mjs, scripts/token-data.mjs,
scripts/check-style-dictionary.mjs, layouts/shortcodes/token-table.html,
layouts/_default/baseof.html.