Typography¶
"Sharp, clear, invisible. The best typography is the one you don't notice — you just read."
Font Choice: Inter¶
Inter is the typeface for the entire site — headings, body, UI, everything.
Why Inter?¶
- Linear, Stripe, and Notion all use Inter — our three design references
- Already loaded on the site (zero migration cost)
- Excellent weight range: 400–800
- Optimised for screens at all sizes (12px badges to 40px headlines)
- Variable font support for precise weight control
- Massive language support
Font Stack¶
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
What About Other Candidates?¶
| Font | Verdict | Reason |
|---|---|---|
| Geist (Vercel) | ❌ Rejected | Slightly too tight at small sizes. Limited weight range. |
| Plus Jakarta Sans | ❌ Rejected | Too rounded/friendly — doesn't match the sharp, professional feel. |
| General Sans | ❌ Rejected | Good but adds a new dependency for marginal benefit over Inter. |
Type Scale¶
Based on Linear's type system. Every text element on the site uses one of these sizes.
| Token | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
--text-display |
2.5rem (40px) | 600 | 1.2 | -0.025em | Hero headlines only |
--text-h1 |
2rem (32px) | 600 | 1.25 | -0.02em | Page titles |
--text-h2 |
1.5rem (24px) | 600 | 1.3 | -0.01em | Section headings |
--text-h3 |
1.25rem (20px) | 600 | 1.4 | 0 | Sub-sections, card titles |
--text-body |
1rem (16px) | 400 | 1.7 | 0 | Reading text, descriptions |
--text-sm |
0.875rem (14px) | 400 | 1.6 | 0 | UI text, meta, compact areas |
--text-caption |
0.75rem (12px) | 500 | 1.5 | 0.01em | Badges, labels, timestamps |
Rules¶
- No arbitrary font sizes. Every
font-sizemust reference a token. No0.82rem, no0.92rem, no1.1rem. - Headings are always weight 600. Not 700, not 800. Clean and sharp, not heavy.
- Body text line-height is 1.7. This gives optimal reading comfort (Stripe uses 1.625, we round up for extra breathing room).
- Negative letter-spacing on headings only. Headlines look tighter and more premium with
-0.02em. Body text stays at 0. - No text-transform: uppercase except for
--text-captionlabels. ALL CAPS IS SHOUTING. Zen doesn't shout.
Reading Optimisation¶
For long-form content (blog posts, study guides):
.reading-content {
font-size: var(--text-body); /* 16px */
line-height: 1.7;
max-width: var(--max-reading); /* 720px */
color: var(--text-secondary); /* Not primary — softer on the eyes */
}
.reading-content h1,
.reading-content h2,
.reading-content h3 {
color: var(--text-primary); /* Headings stand out */
margin-top: 2em;
margin-bottom: 0.5em;
}
Code Typography¶
CSS Implementation¶
:root {
/* Font families */
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
/* Type scale */
--text-display: 2.5rem;
--text-h1: 2rem;
--text-h2: 1.5rem;
--text-h3: 1.25rem;
--text-body: 1rem;
--text-sm: 0.875rem;
--text-caption: 0.75rem;
}
body {
font-family: var(--font-sans);
font-size: var(--text-body);
line-height: 1.7;
color: var(--text-secondary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 {
font-weight: 600;
color: var(--text-primary);
}
h1 { font-size: var(--text-h1); line-height: 1.25; letter-spacing: -0.02em; }
h2 { font-size: var(--text-h2); line-height: 1.3; letter-spacing: -0.01em; }
h3 { font-size: var(--text-h3); line-height: 1.4; }