Typography
One family, thirteen styles, four weights. Type belongs to the scale layer, because it does not change between themes.
See it
The styles as they meet in a card: a title in heading/h4, a lead line in subheading/md, body copy, a button label, and a timestamp in caption/md. Five styles are usually all one surface needs.
Waiting room
Upcoming appointments
Three clinicians available this afternoon
The appointment was moved to Thursday at 14:30 and the client has been notified. The room is ready from 14:15.
Choosing a style
The name says the job, not the size. heading/h1 is the page title and there is one per page; h2 a section, h3 a subsection, h4 a card, and each level is a step down the scale, so a subordinate heading can never overpower its parent. subheading/lg is a lead paragraph or a prominent label, and subheading/md a panel heading.
body/md, at 14px, is the default, and it is the most used style in the system. Fourteen rather than sixteen is a reason you can name: this is a dense professional tool, where a table of forty rows has to fit a screen, and Inter holds at fourteen. body/lg is for long-form copy — a letter, a note the reader settles into — and nothing else. caption/md is helper text and metadata, caption/sm the dense table cell and the timestamp, and caption/caps an overline for a section of a panel, the one place capitals earn their tracking; it is not a label style, and a form label is body text.
Button labels have their own two styles because a label is set tighter than a line of body copy and never wraps. Everything is Inter; code and the site’s own measurements are the system monospace. Two families, and the second only where the content is a value.
The scale
Line height follows the role: headings sit near 1.1, body copy between 1.5 and 1.6, and a caption in between, because a caption wraps to two lines at most. Tracking follows the size — negative on the large sizes, where Inter’s letters drift apart, and positive on the small ones, where they crowd — and body copy at reading size takes none.
heading/h1 — 40/44, ×1.10, -1.8px · Page title
heading/h2 — 32/36, ×1.13, -1.6px · Section title
heading/h3 — 28/32, ×1.14, -1.1px · Subsection title
heading/h4 — 24/28, ×1.17, -0.8px · Card title
subheading/lg — 20/24, ×1.20, -0.3px · Lead paragraph, prominent label
subheading/md — 18/24, ×1.33, -0.2px · Panel heading
body/lg — 16/24, ×1.50, -0.1px · Long-form copy
body/md — 14/22, ×1.57, 0px · Default body — the most used style in the system
button/lg — 16/20, ×1.25, -0.2px · Large button label
button/md — 14/18, ×1.29, -0.1px · Default button label
caption/md — 12/16, ×1.33, +0.2px · Helper text, metadata
caption/sm — 11/14, ×1.27, +0.8px · Dense table cells, timestamps
caption/caps — 10/12, ×1.20, +0.8px · Section eyebrows, overline labels
Weights
Four, and they mean things. Regular is text. Medium is the current item — the page in the sidebar, the selected row’s name — and a label that needs to hold its own beside body copy. Semibold is a heading and a button label. Bold is reserved; nothing in the system uses it yet, and the first thing that does should say why. Nothing goes under regular: a light weight disappears at text sizes, and the smallest size here is ten pixels.
regular 400 — The appointment was moved to Thursday.
medium 500 — The appointment was moved to Thursday.
semibold 600 — The appointment was moved to Thursday.
bold 700 — The appointment was moved to Thursday.
Setting text
A line of prose is capped at 37.5rem — the 68 characters of the body size, set as a length rather than in ch so a heading gets the same measure as a paragraph. Headings wrap balanced, so a two-line title breaks evenly; descriptions wrap pretty, so a single word never lands alone on the last line. Long-form text takes neither.
Numbers that change or line up — a table column, a timer, the ratios in the margin of this site — are set in tabular figures, so 14 and 27 take the same width and a sort changes nothing but the order. Nothing truncates without a way to the whole value: a dialog title wraps, and a token name does not break across lines because a broken identifier cannot be copied.
Punctuation is the real thing: curly quotes in prose and straight ones in code, an en dash for a range — 14:00–15:30 — and the ellipsis character rather than three stops. Copy is stored in its natural case and capitals are a transform, so a redesign never means retyping.
1,114 · 27 · 2,003 — tabular
1,114 · 27 · 2,003 — proportional
“Moved to Thursday, 14:00–15:30 … and confirmed.”
Corrections carried over
Three defects in the source are fixed here: two caption styles were set in Montserrat while everything else was Inter; letter-spacing mixed px and percent between weights of the same style, resolving to fractions of a pixel that were plainly not the intent; and the all-caps family carried its transform on the regular weight but not on medium or semibold.
The system this was derived from stored the cross-product of style and weight as forty-four separate text styles. Weight is an independent axis, so thirteen styles plus four weights expresses the same system in seventeen tokens — and makes it possible to change every semibold at once.
Accessibility
Text is real text, selectable and resizable: the site sets text-size-adjust: 100% so a phone does not inflate it on its own, and the page reflows to 320px and to 200% zoom without a sideways scroll. Font smoothing is set once on the root, where macOS would otherwise render every weight heavier than drawn. The document declares its language, so quotes, hyphenation and a screen reader’s voice follow it.
One thing is recorded rather than solved. A text field is body size, 14px, and iOS Safari zooms the whole page into a field under sixteen. The two fixes look different — sixteen on a phone, or fourteen held by a transform — and the choice is still to be made.