Design tokens
Four tiers, each with one job. Components never touch the raw palette; brands never touch component files. The tier boundaries are what make dark mode, density, and re-branding one-attribute or one-file operations.
The four tiers
/* Tier 1 — raw palette: never consumed by components */
--bo-palette-blue-600: #2563eb;
/* Tier 2 — semantic roles: what components reference; dark theme
redefines THIS tier under [data-theme="dark"] */
--bo-color-accent: var(--bo-palette-blue-600);
--bo-color-accent-solid: var(--bo-palette-blue-600); /* carries white text, both themes */
--bo-color-accent-text: var(--bo-palette-blue-700); /* sits on accent-subtle, >= 4.5:1 */
/* Tier 3 — density aliases: remapped by [data-density], the ONLY sizing
source components use internally */
--bo-density-row-height: 2.5rem;
/* Tier 4 — component-local: defaults to globals, variants override locally */
.bo-btn { --bo-btn-bg: var(--bo-color-accent-solid); } Token roles encode contrast guarantees: *-solid
backgrounds carry white text in both themes (≥ 4.5:1, never dark-remapped);
*-text foregrounds sit on *-subtle backgrounds
(≥ 4.5:1, remapped to light steps in dark mode). Every pair is
computed and CI-gated on every build
— every resolved value, both themes, in the
token reference.
Unit doctrine
- rem for space and size — tracks the user's font preference. Density is rem-only; px overrides of density tokens are unsupported (they clip text when users raise the root font).
- px only for hairlines (borders, focus rings, connectors) — visual weight must not scale; integer px + single-edge borders is also the 125% display-scaling mitigation.
- ch for mono-measured content and docs prose only — always a minimum width, never in a token consumed across font contexts, never in print.
- Container-query thresholds in rem;
ptonly inside@media print; line-height unitless. - Heights are minimums (
min-height) — fixed heights clip under WCAG text-spacing overrides.
Constraint: the framework assumes an unmodified root
font-size. Hosts that rescale html (legacy 62.5% hacks) rescale
everything — embed via iframe instead.