Foundations
The tokens, measurements, and laws from which every component and pattern is derived. Nothing in later volumes may contradict this volume. If a problem isn't answered here, resolve it in the spirit of the principles, document it, and propose it for the next revision — never improvise silently.
Principles
Four laws. Every rule in this book serves one of them. When the book is silent, decide in their favour.
Nothing approximate.
Engineered geometry, tokenised values, exact alignment. If a measurement isn't on the scale, it's wrong. Precision earns trust before a word is read.
Calm under load.
Feel like something that stays up when things go down. Solid surfaces, steady rhythm, no visual panic — even at P1 severity.
State, shown plainly.
Legibility over decoration. Surface truth — green when healthy, red when not — never obscured by ornament or ambiguity.
Always watching.
The pulse is the soul. Motion and signal show the estate is observed in real time. Used with restraint, it makes the product feel awake.
Rule grammar
Rules are graded. Keywords are absolute, read as in RFC 2119.
Token names (--p500, --s4) are normative. Reference tokens, never raw values.
Color
Obsidian dark, one signal green. Green is the pulse — used sparingly so it always carries meaning. Click any swatch to copy.
1.1.1 Core ramps
Obsidian — surfaces
Pulse — the accent
Neutrals — text & light mode
1.1.2 Elevation by tint
Dark UIs express depth with surface tint and a hairline border, not heavy shadow. Each step up the surface ramp is one level of elevation.
--hair border. Tint alone reads flat on low-contrast displays.1.1.3 Semantic & data
| Token | Hex | Meaning | Use |
|---|---|---|---|
| --p500 | #22C55E | Success / healthy / live | Operational state, primary action, the pulse |
| --info | #38BDF8 | Informational | Neutral notices, links, in-progress |
| --warn | #F59E0B | Caution / degraded | Degraded nodes, soft warnings |
| --danger | #F43F5E | Error / offline / destructive | Failures, destructive actions |
| --violet | #8B5CF6 | Data series 4 | Charts only — never UI chrome |
Data-viz series order: --p500, --info, --warn, --violet, then tints. Status colours keep their meaning in charts — green is always "good."
1.1.4 Contrast
| Pairing | Ratio | Verdict |
|---|---|---|
| Snow on Obsidian-950 | ≈ 16:1 | AAA · body |
| Mist on Obsidian-950 | ≈ 9:1 | AAA · secondary |
| Slate on Obsidian-950 | ≈ 4.8:1 | AA · labels only |
| Pulse-500 on Obsidian-950 | ≈ 6.6:1 | AA · large / graphical |
Typography
Three families, three jobs, no overlap.
Wordmark & ≥24px headings only
All readable copy & UI
Data, code, labels, metadata
1.2.1 Type scale
| Token | Family | Size / line | Weight · tracking | Use |
|---|---|---|---|---|
| display-l | Display | 48 / 52 | 800 · +0.01em | Page hero |
| display-m | Display | 36 / 40 | 700 · +0.02em | Section hero |
| h1 | Sans | 30 / 36 | 700 | Page title |
| h2 | Sans | 24 / 30 | 600 | Subsection |
| h3 | Sans | 20 / 28 | 600 | Block heading |
| body-l | Sans | 18 / 28 | 400 | Lead paragraph |
| body | Sans | 16 / 26 | 400 | Default text |
| body-s | Sans | 14 / 22 | 400 | Secondary |
| caption | Sans | 13 / 18 | 400 | Captions, help |
| label | Mono | 11 / 16 | 500 · +0.16em · UPPER | Eyebrows, tags |
| code | Mono | 13 / 20 | 400 | Code, data values |
1.2.2 Numerics & truncation
Spacing & layout
Everything is a multiple of 4px. One base unit is what makes unrelated screens feel like one product.
1.3.1 The scale
13px, 15px, 30px do not exist.1.3.2 Inset · stack · inline
Padding inside a container. Cards --s6. Compact controls --s3×--s4.
Vertical gap. Default --s4; related --s2; unrelated blocks --s8+.
Horizontal gap. Icon-label --s2; button group --s3; toolbar sections --s6.
1.3.3 Density
Comfortable is default. Compact (tables, inventory, dashboards) steps each inset/stack token down one.
Grid & breakpoints
A 12-column fluid grid inside a fixed content well, with a persistent navigation rail.
| Columns | 12 | Subdivide 2 / 3 / 4 / 6 |
| Gutter | --s4 → --s6 | Compact → comfortable |
| Content max | 1080px | Reading & app well |
| Page margin | --s6 → --s11 | Scales with viewport |
| Nav rail | 288px fixed | Persistent ≥ lg; off-canvas below |
1.4.1 Breakpoints
| Token | Min | Behaviour |
|---|---|---|
| sm | 480px | Single column, stacked controls |
| md | 768px | Two-column grids permitted |
| lg | 1024px | Nav rail persistent; full grid |
| xl | 1280px | Comfortable gutters & margins |
| xxl | 1536px | Well centred, margins grow |
lg, the nav rail collapses to an off-canvas drawer. The content well never sits under a fixed rail it can't clear.Elevation & shape
Depth is layered and ordered; corners follow one radius scale.
1.5.1 Z-layers
| z-base | 0 | Page content |
| z-raised | 10 | Cards, hovered rows |
| z-sticky | 30 | Sticky headers, toolbars |
| z-rail | 40 | Navigation rail / drawer |
| z-modal | 50 | Dialogs & scrim |
| z-toast | 90 | Toasts, transient alerts |
1.5.2 Shadow tokens
| shadow-sm | 0 1px 2px rgba(0,0,0,.4) | Hover lift |
| shadow-md | 0 6px 16px rgba(0,0,0,.45) | Popovers, menus |
| shadow-lg | 0 18px 40px rgba(0,0,0,.5) | Modals only |
1.5.3 Corner radius
| --r-xs (4) | Inputs in cards, chips, code blocks |
| --r-md (9) | Buttons, inputs — default |
| --r-lg (14) | Cards, panels, modals |
| --r-xl (20) | Hero surfaces, app-icon tiles |
| pill / full | Status pills, avatars, the live dot |
Iconography
Icons are a system, not a pile of drawings. They share one grid, one stroke, and a strict convention for when green appears — so the set reads as a single hand and every glyph is distinguishable from its neighbours.
1.6.1 The convention
--ink. Domain icons (node, deploy, audit — things with meaning) carry exactly one green --accent element, placed on the part that is the live / active / verified thing.1.6.2 Construction grid & keylines
Every icon is drawn on a 24px grid with 1px padding (drawable area 22px). Forms snap to the keyline shapes so square, round and tall icons feel optically equal in weight.
Square 20×20 — blocky forms (host, container).
Circle 22Ø — round forms run slightly larger to match weight (node, observe).
Rectangle wide forms (terminal, database).
1.6.3 Stroke spec
| Stroke weight | 2px @ 24px (scales proportionally) |
| Caps & joins | Round |
| Interior corners | 2px radius |
| Structure / signal | --ink · one --p500 element |
| Fill | None — outline (default variant) |
1.6.4 Chrome set · monochrome
1.6.5 Domain set · two-tone
1.6.6 Deliberate metaphors
Where there is a convention, we use it. Where the obvious glyph would collide with a neighbour or mislead, we modify it or design a new one. The reasoning is part of the system.
1.6.7 Variants
Each glyph ships as outline (default) and, where it appears in navigation, solid (filled silhouette) for the active/selected state. The green signal element is retained in both.
Optical sizing
1.6.8 Rules
Motion
Motion is purposeful, quick, and eased — it communicates state and causality, never decoration. The heartbeat is the one signature animation and the only thing permitted to loop indefinitely.
1.7.1 Principles
Purposeful
Every animation answers "what changed and why." If it explains nothing, remove it.
Quick
UI transitions land in 120–240ms. Slow motion feels broken, not premium.
Eased
Decelerate into rest. Linear is reserved for the continuous pulse loop only.
Restrained
One focal motion per view. Many small animations compete and cheapen.
1.7.2 Duration tokens
| Token | Value | Use |
|---|---|---|
| d-instant | 0ms | Direct manipulation (drag) |
| d-fast | 120ms | Taps, toggles, hover colour |
| d-quick | 180ms | Buttons, small reveals |
| d-base | 240ms | Panels, cards, menus |
| d-slow | 360ms | Modals, page transitions |
| d-pulse | 2800ms loop | Live indicators & the mark |
1.7.3 Easing tokens
1.7.4 Per-component motion
| Element | Trigger | Property | Duration · easing |
|---|---|---|---|
| Button | Hover / press | bg, transform 1px | fast · standard |
| Card / row | Hover | border, translateY 2px | quick · standard |
| Menu / popover | Open | opacity + 4px rise | base · decelerate |
| Modal | Open | opacity + scale .98→1 | slow · emphasized |
| Toast | Enter / exit | opacity + 20px slide | base · standard |
| Page | Route change | opacity + 14px rise (stagger) | base · decelerate |
1.7.5 Choreography
When several elements enter together, stagger them 40–60ms in reading order. One orchestrated entrance beats scattered independent animations.
1.7.6 The signature pulse
The heartbeat traces the pulse path over 2800ms on a continuous loop with --e-standard. It is visual proof that the estate is being watched.
1.7.7 Accessibility
prefers-reduced-motion. When set, disable loops and large transforms; keep opacity only. The pulse becomes a static green dot — state stays legible without motion.Next: Components
Foundations are locked. Volume II — Components → builds every element on these tokens and laws.