Docs · Design tokens

Sports Operations Docs · Design tokens, home

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.css read 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") in src/components/desk/globe.tsx, col("--globe-land") in src/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

TokenDarkLightContrastUse
--bg#07090e#eef1f6#000000Page background
--panel#10151c#ffffff#0a0a0aPanels, cards, tooltips
--raised#18202b#f4f7fb#1f1f1fHover and selected rows inside a panel
--ink#f3f6fa#0e1620#ffffffPrimary text
--fg#f3f6fa#0e1620#ffffffBody text color; same value as --ink
--muted#b7c2d0#3e4c5e#f0f0f0Secondary text
--dim#9aa7b8#4d5d72#e0e0e0Captions, axis labels, timestamps
--faint#8d9aab#5c6b7e#d4d4d4Least emphasis that still passes contrast
--line#243140#d5deea#a3a3a3Panel borders
--line-soft#1b2633#e6edf5#5c5c5cRow dividers
--accent#8eb4d4#2a6288#9fd3ffLinks, active tab, section labels
--accent-ink#071018#ffffff#000000Text on an accent fill
--warn#c4a36a#8a5a12#ffd27aNot live, late twins, hits
--shadow0 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 #ffffffFloating 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).

TokenDarkLightContrastUse
--c1#8eb4d4#2a6288#9fd3ffRec, square, first series
--c2#9aa8c4#3d4e78#c9d2ffSecond series
--c3#6fbfa3#1c6b52#7dffc4Sharp, ok, gains (text-pos)
--c4#c4a36a#8a5a12#ffd27aLate, watch, warn
--c5#e08b82#a33b32#ff9b91Steam, high, errors, losses (text-neg)
--c6#7ec8c4#146864#8ff5efExchange books
--c7#b39ddb#5b3f9e#dcc8ffCrypto books, whales
--cyan#8eb4d4#2a6288#9fd3ffOlder name for --c1; prefer --c1

Globe

Both globes read these: the SVG globe on the desk and the WebGL globe on the security model.

TokenDarkLightUse
--globe-deep#070b12#dfe7f1Ocean, far side
--globe-sea#16324a#f4f8fcOcean, near side
--globe-land#6d94b4#4a7ba6Land in daylight
--globe-landnight#22364a#8aa6c0Land on the night side
--globe-night-k0.320.82Ocean brightness at night
--globe-coast#c5d7e6#1d456bCoastlines
--globe-grid#2c4256#b5c6d8Graticule
--globe-air#8eb4d4#7fa8ccAtmosphere and routes
--globe-city#d2b07a#8a5a12City markers

Type, spacing and motion

The same in both themes. 10 px is the floor for anything a person has to read.

TokenValueUse
--sans"Geist Variable", ui-sans-serif, sans-serifBody and labels
--mono"Geist Mono Variable", ui-monospace, monospaceNumbers, odds, ids, clocks
--fs-2xs10pxChips, table group headers
--fs-xs11pxDense table cells
--fs-sm12pxDefault table text
--fs-md13pxPanel body
--fs-lg14pxPanel titles
--fs-xl18pxScreen titles
--fs-2xl22pxHeadline numbers
--tr-10.04emBody tracking
--tr-20.08emUppercase labels
--tr-30.14emDisplay caps
--r-sm4pxChips, inputs
--r-md8pxPanels, popovers
--r-lg12pxModals
--easecubic-bezier(0.22, 0.7, 0.2, 1)Every transition