Typography
Three font families with strict roles — display, body, and mono
Display / Besley
Besley
XL Title 2
The quick brown
42px Bold
XL Title
The quick brown fox
36px Bold
Large Title
The quick brown fox
34px Bold
Title 1
The quick brown fox jumps
28px Bold
Title 2
The quick brown fox jumps over
22px Semi
Title 3
The quick brown fox jumps over the lazy dog
20px Semi
Headline
The quick brown fox jumps over the lazy dog nearby
17px Semi
| Token | All Size | Weight | Web line-height | Notes |
|---|---|---|---|---|
| xlTitle2 | 42 | 700 | 1.15 | iOS 17+ only (extraLargeTitle2) |
| xlTitle | 36 | 700 | 1.15 | iOS 17+ only (extraLargeTitle) |
| largeTitle | 34 | 700 | 1.18 | Web: use for hero/page headers. Consider clamp(28px, 4vw, 34px) for fluid sizing |
| title1 | 28 | 700 | 1.21 | |
| title2 | 22 | 600 | 1.27 | |
| title3 | 20 | 600 | 1.3 | |
| headline | 17 | 600 | 1.35 |
When to use
- XL Title 2/Hero moments, splash screens, marketing surfaces
- XL Title/Feature headers, onboarding screens, prominent section openers
- Large Title/Top-level navigation titles. iOS Maps to UINavigationBar large title. Android Maps to TopAppBar large title in Material3. Web Use fluid sizing with
clamp()for responsive - Title 1–3/Section headers, card titles, detail screen headers
- Headline/Emphasized inline text, list item titles with serif character
- Display sizes/Same px values on all platforms. Display sizes are large enough that 1pt/1px difference is negligible.
Platform notes
- iOS Uses Bespoke Serif (bundled) as the native equivalent. Registered via CTFontManagerRegisterFontsForURL. Maps to UIFont.bespokeSerif(ofSize:weight:).
- Android Bundle Besley in
res/font/. In Compose useFontFamily(Font(R.font.besley_bold)). Do not use Google Fonts runtime download — bundle for offline consistency. - Android Use
sp(scale-independent pixels) for all display sizes. Values map 1:1 from the type scale tokens. Respect user font size accessibility settings. - Web Besley loaded via Google Fonts (variable, 400–900). For hero/page headers consider
clamp(28px, 4vw, 34px)for fluid sizing on responsive layouts. - All Display sizes (42–17px) use identical values on all platforms. At these sizes, the 1pt/1px difference is negligible.
Body / Figtree
Figtree
Body
The quick brown fox jumps over the lazy dog. Typography is the craft of endowing human language with a durable visual form.
18px Regular
Body Semi
The quick brown fox jumps over the lazy dog. Emphasis within running text.
18px Semi
Callout
The quick brown fox jumps over the lazy dog. Secondary body text for supporting paragraphs.
17px Regular
Subheadline
The quick brown fox jumps over the lazy dog. Subtitles and descriptions below headings.
16px Regular
Footnote
The quick brown fox jumps over the lazy dog. Timestamps, attributions, and fine print that supports without competing.
14px Regular
Caption 1
The quick brown fox jumps over the lazy dog. Image captions, table annotations, small metadata.
13px Regular
Caption 2
The quick brown fox jumps over the lazy dog. The smallest readable text — legal disclaimers, version numbers.
12px Regular
| Token | iOS Size | Android Size | Web Size | Weight | Web line-height | Web letter-spacing |
|---|---|---|---|---|---|---|
| body | 17pt | 18sp | 18px | 400 | 1.6 | normal |
| bodySemi | 17pt | 18sp | 18px | 600 | 1.6 | normal |
| callout | 16pt | 17sp | 17px | 400 | 1.5 | normal |
| subheadline | 15pt | 16sp | 16px | 400 | 1.5 | +0.01em |
| footnote | 13pt | 14sp | 14px | 400 | 1.45 | +0.01em |
| caption1 | 12pt | 13sp | 13px | 400 | 1.4 | +0.01em |
| caption2 | 11pt | 12sp | 12px | 400 | 1.35 | +0.02em |
When to use
- Body/Primary UI text, form fields, list items, chat messages
- Callout/Secondary content blocks, card descriptions, tooltips
- Subheadline/Subtitles below headings, list item descriptions
- Footnote/Timestamps, attributions, supplementary info
- Caption 1–2/Image captions, legal text, version numbers, tab bar labels
Platform notes
- Web Body text is 18px (vs 17pt iOS). Web rendering at 1x displays lacks Retina sharpness — the extra pixel improves readability.
- Web Caption2 is 12px minimum (vs 11pt iOS). Below 12px text becomes illegible on non-Retina screens. Accessibility guideline.
- Web Small sizes (footnote, caption) get +0.01em letter-spacing. Figtree's tracking at small sizes benefits from — slight loosening helps on screen.
- Web Always set explicit
line-height. iOS derives it from font metrics automatically; browsers use a default ~1.2 which is too tight for body text. - iOS Uses
UIFont.satoshi(ofSize:weight:)with variable font wght axis. Registration viaCTFontManagerRegisterFontsForURL. - Android Bundle Figtree in
res/font/. In Compose useFontFamily(Font(R.font.figtree_variable)). Do not use Google Fonts runtime download — bundle for offline consistency. - Android Use
spfor font sizes — values map 1:1 from the type scale tokens. Use Web column sizes (18sp body, 12sp caption2 minimum) rather than iOS pt values. - Android Line height in Compose: specify as
(fontSize * lineHeightMultiplier).spusing the Web line-height column values. In XML useandroid:lineSpacingMultiplier. - Android Letter spacing in Compose is in
emunits (same as Web). In XML useandroid:letterSpacing(also in em). Use the Web letter-spacing column values. - Web Load via Google Fonts or self-host .woff2. Variable font: single
@font-facewithfont-weight: 300 700.
Mono / IBM Plex
IBM Plex Mono
Code
let configuration = URLSessionConfiguration.default
14 / 21 Regular
Label
Section Label · 2 items · Updated 3m ago
11 / 15 Semi uc
Data
1,247 messages · 98.6% uptime · 340ms p99
13 / 18 Semi tab
When to use
- Code/Inline code, API responses, terminal output
- Label/Section headers, metadata, navigation breadcrumbs — uppercase + tracking
- Data/Counters, stats, tabular numbers — Web use
font-variant-numeric: tabular-numsfor column alignment. Android usefontFeatureSettings = "tnum"in Compose
Platform notes
- All Same sizes on all platforms — monospace is rendered consistently across iOS, Android, and web.
- Web Load via Google Fonts:
family=IBM+Plex+Mono:wght@400;600. Only 400 and 600 weights needed. - iOS Bundled as static .ttf (Regular + SemiBold). Loaded via
Font.Family.ibmPlexMono. - Android Bundle IBM Plex Mono in
res/font/(Regular + SemiBold .ttf). In Compose useFontFamily(Font(R.font.ibm_plex_mono_regular)). Do not use Google Fonts runtime download. - Android Use
spfor all mono sizes. For tabular number alignment in Compose, usefontFeatureSettings = "tnum".