Skip to content
ArcadiaDesign

Ramp

Nine steps, each a size, a line height and a tracking; the values are measured live, in px.

StepSampleSizeLineTracking
Key caps, gutter numbers and captions
Section labels, badges and code
Rows, menus, pills and pickers
Conversation, the composer and tool lines
Markdown h3, a lead
Markdown h2, settings titles
Markdown h1, a section
Page titles
A public page's one statement

Tracking tightens as the size grows, about 1% of the size from 24px up and 2% at 48, so large type sets as compact as the reading sizes. Display sizes use weight 460, between regular and medium.

13 is the UI default and 15/24 is for reading; display and hero are for page titles and empty states. Hierarchy comes from rank (text-1 to text-4) before size, and from weight 500, never bold.

Roles

--type-* shorthands name a role: weight, size, line height and family.

RoleSampleSizeLineWeight
2m ago
Recent
Rename project
Fix the flaky settings test
The release spring brings a pressed button back with a 2.8% overshoot: felt rather than seen, and never in the way of the next click.
Settings
Checkpoints
Typography
Projects
Recent
const turn = await agent.run(prompt);
473k tokens, synced 5m ago, v0.1.0
Equipment for engineers in the field
CSS

They set the font only, so set the paired tracking beside them. A group label (a sidebar's Projects) is sentence case at 13/500 in text-1; an eyebrow (12/16, sentence case, text-3) names sections only inside menus, palettes and pickers. A readout (mono 11/16) is for machine facts: counts, versions, refs, timings. It never labels anything: column heads and stat labels are sans. A hero opens a public page, once.

Weights

Four weights.

Rename
418
Rename
460
Rename
500
Rename
600

418 is where SF Pro reads crisp on both themes; 500 is every label, button, title and heading; 460 is for display sizes; 600 is only for strong text in prose and search hits.

Legibility cut

One OpenType feature, on everywhere: SF Pro's cv05, a capital I with serifs, so Il1 and ILineItem never collide in identifier-heavy prose. It lives in --font-features.

Il1ILineItemIDisposable
Without it
Il1ILineItemIDisposable
The kit default

Geist Mono has no cv05, and neither do Segoe and the other fallbacks, so code needs no exclusion and other platforms keep their own I. There are no slashed zeros; numbers in readouts use tabular-nums, which the cut does not touch.

CSS

Links are ink, told apart by a quiet underline rather than a colour. The accent is kept for lights.

TokenUseValue
text-1: links are ink.
Ink at 30%: a quiet line under the ink.
text-1: on hover the line brightens to full ink; the text stays.
The underline's weight.
Clear of the descenders.

A bare <a href> in running text (p, li, dd, blockquote, figcaption and table cells) gets this from base.css. Anything with a class is a component and styles itself with the same tokens; heading links and navigation stay plain.

Text that doesn't fit

Never three dots: no ellipsis, no line clamp, no trailing dots in copy. They read as a slip. Four moves, in this order.

MoveWhat it doesWith
1. Fit it at the sourceSay what identifies the thing in fewer characters: a path's last folder or its place in the project, a branch without its namespace, a machine's name, a model's family.forms
2. Give way by priorityIn a row of chips the least important go icon-only first. Their words stay their accessible name and show on hover.PriorityRow
3. Fade its endOnly text that truly must be cut, a long chat title or a path in a long list, fades out at its end edge, with the full text on hover.FadeText
4. Let motion say itA status drops its dots: the spinner or the shimmer beside it already says the work goes on.Spinner

A status word (Signing in, Reconnecting, Summarizing context) needs no dots either, as long as something beside it moves. A loading row is a Skeleton in the row's shape, not a word.

Families

The system stack for text, so SF Pro on Apple platforms and the native UI face elsewhere, at no download.

TokenSampleStack
The quick brown fox-apple-system, SF Pro Text, Segoe UI, system-ui
bun test --watchGeist Mono, SF Mono, ui-monospace, Menlo, Consolas

Conversation text (15/24) renders untracked; UI text (13/18) tightens by 0.08px. Code is Geist Mono at 12/19, a terminal's line; inline code inside prose is --font-size-code-inline: 0.867em, so 13px in 15px text. Geist Mono is the variable cut (100 to 900) under the SIL Open Font License, embedded in the kit's stylesheet.

The tracking follows Apple's table for SF Pro: a hair open at 11px, none at 12px, −0.08px at 13px, none again at the 15px reading size, and tighter from 17px up. Each --type-* role pairs with the tracking of its size, which is why the shorthand leaves letter spacing to you.

Geist Mono ships with the kit for code, paths and token names; numbers stay in SF Pro, tabular.