Theme builder
Pick one brand color and this builder derives the rest of the
data-color accent set — the hover shade, the soft tint, and the
text-on-primary color — checks the WCAG contrast for you, and
generates ready-to-use exports.
Two modes:
- Accent — adds a new
[data-color="<name>"]axis (opt-in, sits alongside the built-in five). Just the accent changes. - Full theme — customises the default look: accent plus a
neutral ramp (gray / slate / zinc / neutral / stone, driving
surface / text / border / secondary), the control radius, and
typography (body / heading / mono
font-family), across both light and dark. The output is computed as the diff of the themed build against the stock build, so it’s exactly the variables that changed — nothing more.
It works by running the real token transformer
(@hypermedia-components/core/token-transform) on the real DTCG
sources right in your browser. The preview, the Apply to this page
button, and every export are produced by the same buildTokensCss the
library build uses — so a custom theme behaves exactly like a built-in
one (every affected component variable, subtree-safe), and the
“DTCG sources → generated CSS variables” model is never bypassed.
Semantic status colors (success / warning / error) stay fixed — the accent doesn't touch them.
Scoped to this box and rendered by the real token build. Toggle the site's light/dark switch to check both. Apply to this page themes the whole site.
Additive — keep the stock CSS and load this after it. No build.
Save as color.<name>.tokens.json and register it in build-tokens.mjs (Path B).
The complete token CSS (all built-in themes + yours). Drop-in replacement for the stock token stylesheet.
How the derivation works
Section titled “How the derivation works”| Output | Derivation |
|---|---|
action-primary-bg / border | Your chosen brand color, as-is. |
action-primary-hover-bg / border | Brand color darkened toward black by the Hover darkness percentage. |
action-primary-fg | Auto picks white or gray.900 (#111827) — whichever has the higher contrast against the brand color. Override it manually if you prefer. |
action-primary-soft-bg | color-mix(in srgb, <brand> N%, transparent) — one value that blends correctly on light and dark surfaces. |
focus-ring | Defaults to the brand color. |
The contrast read-out is the WCAG 2.x ratio between the brand color and the resolved text color. Aim for 4.5 : 1 (AA) or better; the badge turns red below that.
The three exports
Section titled “The three exports”The builder runs buildTokensCss with your color injected as a
synthetic color.<name> source, then hands you the output three ways:
-
Theme CSS block — just this theme’s
[data-color="<name>"]block (every affected component variable, resolved). Additive: keep the stock token CSS and load this after it, then setdata-color="<name>". No build. This is the correct Path A — overriding the seven semantic variables by hand would not work (see How the cascade actually works). -
DTCG token file —
color.<name>.tokens.json. Save it underpackages/core/src/tokens/and register it inbuild-tokens.mjsto ship the theme in the build (Path B). Also feeds external DTCG tooling (Style Dictionary, Figma). -
Full token CSS — the complete
hc.tokens.css(every built-in theme plus yours). A drop-in replacement for the stock token stylesheet when you’d rather swap one file than add a block.
Apply to this page injects the generated block onto the docs
site’s <html> so you can browse every component under your theme;
Reset clears it.
Related
Section titled “Related”- Color themes — the built-in five, the cascade explanation, and the full authoring guide.
- Density — orthogonal sizing axis.
- Tokens overview — the four-layer model.