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#

GroupPurposeGenerated reference
ColourCore brand and interface coloursColour tokens
FontSelf-hosted font stacksTypography tokens
Type scaleFluid text sizes used across page hierarchyTypography tokens
SpaceFluid spacing values for layout rhythmSpace tokens
LayoutPage-level constraintsLayout 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:check enforcing 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:check to guard generated output and CSS references.
    • Added npm run tokens:update as the safe token workflow: rebuild generated CSS, then verify it.
    • Added the dormant Style Dictionary pipeline: source tokens, generated CSS output, and npm run tokens:build.

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 &amp;<br/>ungoverned Tailwind colour".-> SITE

    SITE["assets/css/site.css<br/>hand-written, var(--&hellip;) 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 -->|"{{&lt; token-table category=&#39;color&#39; &gt;}}"| 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 check

Fig. 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() &ge; 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 &mdash; web"]
    brandMetadata -->|"brand palette view"| SW2["Colour swatch &mdash; brand"]

    classDef ref fill:transparent,stroke:#e6461a,stroke-width:2px,stroke-dasharray:4 3;
    class WEBM,brandMetadata ref

Fig. 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 marked visibility: 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 as color.accent, whose table row shows both its $value alias 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.