cortena-design
v3.6.0
Published
Cortena design tokens — the single source of truth for the Ascendence AI visual language.
Readme
cortena-design
Design tokens for Cortena and Ascendence AI — the single source of truth for colour, type, spacing, radius, shadow, motion and chart palettes.
Intended consumers: cortena (cortenaweb, cortena-auth) and cortena-extensions
(11 web apps). Wiring those apps up is out of scope for this package — see
CONSUMING.md.
Build
pnpm install
pnpm check # fails if dist/ is stale
pnpm test --maxWorkers=2 # 278 tests
pnpm build # writes dist/
pnpm lint <path> # fails on hard-coded values in a consuming appOpen dist/guide.html to see everything rendered, with contrast ratios computed live.
How it works
src/tokens/*.json is the only thing edited by hand. build/build.mjs validates it,
enforces WCAG AA, and emits dist/. dist/ is committed, so consumers compile nothing.
The contrast gate fails the build. If a colour does not clear its threshold, do not
lower the threshold — pick a nearer stop of the same hue, mark it $derived: true, and
record the measured ratio in its $description.
Every semantic colour must declare $contrastAgainst or $decorative. Without that
rule the gate is opt-in, and a token added without a declaration is checked by nothing.
The ramp gate fails the build too. The contrast gate is the wrong instrument for a sequential or diverging ramp — a ramp's low end means "near zero" and is supposed to recede into the canvas — so the ramps are checked for what they actually have to prove: one hue for sequential, monotone lightness, at least 0.06 OKLCH lightness between adjacent steps, and a genuinely neutral midpoint with opposed poles for diverging. Re-step a ramp that fails; do not relax the check.
The lint fails the build too. cortena-design-lint reports every hard-coded
value a token exists for, and every var() that does not resolve — with the nearest
token and its value, computed from dist/tokens.css rather than a table. It walks
.css, .tsx, .jsx and, since 3.3.0, .ts. Suppressing a line requires a reason.
See LINTING.md.
See CONSUMING.md for how other repos pull this in, and CHANGELOG.md for what
changed in each release from 3.4.1 on (earlier ones are in the git log).
