Typography
Font families, type scale, headings H1–H6, body, overline, caption, and code — all drawn from token.css.
Font Families
Ten font family tokens, each with a purposeful role. Swap a value in
token.css and the change cascades across every component that uses it.
Headings H1 – H6
All heading sizes use clamp() for fluid scaling between a minimum (mobile)
and maximum (desktop) value. H1–H3 use --font-display;
H4–H6 switch to --font-sans for better legibility at smaller sizes.
--text-h1
36 → 61px
The quick brown fox
--text-h2
30 → 49px
The quick brown fox
--text-h3
24 → 39px
The quick brown fox
--text-h4
20 → 31px
The quick brown fox
--text-h5
18 → 25px
The quick brown fox jumps over the lazy dog
--text-h6
16 → 20px
The quick brown fox jumps over the lazy dog
Body Text Scale
Five body sizes with fixed rem values. The default --text-body (1rem / 16px)
is the baseline for all prose. Sizes below it are for UI chrome only — never use
--text-body-xs for longform content.
--text-body-xl
20px
Intro paragraph or hero subtitle — used sparingly to draw the reader in.
--text-body-lg
18px
Lead paragraph or article introduction — a step above default body.
--text-body
16px — default
Standard body copy for paragraphs, list items, and general content. Line height is 1.75 for comfortable longform reading.
--text-body-sm
14px
Secondary copy, helper text, form hints, timestamps.
--text-body-xs
13px
Compact UI labels, sidebar navigation, dense data tables.
Utility Text — Overline, Caption, Micro
Small-scale text roles for labels, metadata, and tags. Overline always pairs wide letter-spacing with uppercase.
--text-caption
12px
--text-overline
11px · uppercase · wide
--text-xs
10px
Code & Mono
Inline code uses --text-code (14px) with a subtle background chip.
Block code in <pre> inherits the same size with
--leading-code (1.65) for scannability.
Inline code
Use x-data="{ open: false }" to initialise an Alpine component,
then bind x-show="open" on the element you want to toggle.
The Esc key should always close overlays.
Block pre
/* token.css */
--font-mono: "JetBrains Mono", Menlo, monospace;
--text-code: 0.875rem; /* 14px */
--leading-code: 1.65;
--tracking-code: -0.01em;
Blockquote
Good typography is invisible. It gets out of the way and lets the content speak. — Robert Bringhurst
Font Weight Scale
Six weight tokens. Use semantic names — never raw numbers — so swapping the underlying font family doesn't require a hunt-and-replace across components.
--weight-display
400 · Regular
Display font headings (reads elegant at 400)
--weight-body
400 · Regular
Body copy, paragraph text
--weight-body-medium
500 · Medium
Labels, nav items, table headers
--weight-heading-sans
600 · Semibold
H4–H6, section titles, card names
--weight-bold
700 · Bold
Emphasis within body text, strong element
--weight-mono
400 · Regular
Inline code, pre blocks
--weight-mono-bold
600 · Semibold
Highlighted keywords, kbd element
Line Height
Leading decreases as font size increases — large display type needs tighter line spacing than a body paragraph does.
| Token | Value | Role | Preview |
|---|---|---|---|
--leading-h1 |
1.1 | H1 display | Display heading second line |
--leading-h2 |
1.15 | H2 | Section heading second line |
--leading-h3 |
1.2 | H3 | Sub-heading second line |
--leading-h4 |
1.3 | H4 | Card title second line |
--leading-body |
1.75 | Body prose | Comfortable reading for long paragraphs |
--leading-ui |
1.4 | Labels, buttons | Compact UI text second line |
--leading-code |
1.65 | Code blocks | const x = 1; const y = 2; |
Letter Spacing
Negative tracking tightens large display type; positive tracking opens up small uppercase labels for legibility.
--tracking-display
−0.03em
H1 — tight for large display
--tracking-h2
−0.025em
H2 headings
--tracking-h3
−0.02em
H3 headings
--tracking-body
0
Default body — no adjustment
--tracking-overline
+0.1em
Overlines, uppercase labels
--tracking-code
−0.01em
Code — subtle tightening
Token Quick Reference
Click any token to copy it to your clipboard.
| Token | Value | Category |
|---|---|---|
--font-display |
"Inter", system-ui, sans-serif | Family |
--font-sans |
"DM Sans", system-ui, sans-serif | Family |
--font-body |
"Inter", system-ui, sans-serif | Family |
--font-serif |
"DM Serif Display", Georgia, serif | Family |
--font-mono |
"JetBrains Mono", Menlo, monospace | Family |
--font-brand |
"Space Grotesk", sans-serif | Family |
--font-accent |
"Pacifico", cursive | Family |
--font-decorative |
"Playfair Display", serif | Family |
--font-script |
"Great Vibes", cursive | Family |
--font-emoji |
"Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji" | Family |
--text-h1 |
clamp(2.25rem, 5vw, 3.815rem) | Size |
--text-h2 |
clamp(1.875rem, 4vw, 3.052rem) | Size |
--text-h3 |
clamp(1.5rem, 3vw, 2.441rem) | Size |
--text-h4 |
clamp(1.25rem, 2.5vw, 1.953rem) | Size |
--text-h5 |
clamp(1.125rem, 2vw, 1.563rem) | Size |
--text-h6 |
clamp(1rem, 1.5vw, 1.25rem) | Size |
--text-body-xl |
1.25rem | Size |
--text-body-lg |
1.125rem | Size |
--text-body |
1rem | Size |
--text-body-sm |
0.875rem | Size |
--text-body-xs |
0.8125rem | Size |
--text-blockquote |
clamp(1.25rem, 2vw, 1.5rem) | Size |
--text-caption |
0.75rem | Size |
--text-overline |
0.6875rem | Size |
--text-xs |
0.625rem | Size |
--text-code |
0.875rem | Size |
--text-code-sm |
0.8125rem | Size |
--leading-h1 |
1.1 | Leading |
--leading-h2 |
1.15 | Leading |
--leading-h3 |
1.2 | Leading |
--leading-h4 |
1.3 | Leading |
--leading-h5 |
1.35 | Leading |
--leading-h6 |
1.4 | Leading |
--leading-body |
1.75 | Leading |
--leading-ui |
1.4 | Leading |
--leading-code |
1.65 | Leading |
--tracking-display |
-0.03em | Tracking |
--tracking-h2 |
-0.025em | Tracking |
--tracking-h3 |
-0.02em | Tracking |
--tracking-body |
0 | Tracking |
--tracking-overline |
0.1em | Tracking |
--tracking-code |
-0.01em | Tracking |
--weight-display |
400 | Weight |
--weight-heading-sans |
600 | Weight |
--weight-body |
400 | Weight |
--weight-body-medium |
500 | Weight |
--weight-bold |
700 | Weight |
--weight-mono |
400 | Weight |
--weight-mono-bold |
600 | Weight |