Design tokens
One palette, one type scale, one set of radii. They live in src/styles.css :root, the light and contrast themes override them in [data-theme="light"] and [data-theme="contrast"], and this file is the contract. bun run cli design reads the tables below with Bun.markdown and fails when a value here differs from the stylesheet, when a token is in one and not the other, when code reads a variable nothing defines, or when a component or route writes a hex color.
How to use them
- Desk classes in
src/styles.cssread the variables directly:color: var(--muted). - Tailwind utilities read the same variables through
@theme inline:bg-panel,text-ink,text-dim,border-line,text-accent,text-warn,text-pos,text-neg. They follow the light theme with no extra class. - Canvas and SVG code that needs a color string reads the token at draw time (
cssVar("--globe-sea")insrc/components/desk/globe.tsx,col("--globe-land")insrc/lib/remix/globe.js) and redraws on a theme change. - A new color is a new row here and a new line in both theme blocks. Never a hex literal in a component.
Surfaces and text
| Token | Dark | Light | Contrast | Use |
|---|---|---|---|---|
--bg | #07090e | #eef1f6 | #000000 | Page background |
--panel | #10151c | #ffffff | #0a0a0a | Panels, cards, tooltips |
--raised | #18202b | #f4f7fb | #1f1f1f | Hover and selected rows inside a panel |
--ink | #f3f6fa | #0e1620 | #ffffff | Primary text |
--fg | #f3f6fa | #0e1620 | #ffffff | Body text color; same value as --ink |
--muted | #b7c2d0 | #3e4c5e | #f0f0f0 | Secondary text |
--dim | #9aa7b8 | #4d5d72 | #e0e0e0 | Captions, axis labels, timestamps |
--faint | #8d9aab | #5c6b7e | #d4d4d4 | Least emphasis that still passes contrast |
--line | #243140 | #d5deea | #a3a3a3 | Panel borders |
--line-soft | #1b2633 | #e6edf5 | #5c5c5c | Row dividers |
--accent | #8eb4d4 | #2a6288 | #9fd3ff | Links, active tab, section labels |
--accent-ink | #071018 | #ffffff | #000000 | Text on an accent fill |
--warn | #c4a36a | #8a5a12 | #ffd27a | Not live, late twins, hits |
--shadow | 0 10px 28px color-mix(in srgb, #000 32%, transparent), 0 0 0 1px color-mix(in srgb, var(--ink) 6%, transparent) | 0 8px 22px rgba(14, 22, 32, 0.06), 0 0 0 1px rgba(14, 22, 32, 0.06) | 0 0 0 1px #ffffff | Floating panels |
Series and tones
--c1 to --c7 are the chart series and the data-tone colors. State is never color alone (AGENTS.project.md, accessibility).
| Token | Dark | Light | Contrast | Use |
|---|---|---|---|---|
--c1 | #8eb4d4 | #2a6288 | #9fd3ff | Rec, square, first series |
--c2 | #9aa8c4 | #3d4e78 | #c9d2ff | Second series |
--c3 | #6fbfa3 | #1c6b52 | #7dffc4 | Sharp, ok, gains (text-pos) |
--c4 | #c4a36a | #8a5a12 | #ffd27a | Late, watch, warn |
--c5 | #e08b82 | #a33b32 | #ff9b91 | Steam, high, errors, losses (text-neg) |
--c6 | #7ec8c4 | #146864 | #8ff5ef | Exchange books |
--c7 | #b39ddb | #5b3f9e | #dcc8ff | Crypto books, whales |
--cyan | #8eb4d4 | #2a6288 | #9fd3ff | Older name for --c1; prefer --c1 |
Globe
Both globes read these: the SVG globe on the desk and the WebGL globe on the security model.
| Token | Dark | Light | Use |
|---|---|---|---|
--globe-deep | #070b12 | #dfe7f1 | Ocean, far side |
--globe-sea | #16324a | #f4f8fc | Ocean, near side |
--globe-land | #6d94b4 | #4a7ba6 | Land in daylight |
--globe-landnight | #22364a | #8aa6c0 | Land on the night side |
--globe-night-k | 0.32 | 0.82 | Ocean brightness at night |
--globe-coast | #c5d7e6 | #1d456b | Coastlines |
--globe-grid | #2c4256 | #b5c6d8 | Graticule |
--globe-air | #8eb4d4 | #7fa8cc | Atmosphere and routes |
--globe-city | #d2b07a | #8a5a12 | City markers |
Type, spacing and motion
The same in both themes. 10 px is the floor for anything a person has to read.
| Token | Value | Use |
|---|---|---|
--sans | "Geist Variable", ui-sans-serif, sans-serif | Body and labels |
--mono | "Geist Mono Variable", ui-monospace, monospace | Numbers, odds, ids, clocks |
--fs-2xs | 10px | Chips, table group headers |
--fs-xs | 11px | Dense table cells |
--fs-sm | 12px | Default table text |
--fs-md | 13px | Panel body |
--fs-lg | 14px | Panel titles |
--fs-xl | 18px | Screen titles |
--fs-2xl | 22px | Headline numbers |
--tr-1 | 0.04em | Body tracking |
--tr-2 | 0.08em | Uppercase labels |
--tr-3 | 0.14em | Display caps |
--r-sm | 4px | Chips, inputs |
--r-md | 8px | Panels, popovers |
--r-lg | 12px | Modals |
--ease | cubic-bezier(0.22, 0.7, 0.2, 1) | Every transition |