Typography
Sora for figures and titles, Geist for every word of UI, Geist Mono for code. Every numeral is tabular, so figures read like a till.
Three typefaces
Sora's geometric lowercase echoes the Orbit wordmark and gives money the presence of a till display. Geist does every other job with an instrument's neutrality. All three are variable fonts, self-hosted through fonts.css.
--o-font-display--o-font-sans--o-font-mono| Token | Stack |
|---|---|
--o-font-display | 'Sora Variable', 'Sora', var(--o-font-sans) |
--o-font-sans | 'Geist Variable', 'Geist Sans', 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif |
--o-font-mono | 'Geist Mono Variable', 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace |
The ramp in product
Twelve roles, each set exactly as the components set them. Sora carries the figures and headlines; from Title down, everything is Geist.
- £3,214.80
- Good afternoon, Priya
- Orders
- £18,420.50
- 1,284
- Next up
- Delete 3 products?
- 5 orders to fulfil
- Paid and waiting to be sent. The oldest has waited 1 day.
- Save changes
- Takings today
- vs this time yesterday
- Unfulfilled · 12
Type tokens
A fixed rem scale for product UI, with a ratio of about 1.14. Components use 2xs to lg; the larger steps are for page titles, headlines and figures.
--o-text-2xs11px · 0.6875remArden chairSmall badges and deltas, nav counts, keycaps, chart axes--o-text-xs12px · 0.75remArden chairCaptions, meta lines, tooltips, badges, xs buttons--o-text-sm13px · 0.8125remArden chairLabels, hints, segmented options, sm buttons--o-text-md14px · 0.875remArden chairThe default UI size: body, fields, menus, buttons--o-text-lg15px · 0.9375remArden chairCard and empty-state titles, lg buttons--o-text-xl17px · 1.0625remArden chairPage-level text. Components stop at lg--o-text-2xl20px · 1.25remArden chairHeadlines: section titles on the canvas--o-text-3xl24px · 1.5remArden chairPage titles, and Display on phones--o-text-4xl30px · 1.875remArden chairDisplay: greetings and whole-screen states--o-text-5xl40px · 2.5remArden chairLarge figures--o-text-6xl56px · 3.5remArden chairThe largest figuresLeading and tracking
| Token | Value | Used for |
|---|---|---|
--o-leading-tight | 1.15 | Large display lines. No component uses it yet. |
--o-leading-snug | 1.3 | Titles, labels, dialog titles, tooltips. |
--o-leading-normal | 1.45 | Body text, menus, dialogs, cards. The .o-root default. |
--o-tracking-display | -0.025em | Sora figures and headlines (and the .o-display class). |
--o-tracking-tight | -0.012em | Titles in Geist: card and empty-state titles. |
Tabular numerals
The Till Rule: every numeral is tabular, everywhere. Figures, badges, deltas, fields, times, amounts, shortcuts. Columns of money line up, and a total that changes never shuffles sideways.
Figures that change
Money and counts that lead a view are set in Sora 600 and roll into place like a till display. A fall is written with a true minus sign. Take a sale to see it.
Weight in half-steps
Emphasis is tuned, not shouted: Geist moves in steps of 50, so a label can sit a half-step above its value. Synthesised bold is switched off inside .o-root, so a weight is never faked.
In both themes
The same ramp, light and dark. Words stay ink in both.
Guidelines
- The Sora Budget Rule. Sora is for figures, greetings, page titles and section headlines. Controls, labels, tables and body copy are always Geist.
- The Till Rule. Every numeral is tabular. Figures inside lists stay Geist at 550 to 600.
- The Sentence Case Rule. No all-caps, no tracked-out labels, no small labels stacked above headings.
- Geist Mono only for code, IDs and SKUs.
- Empty-state lines stop at 44 characters; body text in docs and settings at about 68.
In code
Read the tokens, or use the two utility classes: .o-display for Sora with display tracking, and .o-num for tabular numerals.
.takings__value {
font-family: var(--o-font-display);
font-size: 1.625rem;
font-weight: 600;
line-height: 1.1;
letter-spacing: var(--o-tracking-display);
font-variant-numeric: tabular-nums;
}
.takings__label {
font-size: var(--o-text-sm);
font-weight: 500;
color: var(--o-fg-3);
}<span className="o-display o-num">£3,214.80</span>