Editorial scale, mechanical labels.
Three typefaces, one editorial scale. Display type names the read. Mono type carries proof. Sans does the work between them.
Three families. Defined roles.
Geist Sans and Mono come from the geist npm package and load in app/layout.tsx. The serif is the system serif fallback — we have not paid for a custom face because the system pairing already feels right at editorial weight.
abcdefghijklmnopqrstuvwxyz
0123456789 & ! ? — / · @ #
geist npm package (loaded in app/layout.tsx)
var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif
Body copy, descriptions, evidence prose, navigation, controls.
abcdefghijklmnopqrstuvwxyz
0123456789 & ! ? — / · @ #
geist npm package (loaded in app/layout.tsx)
var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace
Counters, indexes, dates, file paths, eyebrows, compact metadata.
abcdefghijklmnopqrstuvwxyz
0123456789 & ! ? — / · @ #
OS default (Georgia on macOS, Cambria on Windows)
ui-serif, Georgia, Cambria, "Times New Roman", Times, serif
Display titles, headlines, section heads, editorial reads.
Every step, every value.
Sizes are pixel-anchored, not t-shirt sizes. The right column shows the live metrics; the specimen renders at the actual size so values can be confirmed in devtools. The token column maps each step to its Tailwind utility (e.g. text-display, text-h1, text-body, text-mechanical).
- Family
- serif
- Size
- 58/92px
- Weight
- 600
- Line
- 0.88
- Tracking
- -0.03em
- Token
- text-display
Route titles, decisive editorial reads. One per page.
- Family
- serif
- Size
- 54/76px
- Weight
- 600
- Line
- 0.9
- Tracking
- -0.025em
- Token
- text-h1
Page titles inside reference frames.
- Family
- serif
- Size
- 40/56px
- Weight
- 600
- Line
- 0.95
- Tracking
- -0.015em
- Token
- text-h2
Section heads inside reference pages.
- Family
- serif
- Size
- 34/38px
- Weight
- 600
- Line
- 0.95
- Tracking
- -0.01em
- Token
- text-h3
Specimen names, panel titles, pattern names.
- Family
- serif
- Size
- 28px
- Weight
- 600
- Line
- 1
- Tracking
- -0.005em
- Token
- text-h4
Component names in inventories, sub-section heads.
- Family
- sans
- Size
- 18px
- Weight
- 600
- Line
- 1.25
- Tracking
- 0
- Token
- text-h5
Card titles, dense module headers.
- Family
- sans
- Size
- 14px
- Weight
- 600
- Line
- 1.3
- Tracking
- 0.01em
- Token
- text-h6
Inline group labels, small panel heads.
- Family
- sans
- Size
- 18px
- Weight
- 400
- Line
- 1.6
- Tracking
- 0
- Token
- text-body-lg
Lead paragraphs, page kickers when the read needs weight.
- Family
- sans
- Size
- 14px
- Weight
- 400
- Line
- 1.65
- Tracking
- 0
- Token
- text-body
Default paragraph text, descriptions, evidence prose.
- Family
- sans
- Size
- 12px
- Weight
- 400
- Line
- 1.55
- Tracking
- 0
- Token
- text-body-sm
Helper copy, captions under specimens, secondary metadata.
- Family
- sans
- Size
- 11px
- Weight
- 500
- Line
- 1.45
- Tracking
- 0.01em
- Token
- text-caption
Compact labels, footnotes, mobile section titles.
- Family
- sans
- Size
- 10px
- Weight
- 600
- Line
- 1.4
- Tracking
- 0.18em
- Token
- text-eyebrow
Uppercase context labels above section heads. .eyebrow class.
- Family
- mono
- Size
- 11px
- Weight
- 500
- Line
- 1.4
- Tracking
- 0.14em
- Token
- text-mechanical
Counters, indexes, dates, file paths, system labels.
Serif for meaning. Mono for proof.
Use display type to name the real read of a page. Use sans for everything between. Use mono for counters, indexes, paths, dates, and anything that is metadata about a claim. Never use mono to decorate.
Display, H1–H4. Editorial, ranged-loose, used at most once or twice per route.
H5, H6, all body. Default for reading and controls. If unsure, use sans.
Eyebrows, counters, file paths, timestamps. Carries the system's voice of evidence.