@freecodexyz/design-tokens
v0.1.0
Published
Platform-neutral design tokens for the FCF design system, in DTCG format.
Maintainers
Readme
@freecodexyz/design-tokens
The design decisions, as platform-neutral DTCG JSON, compiled to every format the organisation consumes.
pnpm add @freecodexyz/design-tokensOutputs
| File | For |
| ---------------------- | ------------------------------------------------------------ |
| tokens.css | The custom properties, with every theme block. What products load. |
| tokens.scss | $fcf-* variables, !default. Compiled values — light theme only. |
| tokens.map.scss | The same as one flat Sass map. |
| tokens.js / .d.ts | A typed map of token name → var(--fcf-…). |
| tokens.json | Resolved values, nested. |
| tokens.resolved.json | Resolved values, flat, with types and descriptions. For tooling. |
| tokens.dtcg.json | The merged DTCG source. For design tools. |
Using them
In CSS — load tokens.css (or all of @freecodexyz/design-system-css) and read
the properties:
.thing { color: var(--fcf-color-fg-muted); }In JavaScript — the export is a map of references, not values, so it tracks the active theme:
import { token } from '@freecodexyz/design-tokens'
token.colorBgCanvas // 'var(--fcf-color-bg-canvas)'For the resolved value at build time — a contrast check, a docs table — use
tokens.resolved.json. Do not use it for anything that renders: it is the light
theme, frozen.
The tiers
primitive/ ramps, scales, curves. The only literals in the system.
semantic/ roles: color.bg.canvas, text.heading-1.size, radius.control
component/ button.accent.background, field.border-focus, table.row-hover
themes/ dark, three accents, two radius variantsComponents consume semantic or component tokens. A component that reaches into a primitive cannot be re-themed, which is the whole point of the split.
semantic/accent.json is a thin alias layer that every accent-driven token
points at — which is why an accent theme is eleven lines and works in both
themes. See RFC 0001.
Building
pnpm build # runs Style Dictionary; output is committedCI fails if the committed output does not match a fresh build.
Two custom transforms live in build/hooks.mjs: duration/css, because DTCG
duration objects have no built-in CSS handler, and dimension/fluid, which turns
a $extensions descriptor into a clamp() interpolating across the system's
single viewport range.
Guarantees
test/contrast.test.ts asserts, against the emitted tokens.css, that every
foreground/background pair the system permits meets WCAG AA — in both themes and
all four accents — and that the accent families share one lightness ladder, so
swapping an accent cannot change contrast.
