All documents

Typography

Three families, no more. Self-hosted as woff2 in public/fonts/ — never a runtime call to Google to paint our own identity. Declared in styles/ds/typography.css; the @font-face blocks live at the top of styles/globals.css.

FamilyVariableJob
DM Sans
--font-display
Display. H1s, big numerals, marquee callouts
Inter
--font-body
Workhorse. Body, UI, buttons, nav, captions
JetBrains Mono
--font-mono
Data. Figures, codes, labels, anything that should read as system output

Rules from the guide, and they are hard: never more than three weights on one screen, never more than two families in one paragraph, never the display font for body copy.

The seven tiers

These are Tailwind sizes minted in @theme — use the tier, not a pixel value.

ClassSize / line-heightUsed for
text-display
26px / 1.25
The page <h1>, DM Sans 800, tracking-tight
text-section
17px / 1.3
A panel or section title, 600
text-body
15px / 1.6
Body copy, descriptions, prose
text-caption
13px / 1.45
Dense UI text, menu items, tile sublabels
text-data
14px / 1.3
Figures in mono, tabular-nums
text-eyebrow
11px
Mono-caps labels (use .mono-caps, below)
text-stat
56px / 1.0
The stat-tile numeral, DM Sans 800

A new tier must be registered in TYPE_TIERS in lib/utils.ts on the same commit — see 11-traps.md. This is not optional; skipping it deletes type sizes at random.

Marketing surfaces get the guide's larger ramp (hero 56–72px, H2 36–44px, H3 24–28px, body 16–18px). Product surfaces use the tiers above — a dashboard with a 64px h1 is a landing page with a table in it.

.mono-caps — the system's label voice

font-family: var(--font-mono);
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;

This is how a section, a column, a role, a state, or a scope is labelled — in the rail, on a stat tile, in a badge, in a table cell. A section is marked with type, never with a coloured rule or a filled header band.

Use Eyebrow from components/brand/devices.tsx when it is a standalone label; the raw .mono-caps class when it is inline in a cell or a badge.

Figures

Anything a reader compares vertically is mono and tabular: font-mono tabular-nums. The table's align="number" column does this for you and right-aligns it. A figure that shifts by a pixel as it updates is a figure that cannot be scanned.

Accent in headlines

One to three words maximum, and only when those words are the subject (--accent-ink, never --brand-accent as text). Never more than 30% of a headline.

Copy voice

Short, English, and it reads like a tool, not documentation. Caveats belong in a docs page or a provenance record, not in the chrome. No em-dashes or en-dashes in product or marketing copy — commas, periods, or "to" for ranges (guide section 17).