Styleguide
The design this app is built on, shared by the product and this dashboard. Every token and component says who reaches for it. Derived from globals.css at build time. To change a value, change the CSS.
No feature doc carries area: design, so these pages are the only home the product's design has.
Token health
244 defined, 173 in:root: 35 both · 2 product · 62 dashboard · 74 unused · 0 referenced-but-undefined (0 silent)Unused (74): nothing reaches for these; the ramps among them are palette
Neutral --neutral-150 · --neutral-700 · --neutral-800 · --neutral-950 · --neutral-black
Brand (indigo — swap for your own accent) --brand-50 · --brand-100 · --brand-200 · --brand-300 · --brand-500 · --brand-800 · --brand-900
Status: Success --success-50 · --success-100 · --success-300 · --success-500 · --success-600 · --success-850
Status: Warning --warning-50 · --warning-100 · --warning-300 · --warning-600 · --warning-850
Status: Error --error-50 · --error-100 · --error-300 · --error-500 · --error-600 · --error-850
Status: Info --info-25 · --info-50 · --info-100 · --info-300 · --info-500 · --info-600 · --info-850
Transparent: Dark (black overlay) --transparent-dark-0 · --transparent-dark-4 · --transparent-dark-8 · --transparent-dark-10 · --transparent-dark-24 · --transparent-dark-32 · --transparent-dark-40 · --transparent-dark-64 · --transparent-dark-80 · --transparent-dark-90
Transparent: Light (white overlay) --transparent-light-4 · --transparent-light-8 · --transparent-light-24 · --transparent-light-32 · --transparent-light-40 · --transparent-light-64 · --transparent-light-80
Surface --surface-disabled · --surface-base-inverse
Status --status-success-main · --status-error-main · --status-info-light · --status-info-main · --status-info-strong
RADIUS --radius-none · --radius-lg · --radius-xl · --radius-form
SPACING --space-jumbo-1 · --space-jumbo-3
Font families & weights --weight-light
Heading sizes (desktop defaults) --font-size-h1 · --font-size-h3-plus
Line heights & letter spacing --tracking-tight
SHADOWS --shadow-sm · --shadow-md · --shadow-lg · --shadow-xl
Dashboard only (62): the dashboard's own
Neutral --neutral-12 · --neutral-25 · --neutral-100 · --neutral-200 · --neutral-300 · --neutral-400 · --neutral-900
Brand (indigo — swap for your own accent) --brand-25 · --brand-400
Status: Success --success-25 · --success-700
Status: Warning --warning-25 · --warning-500 · --warning-700
Status: Error --error-25 · --error-700
Transparent: Dark (black overlay) --transparent-dark-16
Transparent: Light (white overlay) --transparent-light-16
Surface --surface-popout · --surface-gray · --surface-chip
Brand --brand-subtle · --brand-light · --brand-faded
Text --text-light · --text-inverse
Border --border-light · --border-regular · --border-strong · --border-stronger · --border-strongest
Convenience aliases --border-subtle
Status --status-success-light · --status-success-strong · --status-warning-light · --status-warning-main · --status-warning-strong · --status-error-light · --status-error-strong
RADIUS --radius-tiny · --radius-sm · --radius-circle · --radius-pill
SPACING --space-tiny · --space-xxs · --space-xs · --space-sm · --space-xxl · --space-jumbo-2
Font families & weights --font-heading · --font-mono · --weight-regular · --weight-medium
Heading sizes (desktop defaults) --font-size-h3 · --font-size-h4
Body sizes (desktop defaults) --font-size-body-lg
Line heights & letter spacing --leading-tight · --leading-snug · --leading-normal · --leading-relaxed · --tracking-normal
SHADOWS --shadow-modal
Product only (2): the product's own
Text --text-white
Heading sizes (desktop defaults) --font-size-h2
Referenced but undefined (0) — silent ones render as unset; the usual fix is repointing to a token that exists
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-whitebothbg-surface-topinputs, cards, modals#ffffff#1c1f24--surface-popout→ --neutral-12dashboardbg-surface-popoutelevated panels#fbfbfc#24282e--surface-base→ --neutral-50bothbg-surface-basepage background#f1f3f5#131519--surface-inset→ --neutral-75bothbg-surface-insetsunken / inset areas#e9ecef#0e1013--surface-gray→ --neutral-200dashboardbg-surface-graymuted surfaces#c3cad2#363c44--surface-disabled→ --neutral-300unusedbg-surface-disableddisabled backgrounds#a7b0bb#282c32--surface-base-inverse→ --neutral-800unusedbg-surface-inversedark inverse surfaces#2c313a#edeff2--surface-chip→ --transparent-dark-16dashboard16% dark over the host surface#000000 16%#ffffff 16%Brand
--brand-subtle→ --brand-25dashboardbg-brand-subtleselected / active backgrounds#eef2ff#24204a--brand-light→ --brand-400dashboardbg-brand-lightmid-tone brand accent#6366f1#818cf8--brand-main→ --brand-600bothbg-brand-mainprimary brand colour#4338ca#818cf8--brand-strong→ --brand-700bothbg-brand-stronghover / emphasis on brand#3730a3#a5b4fc--brand-faded→ --brand-maindashboard#4338ca 45%#818cf8 45%Text
--text-primary→ --neutral-850bothtext-fg-primary#21262e#edeff2--text-secondary→ --neutral-750bothtext-fg-secondary#373d46#c5ccd6--text-tertiary→ --neutral-600bothtext-fg-tertiary#4c5360#a4adb9--text-gray→ --neutral-500bothtext-fg-graythe quietest text rung: inactive tabs, metadata#636977#88919c--text-light→ --neutral-300dashboardtext-fg-lightdisabled and decorative only, never text a reader needs#a7b0bb#545b65--text-inverse→ --neutral-25dashboardtext-fg-inverse#f7f8f9#1c1f24--text-white→ --neutral-whiteproducttext-fg-white#ffffffsame in darkBorder
--border-light→ --neutral-50dashboardborder-edge-light#f1f3f5#2a2e34--border-regular→ --neutral-75dashboardborder-edge-regular#e9ecef#343941--border-strong→ --neutral-100dashboardborder-edge-strong#e2e5e9#3f454e--border-stronger→ --neutral-400dashboardborder-edge-strongerthe control boundary, 3:1 on every surface#7d8694#6c737d--border-strongest→ --neutral-500dashboardborder-edge-strongest#636977#88919cConvenience aliases
--border-subtle→ --border-strongdashboardlight dividers#e2e5e9#3f454eStatus
--status-success-light→ --success-25dashboardbg-success-light#ecfdf5#16271d--status-success-main→ --success-500unusedbg-success#10b981#34d399--status-success-strong→ --success-700dashboardbg-success-strong#047857#6ee7b7--status-warning-light→ --warning-25dashboardbg-warning-light#fffbeb#2a2410--status-warning-main→ --warning-500dashboardbg-warning#f59e0b#fbbf24--status-warning-strong→ --warning-700dashboardbg-warning-strong#b45309#fcd34d--status-error-light→ --error-25dashboardbg-error-light#fef2f2#2a1614--status-error-main→ --error-500unusedbg-error#ef4444#f87171--status-error-strong→ --error-700dashboardbg-error-strong#b91c1c#fca5a5--status-info-light→ --info-25unusedbg-info-light#eff6ff#191e33--status-info-main→ --info-500unusedbg-info#3b82f6#60a5fa--status-info-strong→ --info-600unusedbg-info-strong#2563eb#bfdbfeThe ladder on every surface
Each rung that carries information, measured on each surface it can land on, in both themes. A rung clears its floor everywhere or it is not a rung. The heavier figure per theme is that theme's hard surface. Computed at build from the values above.
| Rung | lighttop | lightpopout | lightbase | lightinset | darktop | darkpopout | darkbase | darkinset | Floor |
|---|---|---|---|---|---|---|---|---|---|
--text-primary | 15.20 | 14.70 | 13.67 | 12.82 | 14.34 | 12.86 | 15.87 | 16.54 | 4.5:1 |
--text-secondary | 10.95 | 10.59 | 9.84 | 9.23 | 10.22 | 9.16 | 11.30 | 11.78 | 4.5:1 |
--text-tertiary | 7.74 | 7.48 | 6.96 | 6.53 | 7.28 | 6.53 | 8.06 | 8.40 | 4.5:1 |
--text-gray | 5.50 | 5.32 | 4.95 | 4.64 | 5.18 | 4.64 | 5.72 | 5.97 | 4.5:1 |
--border-stronger | 3.68 | 3.56 | 3.31 | 3.10 | 3.45 | 3.09 | 3.82 | 3.98 | 3:1 |
Primitive ramps
The raw palette: the _-prefixed sections of globals.css. Not for components — reach through a semantic token. Dark values are a safety net for any callsite that reaches a primitive directly; components never should.
Neutral
--neutral-whiteboth#ffffff#1c1f24--neutral-12dashboard#fbfbfc#21252b--neutral-25dashboard#f7f8f9#21252b--neutral-50both#f1f3f5#16181c--neutral-75both#e9ecef#272b31--neutral-100dashboard#e2e5e9#30353c--neutral-150unused#d5dae0#3a4049--neutral-200dashboard#c3cad2#464d57--neutral-300dashboard#a7b0bb#5e6773--neutral-400dashboard#7d8694#808a97--neutral-500both#636977#9aa3af--neutral-600both#4c5360#b4bcc6--neutral-700unused#434a54#c8cfd7--neutral-750both#373d46#d4dae0--neutral-800unused#2c313a#e1e5ea--neutral-850both#21262e#edeff2--neutral-900dashboard#171b21#f4f6f8--neutral-950unused#0d1013#fafbfc--neutral-blackunused#000000#ffffffBrand (indigo — swap for your own accent)
--brand-25dashboard#eef2ff#1e1b3a--brand-50unused#e0e7ff#24204a--brand-100unused#c7d2fesame in dark--brand-200unused#a5b4fcsame in dark--brand-300unused#818cf8same in dark--brand-400dashboard#6366f1#818cf8--brand-500unused#4f46e5same in dark--brand-600both#4338ca#818cf8--brand-700both#3730a3#a5b4fc--brand-800unused#312e81same in dark--brand-900unused#1e1b4bsame in darkStatus: Success
--success-25dashboard#ecfdf5#16271d--success-50unused#d1fae5#1a2f22--success-100unused#a7f3d0#1f3a29--success-300unused#6ee7b7#57b87d--success-500unused#10b981#34d399--success-600unused#059669#6ee7b7--success-700dashboard#047857#6ee7b7--success-850unused#064e3b#6ee7b7Status: Warning
--warning-25dashboard#fffbeb#2a2410--warning-50unused#fef3c7#33290f--warning-100unused#fde68a#3d3211--warning-300unused#fcd34d#c79a2e--warning-500dashboard#f59e0b#fbbf24--warning-600unused#d97706#fcd34d--warning-700dashboard#b45309#fcd34d--warning-850unused#78350f#fcd34dStatus: Error
--error-25dashboard#fef2f2#2a1614--error-50unused#fee2e2#331a17--error-100unused#fecaca#3d1f1b--error-300unused#fca5a5#e0574c--error-500unused#ef4444#f87171--error-600unused#dc2626#fca5a5--error-700dashboard#b91c1c#fca5a5--error-850unused#7f1d1d#fca5a5Status: Info
--info-25unused#eff6ff#191e33--info-50unused#dbeafe#1f2540--info-100unused#bfdbfe#252c4d--info-300unused#93c5fd#6b80e0--info-500unused#3b82f6#60a5fa--info-600unused#2563eb#93c5fd--info-850unused#1e3a8a#bfdbfeTransparent overlays
Alpha layers for scrims, hovers, and photo overlays.
Transparent: Dark (black overlay)
--transparent-dark-0unused#000000 0%same in dark--transparent-dark-4unused#000000 4%same in dark--transparent-dark-8unused#000000 8%same in dark--transparent-dark-10unused#000000 10%same in dark--transparent-dark-16dashboard#000000 16%same in dark--transparent-dark-24unused#000000 24%same in dark--transparent-dark-32unused#000000 32%same in dark--transparent-dark-40unused#000000 40%same in dark--transparent-dark-64unused#000000 64%same in dark--transparent-dark-80unused#000000 80%same in dark--transparent-dark-90unused#000000 90%same in darkTransparent: Light (white overlay)
--transparent-light-4unused#ffffff 4%same in dark--transparent-light-8unused#ffffff 8%same in dark--transparent-light-16dashboard#ffffff 16%same in dark--transparent-light-24unused#ffffff 24%same in dark--transparent-light-32unused#ffffff 32%same in dark--transparent-light-40unused#ffffff 40%same in dark--transparent-light-64unused#ffffff 64%same in dark--transparent-light-80unused#ffffff 80%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.