Cronwerk UI

Adoption

Roll Cronwerk UI into an existing product incrementally — theming setup, font strategy, versioning, and keeping drift out.

stable

Incremental adoption

You do not have to rewrite anything. Cronwerk is designed to land one surface at a time:

  1. Tokens first. Import @cronwerk/tokens/tokens.css and start replacing ad-hoc colors, spacing, and radii with the CSS variables. Nothing visual changes until you opt a surface in — but new work now speaks the language.
  2. Leaf components next. Swap in Button, Chip, Card, and inputs where you already have equivalents. They are self-contained and carry their own styles via @cronwerk/ui/styles.css.
  3. Zones, then pages. Move whole sections onto Panel and the layout primitives once the leaves feel right. Reserve the halftone accent panel for the one statement moment per page.

Theming setup

Theming is one attribute: data-theme="dark" on <html> (light is the default, so no attribute means light). The mechanics:

  • Pre-paint snippet (@cronwerk/tokens/theme-init.js) sets data-theme before first paint from the shared cronwerk-theme localStorage key — inline it in <head> to avoid a flash.
  • Runtime toggle: wrap the tree in ThemeProvider from @cronwerk/ui/theme and call toggleTheme() (or use getTheme/setTheme from @cronwerk/tokens). The key is shared across every Cronwerk property, so a user’s choice follows them between apps.
  • Dark theme comes free for canvas, Card, and neutral/soft Panel. The accent panel stays orange in both themes by design.

Font strategy

Fonts are the consumer’s responsibility (the tokens only name the families). Two supported routes:

  • Bundle with Fontsource (@fontsource-variable/inter, @fontsource-variable/jetbrains-mono) — best for apps that control their build. Self-hosted, no third-party requests.
  • Self-host the woff2 files and declare @font-face yourself if you already have a font pipeline. Match the family names the tokens expect (Inter Variable, JetBrains Mono Variable) or override --font-sans / --font-mono.

Prefer preloading the primary text font (Inter) for a fast LCP; the tokens set font-display behavior at the consumer layer.

Versioning & the public API

Each package is versioned independently with semver. What counts as a breaking change:

  • Token names are public API. Renaming or removing a --token is a MAJOR bump (LIBRARY-SPEC §9) — values can shift within reason, names cannot.
  • Component props follow normal semver: additive props are MINOR, removed or retyped props are MAJOR.

Pin ranges accordingly and read the changesets before a major upgrade.

Do

Consume tokens through the CSS variables (var(--accent)) so a value change flows in automatically.

Don't

Don’t hard-copy a token’s hex into your code — you opt out of theming and every future value fix.

Keeping drift out

Once adopted, keep the surface honest. The repo ships a drift audit (pnpm drift:audit) that flags hard-coded values that should be tokens, and an adoption report (pnpm adoption:report) that tracks how much of each consumer is on the language. Wire them into your own CI as you migrate.