@nicohaberkorn/design-system
v0.4.1
Published
A layered (palette -> reference -> role -> component) design token system for nicohaberkorn.com, built with Style Dictionary: resolves a large combinatorial color/typography/theme matrix at build time into stable, preset-scoped CSS.
Downloads
856
Readme
@nicohaberkorn/design-system
Design tokens (color, typography, layout) for nicohaberkorn.com, extracted from hand-authored CSS into a Style Dictionary pipeline.
Why
The site's original token CSS was hand-authored to let any visitor pick any combination of 8 independent theme axes (2 base palettes x ~20 color schemes x 4 contrast modes x typography variants) via a footer control panel. Production only ever ships one resolved combination (solarpunk) plus a runtime light/dark toggle — but the CSS itself shipped the full combinatorial matrix regardless, ~7,800 lines of color values alone.
This package's build resolves the entire PAL -> REF -> ROLE chain at build time for every axis except theme (the one axis that's still runtime-switchable), and ships only the two resulting theme variants under the same stable public token names (--nh-role-color-*, --nh-role-type-*, --color-comp-*). No --nh-pal-* or --nh-ref-* custom property ships in a preset build at all.
Architecture
tokens/ DTCG token source (JSON), the actual source of truth
color/{pal,ref,role,comp}/
type/{pal,ref,role}.json
layout/layout.json
registry.js axis -> value -> source-file-path map
presets.js preset definitions (solarpunk, technology) — mirrors next-app's VIBES
scripts/
migrate-from-css.mjs ONE-TIME: parsed next-app's original CSS into tokens/ (kept for provenance)
build-tokens.mjs preset builds -> dist/<preset>/{root,dark}.css + dist/foundation.css
build-dev-all.mjs dist/dev-all/ — full unpruned matrix for design-exploration tooling
build-primitives.mjs dist/primitives.css (hand-authored, not run through Style Dictionary)
verify-parity.mjs diffs resolved values against next-app's live CSS cascade
src/primitives/ hand-authored CSS (Every-Layout primitives) — not tokens, copied as-isBuild
npm install
npm run build # -> dist/
npm run verify # diffs dist/solarpunk/{root,dark}.css against next-app's CSS cascadenpm run verify expects a sibling checkout of nicohaberkorn.com at ../nicohaberkorn.com (override with NH_SITE_STYLES=/path/to/next-app/styles).
Consuming this package
@import "@nicohaberkorn/design-system/foundation.css"; /* layout tokens, ships once */
@import "@nicohaberkorn/design-system/primitives.css"; /* stack/cluster/center/cover/sidebar/etc */
@import "@nicohaberkorn/design-system/presets/solarpunk/root.css";
@import "@nicohaberkorn/design-system/presets/solarpunk/dark.css";In development, if you need every axis to stay live-switchable (e.g. a design-exploration picker), dynamically import @nicohaberkorn/design-system/dev-all.css instead of/alongside the preset files — it preserves the original [data-*]-selector cascade rather than resolving it away. See nicohaberkorn.com's next-app/components/Footer.tsx for a working example.
Adding a new preset
Add axis choices to presets.js, add any new token source files under tokens/ if a hue/scheme doesn't exist yet, add the preset name to BUILT_PRESETS, rerun npm run build. Nobody hand-edits dist/**.
