Precise dark surface with a faint 32px hairline grid baked into the canvas. Geist-class sans, JetBrains Mono, one desaturated violet accent. The primary CTA carries a 1px violet underline as its only chromatic mark.
A complete design system, ready for your AI coding agent. Every primitive, token, and pattern below is generated straight from DESIGN.md — drop the file in your project and ship matching UI in minutes.
Prose-first token file — decisions live next to their reasoning.
Fine micro-scale (1–5px) for pills, editorial scale (12–21px) for the grid.
The system's own radius tokens — sm for chips and inputs, md for buttons, lg for cards, pill for fully-rounded CTAs.
Tokens describe the resting state. A real product needs every interaction state. Hover, focus, active, disabled, loading — all derived from the system's resting tokens.
1---2name: "Sable Hairline"3description: "Precise dark surface with a faint 32px hairline grid baked into the canvas. Geist-class sans, JetBrains Mono, one desaturated violet accent. The primary CTA carries a 1px violet underline as its only chromatic mark."4tags: [dark, "dev-tool", minimal, precise, hairline]5colors:6 primary: "#9D8CFF"7 secondary: "#E6E5E3"8 tertiary: "#7A7A82"9 neutral: "#0A0A0B"10 surface: "#131316"11typography:12 display: "Inter Tight"13 body: Inter14 mono: "JetBrains Mono"15 scale:16 hero: "3.75rem / 1.04 / 600 / -0.04em"17 h1: "2.25rem / 1.12 / 600 / -0.032em"18 h2: "1.375rem / 1.3 / 600 / -0.018em"19 body: "0.9375rem / 1.65 / 400 / -0.005em"20radius:21 sm: 4px22 md: 6px23 lg: 8px24 pill: 9999px25shadows:26 card: "0 0 0 1px rgba(255, 255, 255, 0.06)"27 button: "0 0 0 1px rgba(157, 140, 255, 0.35)"28borders:29 card: "1px solid rgba(255, 255, 255, 0.07)"30 divider: "rgba(255, 255, 255, 0.07)"31glass:32 surface: "#131316"33 blur: 0px34 border: "1px solid rgba(255, 255, 255, 0.07)"35 shadow: none36 backdrop: "linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px, linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px, #0A0A0B"37buttons:38 primary:39 background: #1B1B2040 color: #F4F3F041 border: 1px solid rgba(255, 255, 255, 0.10)42 shape: rounded43 padding: 10px 18px44 font: 500 / 0.875rem / -0.005em45 shadow: inset 0 -1px 0 0 #9D8CFF46 secondary:47 background: transparent48 color: #E6E5E349 border: 1px solid rgba(255, 255, 255, 0.10)50 shape: rounded51 padding: 10px 18px52 font: 500 / 0.875rem / -0.005em53 outline:54 background: transparent55 color: #9D8CFF56 border: 1px solid rgba(157, 140, 255, 0.35)57 shape: rounded58 padding: 10px 18px59 font: 500 / 0.875rem / -0.005em60 ghost:61 background: transparent62 color: #7A7A8263 border: none64 shape: rounded65 padding: 10px 6px66 font: mono / 400 / 0.8125rem / 067 hover: underline68charts:69 variant: line70 stroke_width: 1.571 gridlines: true72 highlight: last73 dot_marker: true74 axis_color: "#5A5A62"75 palette: ["#9D8CFF", "#7A7A82", "#3F3F46"]76fonts_url: "https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap"77dependencies: ["lucide-react"]78---79 80# Sable Hairline81 82## AI Build Instructions83 84> **Read this section before writing any code.** The rules below85> are non-negotiable. Every value used in the UI must come from this86> file's frontmatter — never substitute, approximate, or invent new87> colors, fonts, radii, or shadows. If a value is missing, ask the88> user before adding one.89 90### 1 · Your role91 92You are building UI for a project that has adopted **Sable Hairline** as its93design system. Treat `DESIGN.md` as the single source of truth.94Your job is to translate the user's product requirements into95components and pages that look like they were designed by the same96person who authored this file.97 98### 2 · Token compliance99 100- Pull every color, font family, radius, shadow, and spacing value101 from the frontmatter at the top of this file.102- Use semantic roles (e.g. `primary`, `accent`, `muted`) — never103 hard-code hex values that bypass the system.104- When a token can be expressed as a CSS variable, declare it once105 in your global stylesheet and reference it everywhere downstream.106- The Google Fonts `<link>` is provided in the Typography section.107 Add it to `<head>` before any component renders.108 109### 3 · Component recipes110 111Use these recipes verbatim when building the corresponding component.112 113#### Buttons114 115Four variants are defined. Pick one — never blend variants or invent a fifth.116 117- **Primary** — rounded shape, bg `#1B1B20`, text `#F4F3F0`, border `1px solid rgba(255, 255, 255, 0.10)`, padding `10px 18px`, weight `500`, shadow `inset 0 -1px 0 0 #9D8CFF`.118- **Secondary** — rounded shape, text `#E6E5E3`, border `1px solid rgba(255, 255, 255, 0.10)`, padding `10px 18px`, weight `500`.119- **Outline** — rounded shape, text `#9D8CFF`, border `1px solid rgba(157, 140, 255, 0.35)`, padding `10px 18px`, weight `500`.120- **Ghost** — rounded shape, text `#7A7A82`, padding `10px 6px`, weight `400`.121 122Reach for **primary** as the single dominant CTA per screen.123**Secondary** for the supporting action. **Outline** for tertiary124actions in toolbars. **Ghost** for inline links and table actions.125 126#### Cards127 128- Background: `#131316`129- Border: `1px solid rgba(255, 255, 255, 0.07)`130- Shadow: `0 0 0 1px rgba(255, 255, 255, 0.06)`131- Radius: `radius.lg` (`8px`)132- Internal padding: `20px` for compact cards, `24–28px` for content cards.133 134> This system ships a **glass treatment** — see the Glass token table.135> Apply `backdrop-filter: blur(0px)` to translucent panes.136> The page must have a backdrop (gradient mesh / blurred orbs) for glass to refract.137 138#### Charts139 140- Bar/line variant: `line`141- Highlight strategy: `last` — emphasize a single bar/point per chart.142- Use the declared palette in order: `#9D8CFF`, `#7A7A82`, `#3F3F46`.143 144#### Typography pairings145 146- **Display (`Inter Tight`)** — h1, h2, hero headlines, brand wordmarks.147- **Body (`Inter`)** — paragraphs, labels, button text, form inputs.148- **Mono (`JetBrains Mono`)** — code, eyebrows, metadata, numerals in tables.149 150### 4 · Hard constraints151 152Never do any of the following without explicit instruction from the user:153 154- Introduce a new color, font, radius, or shadow that isn't declared above.155- Mix this system with another (e.g. don't paste in Material or Bootstrap defaults).156- Use generic gradient defaults (purple→blue, peach→pink) — they break the system's voice.157- Reach for emoji icons. Use a consistent icon library and size icons in line with body type.158- Add motion that exceeds the system's restraint — keep transitions short (≤200ms) and subtle.159 160### 5 · Before you finish — verify161 162Run through this checklist for every screen you produce:163 164- [ ] Every color used appears in the Colors table above.165- [ ] Headlines use the display font; body copy uses the body font.166- [ ] Buttons match one of the declared variants exactly (shape, padding, weight).167- [ ] Border-radius values come from `radius.sm` / `radius.md` / `radius.lg` / `radius.pill`.168- [ ] Cards and dividers use the declared border + shadow tokens.169- [ ] No values were invented; if you needed something missing, you stopped and asked.170 171---172 173## Overview174Sable Hairline is a precise dark dev-tool surface. Near-black canvas (#0A0A0B) with a faint 32px hairline grid baked into the background — visible enough to register as engineered, quiet enough never to compete with content. One chromatic accent: a desaturated violet #9D8CFF, used only for active states and as a 1px bottom edge on the primary CTA.175 176For developer platforms, infra dashboards, observability tools, anything that needs to read as engineered without resorting to terminal nostalgia.177 178## The Hairline Grid179The grid is the signature. Two stacked 1px linear-gradients at 32px intervals, both at 2.5% white alpha:180 181```css182body {183 background:184 linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px,185 linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px,186 #0A0A0B;187}188```189 190Hold the alpha at 2.5%. At 4% the grid becomes graph paper; at 1% it disappears. The grid stays fixed during scroll on long pages.191 192## Color193- **Violet #9D8CFF** — the only chromatic mark. Active states, CTA accent line, chart line.194- **Bone #E6E5E3** — body text on near-black.195- **Graphite #7A7A82** — secondary text, axis labels, grid alpha at 7%.196- **Sable #0A0A0B** — page canvas, never pure #000.197- **Panel #131316** — lifted surface for cards.198 199## Typography200- **Display: Inter Tight 600** at 3.75rem with -4% tracking.201- **Body: Inter 400** at 0.9375rem with 1.65 leading.202- **Mono: JetBrains Mono 400** for ghost links and code — slightly smaller (0.8125rem).203 204| Role | Font | Size | Weight | Tracking |205|------|------|------|--------|----------|206| Hero | Inter Tight | 3.75rem | 600 | -0.04em |207| H1 | Inter Tight | 2.25rem | 600 | -0.032em |208| H2 | Inter Tight | 1.375rem | 600 | -0.018em |209| Body | Inter | 0.9375rem | 400 | -0.005em / 1.65 |210| Mono | JetBrains Mono | 0.8125rem | 400 | 0 |211 212## Geometry213- **Radii: 4 / 6 / 8.** Tight, precise — never soft. Pill exists only for status chips.214- **Section gap: 96px** desktop, 56px mobile.215- **12-column grid** with 24px gutters — aligns to the background grid module.216 217## Buttons218- **Primary** — flat panel surface with a 1px violet inset bottom edge. The single chromatic mark.219- **Secondary** — bare hairline panel.220- **Outline** — hairline in violet alpha, violet label.221- **Ghost** — JetBrains Mono in graphite, hover underline.222 223## Cards224Lifted panel #131316, 6px radius, 1px hairline at 7% white. No drop shadow — depth comes from the contrast between #0A0A0B canvas and #131316 panel only. Padding 24px minimum.225 226## Charts & Data2271.5px violet line on a faint hairline grid (already part of the canvas). One end-of-line dot marker in violet. Axis labels in graphite at 0.75rem. No fills, no curves — straight segments.228 229## Do's and Don'ts230- ✅ Hold the grid alpha at exactly 2.5% white.231- ✅ Violet is the only color outside the grayscale ramp.232- ✅ Tight radii throughout — the precision is the brand.233- ✅ Inter Tight for display; never substitute a softer geometric sans.234- ❌ No pure #000. Sable carries warmth.235- ❌ No second chromatic accent. The system stays single-hue.236- ❌ No drop shadows. Hairlines and surface contrast carry depth.237- ❌ No rounded corners above 8px outside the pill chip.238 239---240 241## Tokens242 243> Generated from the same source the live preview renders from.244> Treat the values below as the contract — never substitute approximations.245 246### Colors247 248| Role | Value |249|-----------|-------|250| primary | `#9D8CFF` |251| secondary | `#E6E5E3` |252| tertiary | `#7A7A82` |253| neutral | `#0A0A0B` |254| surface | `#131316` |255 256### Typography257 258- **Display:** Inter Tight259- **Body:** Inter260- **Mono:** JetBrains Mono261 262| Role | size / leading / weight / tracking |263|------|------------------------------------|264| Hero | 3.75rem / 1.04 / 600 / -0.04em |265| H1 | 2.25rem / 1.12 / 600 / -0.032em |266| H2 | 1.375rem / 1.3 / 600 / -0.018em |267| Body | 0.9375rem / 1.65 / 400 / -0.005em |268 269### Radius270 271- sm: `4px`272- md: `6px`273- lg: `8px`274- pill: `9999px`275 276### Shadows277 278- **card:** `0 0 0 1px rgba(255, 255, 255, 0.06)`279- **button:** `0 0 0 1px rgba(157, 140, 255, 0.35)`280 281### Borders282 283- **card:** `1px solid rgba(255, 255, 255, 0.07)`284- **divider:** `rgba(255, 255, 255, 0.07)`285 286### Glass287 288Translucent panes with backdrop-filter — the preview renders cards from these exact values.289 290| Property | Value |291|----------|-------|292| surface | `#131316` |293| blur | `0px` |294| border | `1px solid rgba(255, 255, 255, 0.07)` |295| shadow | `none` |296| backdrop | `linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px, linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px) 0 0 / 32px 32px, #0A0A0B` |297 298### Buttons299 300Four variants, each fully tokenized. The preview renders from these exact values.301 302#### Primary303 304| Property | Value |305|----------|-------|306| shape | `rounded` |307| background | `#1B1B20` |308| color | `#F4F3F0` |309| border | `1px solid rgba(255, 255, 255, 0.10)` |310| padding | `10px 18px` |311| fontWeight | `500` |312| fontSize | `0.875rem` |313| tracking | `-0.005em` |314| shadow | `inset 0 -1px 0 0 #9D8CFF` |315 316#### Secondary317 318| Property | Value |319|----------|-------|320| shape | `rounded` |321| background | `transparent` |322| color | `#E6E5E3` |323| border | `1px solid rgba(255, 255, 255, 0.10)` |324| padding | `10px 18px` |325| fontWeight | `500` |326| fontSize | `0.875rem` |327| tracking | `-0.005em` |328 329#### Outline330 331| Property | Value |332|----------|-------|333| shape | `rounded` |334| background | `transparent` |335| color | `#9D8CFF` |336| border | `1px solid rgba(157, 140, 255, 0.35)` |337| padding | `10px 18px` |338| fontWeight | `500` |339| fontSize | `0.875rem` |340| tracking | `-0.005em` |341 342#### Ghost343 344| Property | Value |345|----------|-------|346| shape | `rounded` |347| background | `transparent` |348| color | `#7A7A82` |349| border | `none` |350| padding | `10px 6px` |351| fontFamily | `mono` |352| fontWeight | `400` |353| fontSize | `0.8125rem` |354| tracking | `0` |355| hoverHint | `underline` |356 357### Charts358 359| Property | Value |360|----------|-------|361| variant | `line` |362| strokeWidth | `1.5` |363| gridlines | `true` |364| highlight | `last` |365| dotMarker | `true` |366| axisColor | `#5A5A62` |367| palette | `#9D8CFF`, `#7A7A82`, `#3F3F46` |368 369---370 371## Pro tokens372 373> Production-fidelity tokens. States, density, motion, elevation,374> content rules and a measured WCAG contract — derived from the375> resting tokens unless explicitly authored.376 377### States378 379#### Button380 381- **hover** — shadow: `0 8px 24px -8px rgba(122, 122, 130, 0.35), inset 0 1px 0 rgba(255,255,255,0.18)`, transform: `translateY(-1px)`, filter: `saturate(1.15)`382- **focus** — outline: `2px solid rgba(122, 122, 130, 0.5)`, outline-offset: `3px`383- **active** — transform: `translateY(0) scale(0.98)`, filter: `brightness(0.96)`384- **disabled** — opacity: `0.4`, filter: `saturate(0.4) blur(0.4px)`385- **loading** — opacity: `0.7`386- **selected** — bg: `rgba(122, 122, 130, 0.18)`, color: `#7A7A82`387 388#### Input389 390- **hover** — border: `1px solid rgba(122, 122, 130, 0.4)`, shadow: `inset 0 1px 0 rgba(255,255,255,0.18)`391- **focus** — border: `1px solid rgba(122, 122, 130, 0.65)`, shadow: `0 0 0 4px rgba(122, 122, 130, 0.15), inset 0 1px 0 rgba(255,255,255,0.18)`392- **disabled** — opacity: `0.4`393- **error** — border: `1px solid rgba(248,113,113,0.7)`, shadow: `0 0 0 4px rgba(248,113,113,0.15)`394 395#### Card396 397- **hover** — shadow: `0 16px 48px -16px rgba(122, 122, 130, 0.25), inset 0 1px 0 rgba(255,255,255,0.18)`, transform: `translateY(-2px)`, filter: `saturate(1.1)`398- **selected** — border: `1px solid rgba(122, 122, 130, 0.5)`399- **dragging** — shadow: `0 24px 64px -16px rgba(0,0,0,0.4)`, transform: `scale(1.02)`, opacity: `0.85`400 401#### Tab402 403- **hover** — bg: `rgba(122, 122, 130, 0.08)`404- **focus** — outline: `2px solid rgba(122, 122, 130, 0.5)`, outline-offset: `2px`405- **selected** — bg: `rgba(122, 122, 130, 0.18)`, color: `#7A7A82`406 407### Density408 409| Mode | padding × | row × | body | radius × | Use for |410|------|-----------|-------|------|----------|---------|411| compact | 0.72 | 0.78 | 0.8125rem | 0.85 | Information-dense — tables, IDEs, dashboards |412| comfortable | 1 | 1 | 0.9375rem | — | Default — most product UI |413| spacious | 1.35 | 1.3 | 1rem | 1.15 | Editorial — marketing, long-form, settings |414 415### Motion416 417**Signature — Refract.** Long opacity- and blur-driven transitions. Not a hard move, but a shift of light across the glass surface.418 419```css420transition: opacity 350ms cubic-bezier(0.32, 0.72, 0, 1), backdrop-filter 350ms cubic-bezier(0.32, 0.72, 0, 1), transform 350ms cubic-bezier(0.32, 0.72, 0, 1);421```422 423| Token | Value |424|-------|-------|425| duration.instant | `100ms` |426| duration.fast | `200ms` |427| duration.base | `350ms` |428| duration.slow | `550ms` |429| easing.standard | `cubic-bezier(0.32, 0.72, 0, 1)` |430| easing.decelerate | `cubic-bezier(0.0, 0, 0.2, 1)` |431| easing.accelerate | `cubic-bezier(0.4, 0, 1, 1)` |432| easing.spring | `cubic-bezier(0.34, 1.2, 0.64, 1)` |433 434### Elevation435 436Five-level scale, system-specific recipe.437 438| Level | Shadow | Recipe |439|-------|--------|--------|440| level0 | `inset 0 1px 0 rgba(255,255,255,0.18)` | Flat glass surface — top-edge gloss only. |441| level1 | `0 2px 8px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255,255,255,0.18)` | Soft lift + top-edge gloss. |442| level2 | `0 12px 32px -8px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255,255,255,0.18)` | Floating pane — popover. |443| level3 | `0 24px 64px -16px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(122, 122, 130, 0.08), inset 0 1px 0 rgba(255,255,255,0.18)` | Sheet — accent rim for depth. |444| level4 | `0 40px 96px -24px rgba(0, 0, 0, 0.5), 0 0 48px -12px rgba(122, 122, 130, 0.25), inset 0 1px 0 rgba(255,255,255,0.18)` | Modal — dramatic glow, scrim required. |445 446### Content447 448- **measure:** `66ch` (max line length for body prose)449- **paragraph spacing:** `1.25em`450- **list indent:** `1.5em`451- **list gap:** `0.5em`452- **link:** color `#7A7A82`, underline `hover`453- **blockquote:** border `1px solid rgba(122, 122, 130, 0.4)`, padding `0.9em 1.2em`454- **code:** background `rgba(122, 122, 130, 0.1)`, color `#7A7A82`455 456### Accessibility (WCAG 2.1)457 458**Overall:** AA-Large459 460| Pair | Ratio | Required | Grade | Suggested fix |461|------|-------|----------|-------|---------------|462| Body text on surface | 6.74:1 | AA | AA | — |463| Body text on canvas | 7.19:1 | AA | AAA | — |464| Muted text on surface | 14.73:1 | AA | AAA | — |465| Accent on surface | 4.36:1 | AA-Large | AA-Large | — |466| Accent on canvas | 4.65:1 | AA-Large | AA | — |467 # CLAUDE.md Reference @DESIGN.md for all styling decisions. Apply tokens strictly — do not introduce colors, fonts, or radii outside the system. When in doubt, prefer the values declared in DESIGN.md frontmatter.<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" />npm install lucide-react// tailwind.config.jsexport default { theme: { extend: { fontFamily: { display: ['"Inter Tight"', 'serif'], sans: ['"Inter"', 'sans-serif'], mono: ['"JetBrains Mono"', 'monospace'], }, colors: { primary: '#9D8CFF', secondary: '#E6E5E3', accent: '#7A7A82', neutral: '#0A0A0B', surface: '#131316', }, borderRadius: { sm: '4px', md: '6px', lg: '8px', }, }, },};A multi-stop pastel gradient runs across the page — desaturated lavender, peach, seafoam, cream — every stop at ~25% chroma so it reads as soft sorbet rather than rainbow. Pure paper-white cards, ink text, hairlines. Calm and considered.
Esports broadcast in dark mode. Near-black surfaces, sharp display serif paired with a square mono, knife-edge corners, a single high-voltage lime accent. Built for tournaments and launch events.