Build a source-derived, fully tokenized design system with a parametric theming engine at its
core. Extract the source’s design language (the design file + code) into an exhaustive token foundation, then
let an agent (or human) re-parametrize it from minimal input: give one color anchor (e.g. a
900) and it derives the full coherent scale; swap the type families (e.g. General
Sans / Geist Mono) and it re-applies them across components; pick a radius scale
(sm/md/lg with defined ranges) and everything updates,
all previewable on real components. Build the foundation (visual tokens) first, then structure /
layout and behavior / states, working toward duplicating + re-theming components to compare
variations and, ultimately, one-shotting on-brand pages. Delivered as paired artifacts: an
agent-facing spec (.md) and a mirror human-readable doc, backed by a component
library solid enough to one-shot things.
.md) and the same content in a human-readable /
usable form (e.g. HTML).
xxx-900 as the base” and the system derives the rest of the scale to match that single anchor, with all UI colors flowing from it.sm (max ~6–8px), md (max ~12–16px), lg (~2–24px range), and have components update.the source repo → packages/design-system (on develop).the source UI package
wrappers. They must be generic enough to build a comprehensive marketing site and, since
the product won’t differ much from the site, a product screen too. Every component is
token-only (no hardcoded values) so theming flows through.
-900).
data-theme) that overrides the token CSS variables; base components never change. One component, infinite themes, blueprint always intact. Saved variants can also be written as their own preview route.pocket-ui). The transit layer gets archived/parked; the source-based system is built here so we reuse the toolchain..md spec and the human doc are generated from them, so they can never drift.packages/design-system + the design file variables; produce a raw inventory (color scales, type, space, radius, shadow, motion, z, breakpoints), light + dark where present..md spec + human docs from the single source; wire the skill.the source repo → packages/design-system/ui-preset/src
(theme/tokens/{colors,typography,effects}.ts, theme/extension/theme.ts,
constants.ts). These are the source’s real, exported token values — not inferred. Design file not yet read.
The source system exposes role-based CSS variables, each defined for light and dark. Components never touch raw colors — only roles. Categories found:
The semantic values resolve to Tailwind’s default palette: zinc = neutrals, blue = interactive/brand (light blue-500, dark blue-400), rose = danger, and emerald / amber / violet / orange for tags. There is no separate 50–950 ramp file — semantics reference resolved palette values directly. So the seed→ramp engine needs us to (re)generate numeric ramps and re-map semantics onto them.
Two families: Inter (sans) + Roboto Mono (mono); weights 400 / 500 only. Named text styles by family: h1–h4-webs (marketing, up to 4rem), h1–h3-core (app), h1–h4-docs, body txt-* (xsmall→xlarge, -plus=500), txt-compact-* (tight 1.25rem leading), code-* (mono).
Rich, layered, light + dark — the source’s signature. Tokens: elevation-card-rest/hover, elevation-flyout / tooltip / modal / commandbar / code-block, plus buttons-*, borders-* (base/error/focus/interactive), details-switch-*. These double as borders+focus rings, not just drop shadows.
The preset only customizes colors and boxShadow. Spacing, border-radius, breakpoints, and the font-size scale fall back to Tailwind defaults (radius: 2 / 4 / 6 / 8 / 12 / 16 / 24px / full; spacing 4px base; screens 640/768/1024/1280/1536).
Implication: your parametric radius scale (sm / md / lg) is a new layer we design — the source system has no equivalent. Needs your confirmation of the exact scales (see decisions below).
The design file is the same source UI file and its variables match the code (spot-checked: foregrounds/fg-base = #18181b = code’s --fg-base; font/family/body = Inter). The design file organizes tokens as collections: foregrounds/, backgrounds/, borders/, font/family/, font/weight/, Labels/ (type styles). The Dev-Mode tool reads variables per node (leaf nodes work; whole pages don’t).
Conclusion → sources strategy: code is the authoritative token source (it’s the exported output of these design-file variables); the Tailwind palette supplies the exact numeric ramps; the design file is reserved for component anatomy + page layouts (read later via get_design_context when we build components). Nothing is guessed.
Port the entire the source system token set verbatim (light + dark): all bg / fg / border / button / tag / contrast / alpha colors, the full typography styles, and every elevation shadow. Nothing trimmed — maximum fidelity. We build our additions and theming engine on top of it.
bg-accent, bg-accent-hover, fg-on-accent.error directly but success/warning only live inside tags. Forms/alerts on a site usually need them. Proposed add: fg/bg/border for success + warning.Token scale (px, grounded in Tailwind’s radii): xs 4 · sm 6 · md 8 · lg 12 · xl 16 · 2xl 24 · full.
Semantic radii components reference: radius-control (inputs/buttons) · radius-card · radius-popover · radius-pill.
Global modes remap the semantic radii (your final values):
| role | sharp | default | round |
| control | 2 | 6 | 8 |
| card / panel | 4 | 8 | 12 |
| popover / menu | 4 | 8 | 12 |
| pill | full | full | full |
tokens/tokens/source/{colors,typography,effects}.ts — verbatim the source system export (light + dark): 90 color vars/mode, 23 shadows, 35 type styles.tokens/additions.ts — accent / success / warning (14 vars/mode), each grounded in the source’s palette.tokens/radius.ts — scale + semantic radii + sharp/default/round modes (your values).tokens/fonts.ts — swappable Inter / Roboto Mono stacks. tokens/index.ts assembles + documents provenance.app/foundation.cssscripts/build-tokens.ts (run via npx tsx) emits the foundation: :root light, .dark / [data-theme="dark"], [data-radius="sharp|round"], and the typography utilities wired to --font-* (so a family swap re-flows every text style). Single source → generated CSS, no hand-editing.
/foundation now exhaustiveRenders every ported token with its name + live-resolved value: Backgrounds (20), Foregrounds (9), Borders (8), Buttons (12), Tags (30), Contrast (9), Alpha (2) = 90 colors; plus Additions (14), Shadows (23), Radius, Typography (35). Alpha/transparent tokens render over a checker so transparency reads. light/dark + sharp/default/round toggles re-theme the whole tree via scoped CSS variables (verified: dark → bg-base #212124, accent → #3b82f6; sharp → control 2px) — the non-destructive mechanism the engine will drive.
tokens/primitives/colors.ts — the full Tailwind v3 palette (22 hues × 11 steps = 242), the exact atoms behind the source's semantics (verified zinc-900 #18181b, blue-500 #3b82f6, rose-600 #e11d48). tokens/primitives/spacing.ts — Tailwind v3's 35-step spacing scale. Both emitted as CSS vars (--color-<hue>-<step>, --space-<n>).
Icons — components/icons/: our own set (per your choice), drawn on the source's grid (15px · 1.5 stroke · round caps · currentColor), grown as needed. 21 to start (check, x, chevrons, arrows, search, trash, pencil, copy, info, alert, more, external-link, user, settings…). All on /foundation.
You asked for, in order: 1) exhaustive reference done → 2) capture missing primitives (color ramps 50–950, explicit spacing scale, icons) → 3) components (Phase 3) → 4) theming engine (Phase 2). Components now come before the engine.
Live at /ds: Button (accent / primary / neutral / ghost / danger · sm/md/lg · icons · states), Badge (6 the source system tag colors), Card (outline + elevated). New namespace components/ds/ (the parked v1 ui/ and transit v2/ are left untouched). Every value reads a CSS variable — verified the whole set re-themes across light/dark + sharp/default/round with no component code change.
Styling basis: token-referencing classes (bg-[var(--bg-accent)], rounded-[var(--radius-control)]) — no hardcoded values. A shorter utility-alias layer (Tailwind @theme) can be added later without touching components.
Remaining site-first pieces: section scaffolding — nav / header, hero, feature grid, footer, CTA — composed from these atoms. Then more controls (Input, Select…) and the theming engine (Phase 2 / your #4).
One dark neutral seed (e.g. a 950 from slate/gray/zinc/neutral/stone, or any custom dark color) generates a full neutral ramp. All chrome — surfaces, text, borders, buttons — derives only from that ramp. Accent colors (blue/red/green) are reserved for markers (chips, badges, status), never chrome. Change the one seed → the whole site's personality changes (cool / warm / pure), while functional markers stay constant.
Browser-native: each step is oklch(from var(--neutral-seed) <L> c h) — one seed variable drives the whole ramp, no JS color math, no dependency. The lightness curve (L per step) is grounded in zinc's actual OKLCH so contrast stays proven; the seed supplies hue + chroma. Verified: slate→cool, stone→warm, zinc→pure, custom teal→teal-gray, all live from one color.
Each chrome token was mapped to a ramp step by matching its OKLCH lightness to the zinc reference (53 chrome tokens neutralized, 37 markers kept literal — tokens/chrome.ts). The ramp is computed in JS to concrete oklch() values (lib/theme/ramp.ts); rampVars(seed) sets the 16 --neutral-* vars on a scope and chrome re-resolves against them. Verified live: switching the seed turns the primary button cool (slate 264°) / warm (stone 49°) / green (forest 157°) and tints every surface, while badge markers stay constant.
tokens/typography.ts: display · h1 · h2 · h3 · body · body-sm · caption · code. One heading family, weight as an axis (no -plus), no separate compact set.additions layer (success/warning duplicated the green/orange tags; accent was already dropped). One marker set: neutral · blue(info) · green(success) · orange(warning) · red(danger); purple dropped.--borders-focus.
components/ds/sections.tsxToken-only, lean-type, composed from the atoms: Nav (brand · links · CTA), Hero (eyebrow · display headline · sub · CTAs), FeatureGrid (icon cards), CTA band (inverted), Footer (columns). All flexible via props. Every value reads chrome vars, so a seed/theme/radius change re-skins all of them.
/siteA full marketing page composed from the sections, with a floating control (seed swatches + custom · light/dark · radius). Verified: switching the seed re-skins the entire page — hero, feature cards, the dark CTA band, footer — from cool (slate) to green (forest) etc., markers constant.
/dsThe generated neutral ramp for the current seed, shown as 12 swatches numbered 000–950, live as you pick a color.
--radius-chip (sharp 2 · default 4 · round 4); Badge uses it (slightly-rounded, no longer a pill).uppercase / all-caps label; labels are normal case now.color-mix 16% toward the base, so chips pick up the ramp's undertone and sit well on any seed; text/icon stay saturated for legibility.