Foundation · Type
3 families · 1 scale
Sans for interface, serif for reading, mono for data. Hierarchy comes from size, tracking, and the typeface, never weight or color.
Most design systems shout with bold headings and colored type. This one whispers: a regular-weight headline with tight tracking reads as confident and editorial — the same editorial restraint the rest of the system is built on. The accent color belongs on surfaces and states, not on the letters themselves. Long-form copy uses reading utilities — not the same lane as UI chrome.
Editorial restraint
Size carries hierarchy. Weight stays quiet.
Size first
Step down the scale from display to caption. A smaller size in foreground reads louder than a larger size in muted-foreground.
Tracking second
Headings pull tight (-0.02em from foundation). Eyebrows push wide (0.2em uppercase mono). The contrast creates rhythm without bold.
Family third
Switching from sans to mono or serif is a semantic signal: interface, data, or reading voice. Never mix serif into buttons.
The scale, a waterfall
Display · 96
Marketing heroes, styleguide mastheads
Title · 60
Landing page titles
Heading · 36
Page titles, section heroes
Subhead · 24
Section headings, card titles
Body L · 18
Lead paragraphs, docs intros
Body · 16
Default UI copy, form labels
Small · 14
Secondary labels, table cells
Caption · 12
Eyebrows, metadata, badges
Interface
Geist · --font-sans
font-sans · the workhorse
Headings, labels, buttons, and body copy. Calm and neutral so content stays loudest.
- Page and section headings
- Button and label text
- Form fields and descriptions
- Navigation and toolbars
0123 data
Geist Mono · --font-geist-mono
font-mono · tabular
Metrics, timestamps, counts, IDs, and code. Exact and aligned, engineered crispness.
- Stats, prices, and counts
- Timestamps and durations
- Keyboard hints and kbd
- API paths, IDs, and code snippets
Editorial
EB Garamond · --font-serif
font-serif · reading voice
Long-form prose and pull quotes. Warmth and authority on reading surfaces, not UI chrome.
- Docs philosophy and manifesto copy
- Pull quotes and blockquotes
- Article body in marketing layouts
- Drop caps and editorial spreads
Where each family lands
A role for every surface.
font-sanstext-4xlfont-normalfont-sanstext-2xlfont-normalfont-headingtext-basefont-mediumfont-sanstext-smfont-normalreading-ui16px / 1.6 lhfont-normalfont-monotext-3xlfont-normalfont-monotext-xsfont-normalfont-monotext-xsfont-normalreading-prose18px / 1.7 lhfont-normalfont-heading resolves to the same stack as font-sans. Card, dialog, and sheet titles use it at font-medium, the one place medium weight is expected in UI chrome.
Tracking & leading
Rhythm is baked into foundation.
You rarely need to set letter-spacing by hand. The foundation tokens apply body tracking and heading tightness globally. Reach for utility classes only when you are designing a signature moment.
Body default
-0.006emSet on body in foundation. Slightly tight for crisp UI copy.
Headings h1–h4
-0.02emApplied globally. Pair with font-normal, not bold.
Eyebrows / labels
0.2em uppercaseMono captions use wide tracking + uppercase for scanability.
Display clamp
tracking-tighterLarge marketing type pulls in further for editorial density.
Heading rhythm
Regular weight, tight tracking
letter-spacing: -0.02em · line-height: 1.15
Body rhythm
Generous leading for long UI copy. The eye returns without effort.
letter-spacing: -0.006em · line-height: 1.6
How it reads
Good typography is invisible. You do not notice the letters, you notice that you have finished reading, calm and unhurried, and understood every word.
The measure is short, the leading generous, so the eye returns without effort. Nothing flickers, nothing shouts. Hierarchy is built from size and rhythm, leaving the prose free to carry the argument.
Set this way a changelog becomes a story and documentation becomes a guide. The type gets out of the way and the words do the rest.
“Restraint is the loudest thing a design system can say.”
Mono for facts
Always pair mono numbers with tabular-nums so columns align when values change.
99.98%
uptime
1,284
req / min
42ms
p50
⌘K
search
Weight = emphasis
Headlines stay regular. Medium is for compact UI titles. Bold on headings is flagged by the on-system lint.
Aa
Regular
400
Display, page headings, body
Aa
Medium
500
Card titles, dialog headers
Aa
Semibold
600
Rare inline emphasis only
Aa
Bold
700
Avoid on headings (lint flags it)
In practice
The same instinct, every time.
text-4xl font-normal tracking-tighttext-4xl font-bold text-brandreading-prose on essay / article bodyfull-bleed text-sm sans for long-formreading-ui on docs and help contenttext-sm tracking-tight on paragraphs users readfont-mono tabular-nums text-smfont-sans text-green-600 font-semiboldfont-serif text-lg leading-relaxedfont-serif text-base on a buttontext-xs uppercase tracking-[0.2em]text-xs font-bold tracking-normalSwap the stacks
Your fonts, same tokens.
The default stacks are Geist, Geist Mono, and EB Garamond loaded via Next.js font optimization. Point the CSS variables at your own faces and every font-* utility follows. Tracking and scale stay the same.
Quick reference