Headline.
One supporting sentence.
# Sean Tippen Design System - Build Contract If you read only this file, you can still build a correct on-system page without loading the CSS. Live reference and live examples: https://design.seantippen.com/ This is a dark-first, OKLCH, sharp-cornered system for data-dense dashboards and single-page references. Two stylesheets carry the whole thing: palette, three webfonts, type scale, spacing, motion, and every component named below. --- ## The system in one idea: rationed color on a flat dark field Everything is a flat, cool-dark canvas with one rationed cyan accent. Depth comes from lightness steps on a five-level surface ladder, never from decoration. Corners are square. Numbers are monospace with tabular figures so columns lock. Color is signal: cyan means interactive or current, status colors mean status, and nothing is colored just to look colored. Density is fine and expected. A dashboard is supposed to carry a lot of numbers. Calm comes from structural discipline (one spacing scale, one label size, one type hierarchy, one accent), not from removing data. When a page feels noisy the fault is inconsistency, a stray font size, a second accent, or boxes nested inside boxes. Fix the structure and keep the data. The three faces are a committed split and the split is what makes it work: Big Shoulders Display for exactly one hero header, Inter for every other heading and all body and UI text, JetBrains Mono for numbers, code, and uppercase labels. --- ## 1. Paste this into `
` ```html ``` tokens.css must come before components.css. All three faces (Inter, JetBrains Mono, Big Shoulders Display) load automatically through `@font-face` inside tokens.css, served from the same domain. Do NOT add a Google Fonts link; there is nothing left for it to fetch and it only costs a round trip. `darkreader-lock` plus `color-scheme: dark` stops a reader's dark-mode browser extension from re-mapping the palette. Keep both on any page whose look matters. Fastest correct start: clone the skeleton and edit content only. - `https://design.seantippen.com/starter.html` - dashboard skeleton with the rail nav, a stat band, a card grid, a scroll-wrapped data table, and one wired chart. --- ## 2. Hard rules (non-negotiable) - Use `var(--token-name)` in CSS. Never hardcode a hex, rgba, hsl, or oklch value. Chart.js dataset colors are the only exception (section 6). - ONE accent per layout. Cyan (`--color-accent`) leads. Neon pink (`--color-secondary`) is a STATE and second-series color only: a second chart series, one contrasting progress bar, one alternate KPI marker. It is never a page theme, never a heading color, never a background wash. - Blurple is banned. Hue 270 to 285 is fenced off at the generator tier and is the single most recognizable AI-generated tell. The accent knob's usable range is roughly 150 to 200; the secondary knob's is 300 to 360. - SIZE LAW: `font-size` only ever takes a `--text-*` token, never a raw rem or px value. `--text-xs` (13px floor) is the absolute minimum for ANY text, including captions, footnotes, chart annotations, badges, and pills. Never shrink a registry component's type in page CSS. - Every uppercase mono label uses `--text-label` (14 to 15px), weight 600 to 700, `--tracking-label`, and a muted color. That covers eyebrows, section numbers, KPI and stat labels, table headers, and nav links. Do not re-implement the role at a smaller size with a local class. - Radius is 0. `--radius` and every `--radius-*` except `--radius-full` resolve to 0. `--radius-full` is only for pills, badges, toggle thumbs, and circular dots. Never type a literal `border-radius` value. - No gradients. Not on backgrounds, not on text, not on rules or bars, not as a hover sheen. The canvas is flat `var(--color-bg)` and accents are solid. There is no sanctioned decorative background layer: no dot grid, no noise, no radial blobs, no cursor-tracking glow, no pattern overlay. `.bg-signal` still exists but paints a flat fill and nothing else. - Glass (`backdrop-filter: blur()`) is for floating chrome only: sticky nav, the nav rail, drawers, command palettes, modals. Never on a flat card. - Amber (`--color-warning`) means warning state. Never a decorative accent. - Text is never pure white. The top step is `--color-text`, which is already tuned; going brighter breaks the ladder. - Hover lifts with `translateY(-1px)` plus a deeper shadow, or picks up an accent border. Never `transform: scale()`, never a glow that follows the pointer. - `tabular-nums` on every numeric column, KPI, and stat value. - Wrap every `.data-table` and every chart canvas in `.table-scroll` or `.scroll-x`. Wide content scrolls inside its own box; the page body must never scroll horizontally at 390px. - All motion sits behind `@media (prefers-reduced-motion: no-preference)`. - No em-dashes in copy. Use commas, periods, semicolons, or parentheses. - Plain, literal copy. No hype words, no fake warmth, no "coming soon". --- ## 3. Tokens (most-used; the full set is in tokens.css) ``` /* generator tier - four knobs re-skin the entire system */ --accent-h 195 cyan, the one rationed accent --secondary-h 320 neon pink, state and second series only --base-h 252 cool-rich neutral hue for every surface and text step --contrast 1 0.85 calm ... 1.2 high-contrast (dark mode) /* surfaces - five-step elevation, depth from lightness not shadow */ --color-bg page canvas --color-surface card / panel / banded section --color-surface-hover row hover, faint fill --color-surface-raised raised control, button rest --color-surface-overlay floating overlay, command palette /* text - four steps, never pure white */ --color-text body and headings --color-text-secondary supporting copy --color-text-muted labels, captions, chrome --color-text-disabled disabled, ghost --text-alpha-90/70/50/30/15 text at opacity, for use over a variable background /* borders */ --color-border --color-border-emphasis --color-border-strong /* accent */ --color-accent the rationed cyan --color-accent-hover hover on accent surfaces --color-accent-solid-hover hover on a solid accent fill --color-accent-border interactive border --color-secondary neon pink, state only --accent-muted selected background tint --accent-subtle faint accent wash (active row, active chip) --color-accent-rgb / --color-secondary-rgb for legacy rgba(var(...), x) call sites /* status - fixed semantic hues, never accent-swapped */ --color-success --color-warning --color-danger --color-info --color-success-subtle --color-warning-subtle --color-danger-subtle --color-info-subtle /* chart series - HEX on purpose, see section 6 */ --green --blue --red --amber --purple --cyan --yellow --orange /* type */ --font-sans Inter, body and UI and every heading except the one hero --font-mono JetBrains Mono, numbers / code / uppercase labels --font-display Big Shoulders Display, the ONE hero header per page --text-xs (13px FLOOR) --text-sm --text-label --text-base --text-lg --text-xl --text-2xl --text-3xl --text-4xl all fluid clamp() --text-label the one size for every uppercase mono label --leading-tight/-snug/-normal/-relaxed --measure 65ch --tracking-display (-0.03em) --tracking-tight (-0.01em) --tracking-label (0.12em) /* spacing */ --space-xs/sm/md/lg/xl fluid --space-1 2 3 4 5 6 8 10 12 16 fixed, 4px base --space-section fluid band padding /* motion */ --duration-instant 80ms --duration-fast 150ms --duration-normal 250ms --duration-slow 400ms --ease-out (default) --ease-in --ease-in-out --ease-spring --ease-bounce /* shadow, focus, radius, layout */ --shadow-sm/-md/-lg --shadow-ring --shadow-float --shadow-float-lg --focus-ring use on :focus-visible, never :focus --radius 0 (and every --radius-* except) --radius-full 9999px --max-width 1100px --sidebar-w 260px ``` Light mode ships too. It activates on `:root.light` or `html[data-theme="light"]`; both hooks work. Every token above re-derives, so a page built on tokens flips for free. Persist the choice in `localStorage` and set the class before first paint. Compatibility aliases exist for older pages and stay supported permanently: `--bg --surface --surface2 --surface3 --surface-hover --text --text-dim --text-muted --text-secondary --text-disabled --accent --accent2 --secondary --border --border-emphasis`. New code should use the `--color-*` names. --- ## 4. Canonical page shell A left nav rail owns section wayfinding at 1100px and up. Below 1100px the rail becomes a slide-in sheet opened by a top-bar menu button. One link list serves both, so there is nothing to keep in sync. ```htmlOne supporting sentence.