Example project — Frond is not real.
Authored demo content for a fictional plant-care app, rendered by the same parsers and held to the same invariants as a real project's dashboard. This is the system in use, three months in.
Styleguide
The design system's surface: the colors, type, scale, and components the app is built from. Derived from globals.cssat build time — a token edit updates these pages in the same commit, so they can't drift. To change a value, change the CSS.
Token health
271 defined · 67 unreferenced · 1 referenced-but-undefined (0 silent)Unreferenced (67) — defined in globals.css, used by nothing; the punch-list B5 prune feed
--neutral-600 · --neutral-750 · --neutral-black · --brand-50 · --brand-100 · --brand-200 · --brand-300 · --brand-500 · --brand-800 · --brand-900 · --success-50 · --success-100 · --success-300 · --success-850 · --warning-50 · --warning-100 · --warning-300 · --warning-850 · --error-50 · --error-100 · --error-300 · --error-850 · --info-50 · --info-100 · --info-300 · --info-850 · --transparent-dark-0 · --transparent-dark-10 · --transparent-dark-16 · --transparent-dark-24 · --transparent-dark-32 · --transparent-dark-40 · --transparent-dark-64 · --transparent-dark-80 · --transparent-dark-90 · --transparent-light-4 · --transparent-light-8 · --transparent-light-32 · --transparent-light-40 · --transparent-light-64 · --transparent-light-80 · --surface-neutral-dark · --text-black · --border-lightest · --border-width-reg · --border-width-lg · --border-width-xl · --border-width-xxl · --interaction-hover-lighten · --interaction-hover-subtle · --surface-page · --surface-hover · --border-subtle · --border-default · --text-muted · --status-error-surface · --status-error-border · --status-error-text · --status-info-600 · --success · --error · --space-10 · --space-12 · --weight-extrabold · --font-size-tagline · --font-size-body-xxl · --tracking-wider
Referenced but undefined (1) — silent ones render as unset; the fix is repointing to an existing token, never minting one (CLAUDE.md rule 6)
fallback-guarded · --color-brand-dark — app/[surface]/styleguide/styleguide.css
Semantic tokens
What product code reaches for — never the primitives, never raw hex. Dark mode re-points ONLY this layer (plus a primitive safety net), so a surface built on semantics flips for free. Rows show the Tailwind utility, the token, its primitive target, and both theme values.
Surface
--surface-top→ --neutral-whitebg-surface-topinputs, cards, modals#ffffff#1c1f24--surface-popout→ --neutral-12bg-surface-popoutelevated panels#fbfbfc#24282e--surface-base→ --neutral-50bg-surface-basepage background#f1f3f5#131519--surface-inset→ --neutral-75bg-surface-insetsunken / inset areas#e9ecef#0e1013--surface-gray→ --neutral-200bg-surface-graymuted surfaces#c3cad2#363c44--surface-disabled→ --neutral-300bg-surface-disableddisabled backgrounds#a7b0bb#282c32--surface-base-inverse→ --neutral-800bg-surface-inversedark inverse surfaces#2c313a#edeff2--surface-neutral-dark→ --neutral-900deepest dark surfaces#171b21#090a0cBrand
--brand-subtle→ --brand-25bg-brand-subtleselected / active backgrounds#fbf5f0#382214--brand-light→ --brand-400bg-brand-lightmid-tone brand accent#c06b3e#d18a62--brand-main→ --brand-600bg-brand-mainprimary brand colour#92451f#d18a62--brand-strong→ --brand-700bg-brand-stronghover / emphasis on brand#7a3818#e0b092Text
--text-primary→ --neutral-850text-fg-primary#21262e#edeff2--text-secondary→ --neutral-700text-fg-secondary#434a54#b7bec8--text-tertiary→ --neutral-500text-fg-tertiary#6b7280#8a929e--text-gray→ --neutral-400text-fg-grayinactive tabs, de-emphasized#8892a0#6c747f--text-light→ --neutral-300text-fg-light#a7b0bb#545b65--text-inverse→ --neutral-25text-fg-inverse#f7f8f9#1c1f24--text-white→ --neutral-whitetext-fg-white#ffffffsame in dark--text-black→ --neutral-950#0d1013#ffffffBorder
--border-lightest→ --neutral-white#ffffff#24282e--border-light→ --neutral-50border-edge-light#f1f3f5#2a2e34--border-regular→ --neutral-75border-edge-regular#e9ecef#343941--border-strong→ --neutral-100border-edge-strong#e2e5e9#3f454e--border-stronger→ --neutral-150border-edge-stronger#d5dae0#4c525c--border-strongest→ --neutral-400border-edge-strongest#8892a0#6c747fConvenience aliases
--surface-page→ --surface-topnav bars, sticky headers#ffffff#1c1f24--surface-hover→ --interaction-hover-darkensubtle hover on light surfacesrgba(0, 0, 0, 0.078)rgba(255, 255, 255, 0.06)--border-subtle→ --border-stronglight dividers#e2e5e9#3f454e--border-default→ --border-strongerstandard visible borders#d5dae0#4c525c--text-muted→ --text-tertiaryde-emphasised text#6b7280#8a929eStatus
--status-success-light→ --success-25bg-success-light#ecfdf5#16271d--status-success-main→ --success-500bg-success#10b981#34d399--status-success-strong→ --success-600bg-success-strong#059669#6ee7b7--status-warning-light→ --warning-25bg-warning-light#fffbeb#2a2410--status-warning-main→ --warning-500bg-warning#f59e0b#fbbf24--status-warning-strong→ --warning-600bg-warning-strong#d97706#fcd34d--status-error-light→ --error-25bg-error-light#fef2f2#2a1614--status-error-main→ --error-500bg-error#ef4444#f87171--status-error-strong→ --error-600bg-error-strong#dc2626#fca5a5--status-error-surface→ --status-error-light#fef2f2#2a1614--status-error-border→ --status-error-main#ef4444#f87171--status-error-text→ --status-error-strong#dc2626#fca5a5--status-info-light→ --info-25bg-info-light#eff6ff#191e33--status-info-main→ --info-500bg-info#3b82f6#60a5fa--status-info-strong→ --info-600bg-info-strong#2563eb#bfdbfe--status-info-600→ --info-600#2563eb#93c5fd--success→ --status-success-main#10b981#34d399--error→ --status-error-main#ef4444#f87171Interaction
Hover overlays. lighten = on dark/brand fills · darken = on light surfaces · subtle = ghost buttons and nav. In dark mode every hover lightens — even the darken token.
--interaction-hover-lighten→ --transparent-light-16overlay on dark bgrgba(255, 255, 255, 0.161)rgba(255, 255, 255, 0.09)--interaction-hover-darken→ --transparent-dark-8overlay on light bgrgba(0, 0, 0, 0.078)rgba(255, 255, 255, 0.06)--interaction-hover-subtle→ --transparent-dark-4gentlest overlayrgba(0, 0, 0, 0.039)rgba(255, 255, 255, 0.04)Primitive ramps
The raw palette (Figma's _-prefixed collections). Not for components — reach through a semantic token. Dark values exist as a safety net for legacy callsites that still touch primitives directly; new code never should.
Neutral
--neutral-white#ffffff#1c1f24--neutral-12#fbfbfc#21252b--neutral-25#f7f8f9#21252b--neutral-50#f1f3f5#16181c--neutral-75#e9ecef#272b31--neutral-100#e2e5e9#30353c--neutral-150#d5dae0#3a4049--neutral-200#c3cad2#464d57--neutral-300#a7b0bb#5e6773--neutral-400#8892a0#808a97--neutral-500#6b7280#9aa3af--neutral-600#565e6b#b4bcc6--neutral-700#434a54#c8cfd7--neutral-750#373d46#d4dae0--neutral-800#2c313a#e1e5ea--neutral-850#21262e#edeff2--neutral-900#171b21#f4f6f8--neutral-950#0d1013#fafbfc--neutral-black#000000#ffffffBrand (copper — Groundwork's earth accent)
--brand-25#fbf5f0#2c1a10--brand-50#f6e7db#382214--brand-100#eed3bfsame in dark--brand-200#e0b092same in dark--brand-300#d18a62same in dark--brand-400#c06b3e#d18a62--brand-500#a9552csame in dark--brand-600#92451f#d18a62--brand-700#7a3818#e0b092--brand-800#5f2b13same in dark--brand-900#46200esame in darkStatus: Success
--success-25#ecfdf5#16271d--success-50#d1fae5#1a2f22--success-100#a7f3d0#1f3a29--success-300#6ee7b7#57b87d--success-500#10b981#34d399--success-600#059669#6ee7b7--success-850#064e3b#6ee7b7Status: Warning
--warning-25#fffbeb#2a2410--warning-50#fef3c7#33290f--warning-100#fde68a#3d3211--warning-300#fcd34d#c79a2e--warning-500#f59e0b#fbbf24--warning-600#d97706#fcd34d--warning-850#78350f#fcd34dStatus: Error
--error-25#fef2f2#2a1614--error-50#fee2e2#331a17--error-100#fecaca#3d1f1b--error-300#fca5a5#e0574c--error-500#ef4444#f87171--error-600#dc2626#fca5a5--error-850#7f1d1d#fca5a5Status: Info
--info-25#eff6ff#191e33--info-50#dbeafe#1f2540--info-100#bfdbfe#252c4d--info-300#93c5fd#6b80e0--info-500#3b82f6#60a5fa--info-600#2563eb#93c5fd--info-850#1e3a8a#bfdbfeTransparent overlays
Alpha layers for scrims, hovers, and photo overlays.
Transparent: Dark (black overlay)
--transparent-dark-0rgba(0, 0, 0, 0)same in dark--transparent-dark-4rgba(0, 0, 0, 0.039)same in dark--transparent-dark-8rgba(0, 0, 0, 0.078)same in dark--transparent-dark-10rgba(0, 0, 0, 0.1)same in dark--transparent-dark-16rgba(0, 0, 0, 0.161)same in dark--transparent-dark-24rgba(0, 0, 0, 0.239)same in dark--transparent-dark-32rgba(0, 0, 0, 0.322)same in dark--transparent-dark-40rgba(0, 0, 0, 0.4)same in dark--transparent-dark-64rgba(0, 0, 0, 0.639)same in dark--transparent-dark-80rgba(0, 0, 0, 0.8)same in dark--transparent-dark-90rgba(0, 0, 0, 0.9)same in darkTransparent: Light (white overlay)
--transparent-light-4rgba(255, 255, 255, 0.039)same in dark--transparent-light-8rgba(255, 255, 255, 0.078)same in dark--transparent-light-16rgba(255, 255, 255, 0.161)same in dark--transparent-light-32rgba(255, 255, 255, 0.322)same in dark--transparent-light-40rgba(255, 255, 255, 0.4)same in dark--transparent-light-64rgba(255, 255, 255, 0.639)same in dark--transparent-light-80rgba(255, 255, 255, 0.8)same in darkSource: app/globals.css — parsed by lib/styleguide.ts at build time. To change a value, change the CSS; this page follows in the same commit.