Color tokens define the shared, reusable color values that power both design and code. This page shows what each color looks like. For the full token list with values, see the Tokens page.
Colors are organised into two layers: primitive tokens (raw values) and semantic tokens (intent-based aliases). Always use semantic tokens in production code. Primitives are the building blocks that semantic tokens reference.
Brand Palette
The core brand colors that define the project identity. The engine ships neutral defaults; each brand sets its own values in cms/brands/<brand>/assets/theme.css, and the swatches below render the active brand's values (By Default, instance 0, on this site).
Accent Colors
Primitive Scales
Neutral
Warm grey ramp from lightest to near-black, used for backgrounds, borders, and secondary text.
Black Alpha
Semi-transparent black values for overlays, shadows, borders, and tints.
White Alpha
Semi-transparent white values for highlights and light overlays. Shown on a dark background for visibility.
Semantic Colors
Semantic colors map primitive tokens to meaning and intent. Use these in layouts and components. Never use primitives directly.
Text
Background
Solid colour backgrounds
Solid colour blocks for hero sections, callouts, ad units, and any marketing surface that needs to lean on a brand colour. Each token resolves to the brand primitive when overridden in a client theme, otherwise the design system default applies.
Border
Button
Button colours are now component-scoped tokens on , not root-level variables. See Button documentation for the full token reference (--button-color, --button-bg, --button-text-color, etc.) and the data-color attribute for semantic colour variants.
Status
Status tokens reference the dark shade of each accent colour family — maps to , aligning with the conventional use of blue for informational states. Each status is a pair: the text token sits on a matching --status-*-bg surface. In dark mode the pair flips together — text moves to the light shades, and each surface is derived from the page ground pulled toward the status colour, so tags, badges, callouts and toasts of the same type stay legible in both themes.
Dark Mode
The design system uses a data-theme attribute to switch between light and dark modes. Light mode is the default. Dark mode is an opt-in override, not a baseline. Activate it by setting data-theme="dark" on any element; tokens inherit through the cascade.
Dark mode values (e.g. , ) are overrides applied via [data-theme="dark"]. Never use them as primary values, and never hardcode them. If you're working from a dark-looking screenshot, confirm the intended theme before writing code.
How It Works
:root: light mode tokens (always present)[data-theme="dark"]: overrides semantic tokens with dark values@media (prefers-color-scheme: dark): fallback for users with a dark OS preference — applies only whiledata-themeis unset
The data-theme attribute on <html> is three-state:
| State | Meaning |
|---|---|
| no attribute | No explicit choice — the OS preference decides (this is also what no-JS visitors get) |
data-theme="light" |
Forced light. Light values are the :root defaults, so no extra CSS exists for this state — the attribute's presence defeats the OS fallback |
data-theme="dark" |
Forced dark via the [data-theme="dark"] overrides |
The toggle button in the site header always sets an explicit value — "dark" or "light" — and persists the choice in localStorage. Never toggle by removing the attribute: absence means "follow the OS", so removing it drops an OS-dark visitor straight back into dark mode and light can never stick.
Scoped Usage
You can apply dark mode to any element, not just the page. Note this works for dark only: data-theme="light" is a root-level state — it defeats the OS fallback on <html> but has no overrides of its own, so it cannot light-mode a region nested inside [data-theme="dark"].
Light mode
Primary text Faded text Accent textDark mode
Primary text
Faded text
Accent text
<!-- Dark card on a light page -->
<div data-theme="dark" class="card">
<p>This section uses dark mode tokens</p>
</div>
All semantic tokens inside that element resolve to their dark values via CSS custom property inheritance.
Customizing Dark Mode
Edit the [data-theme="dark"] block in design-system.css (section 2b). When changing a value, also update the @media (prefers-color-scheme: dark) fallback (section 2c) to keep them in sync.