# 0002 — Mindburn Core token source and parity tests

## Status

Accepted — 2026-04-29.

## Context

A design system needs tokens to be reachable from three callers:

1. **CSS** — every primitive's `.css` file references `var(--helm-*)`.
2. **TypeScript** — runtime helpers (theme switching, contrast utilities,
   inline-style validation) need the same values typed and addressable
   in JS.
3. **JSON** — Figma, docs, package smoke tests, and downstream consumers need
   a stable machine-readable token contract.

The package identity changed from HELM-specific core to parent-company core:
`@mindburn/ui-core` now owns primitive, semantic, component, runtime CSS, JSON,
and TypeScript token contracts. HELM-named packages are compatibility wrappers
or HELM product layers, not token authorities.

## Decision

`src/tokens/source.ts` is the canonical structured token source for generated
JSON. `src/tokens/tokens.json` is generated by the package-local
`scripts/generate-tokens.mjs` script and checked by `npm run tokens:check`.
`src/tokens/index.ts` exposes typed runtime helpers and constants. The runtime
CSS contract remains in `src/styles/tokens.css`, including deprecated
compatibility aliases for the current migration window.

A parity test (`src/tokens/index.test.ts`) keeps the TypeScript and CSS
contracts aligned. A future Style Dictionary or W3C token-spec source may
replace the current TypeScript source, but token generation must stay owned by
`@mindburn/ui-core`.

## Consequences

- **+ Token JSON has one owner** — downstream packages consume generated JSON
  from `@mindburn/ui-core` instead of writing into the core package.
- **+ CSS remains stable** — existing `--helm-*` and legacy alias variables
  remain available during the compatibility window.
- **+ Contrast gate** (`tokens:contrast:check`) reads the TS side and
  validates WCAG AA over a curated 20-pair table.
- **+ Tree-shaking-friendly** — consumers can import a single token by
  name without pulling the full CSS bundle.
- **−** Manual CSS/TypeScript mirroring is still a footgun without the parity
  test. The test and `tokens:check` must run on every PR.
- **−** Some token shapes (computed, derived) are awkward to author by
  hand. Style Dictionary backfill will solve this.

## References

- [packages/design-system-core/src/styles/tokens.css](../../../packages/design-system-core/src/styles/tokens.css)
- [packages/design-system-core/src/tokens/index.ts](../../../packages/design-system-core/src/tokens/index.ts)
- [packages/design-system-core/src/tokens/index.test.ts](../../../packages/design-system-core/src/tokens/index.test.ts) — parity test
- Token generation lives in `packages/design-system-core/scripts/generate-tokens.mjs`.
- Commercial HELM may generate derived docs such as contrast tables, but it must not write canonical token artifacts.
