Size

Two ramps: how big a thing is, and how wide a page is allowed to get.

Two groups under one prefix, mirroring how spacing splits. element is small fixed lengths in px — icon boxes and control heights, which are one scale rather than two. measure is page widths in rem, so it scales with the root font while element deliberately does not: a 16px icon should stay a 16px icon.

Measure is the group that earns the page. It is not the breakpoint set: a breakpoint is a width you ask about, a measure is a width you impose, and conflating them is how a layout ends up changing shape at exactly the width it stops fitting.

Element

One ramp, two uses: the square is an icon box, the bar is a control height.

TokenValuePreview
--size-element-3…
--size-element-4…
--size-element-5…
--size-element-6…
--size-element-8…
--size-element-10…
--size-element-12…

Each preview shows the same token doing both jobs. An icon box takes the length twice — it is square, so one token sets height and width — while a control takes it once, as a height. A control's width comes from its content: a button is as wide as its label, so a fixed width would either truncate or leave a gap. Height is the opposite, and has to be agreed across every control on a row or nothing lines up, which is exactly what a token is for.

Neither an icon concept nor a control concept — both are a small fixed dimension, which is why they are one ramp rather than two. base × N like everything else.

Numeric rather than t-shirt, and the merge forces it. sm would have to resolve to one number, and a small icon is not a small control. So the scale holds lengths and the role lives in the component API — Button decides what medium means for a button, Icon decides separately, and those are genuinely different decisions. Semantic aliases can sit on top (--size-control-md: var(--size-element-8)) but need Button and Icon in front of them to be named honestly, so they wait.

One thing the grid removes on purpose: there is no 14px. 4px steps give 12 or 16 and nothing between, which is the same argument Border makes — a scale that cannot express a value is removing a decision rather than failing to offer one.

Measure

Four page widths, only one of which is really a measure.

TokenValuePreview
--size-measure-prose…
--size-measure-panel…
--size-measure-content…
--size-measure-wide…

The bars are relative, not true size: content is the width of the band you are reading, so a full-size row could only fill the page or run off it. Each is drawn as a fraction of the widest, which is the part a table can carry — the Value column has the number.

These are consumed by Stack's maxWidth, which takes a measure name or any raw length. The Stack owns the cap, never the Section — a band paints edge to edge while its content stays within the measure, which is why a full-bleed background and a readable column are the same component rather than two.

The group name papers over it. Measure is a typographic word meaning line length, and prose is the one that qualifies — rem is right there, because characters per line is a function of type size. A px cap would give a reader who enlarges their font the same column with bigger text, which is the problem a measure exists to prevent.

content and wide are not measures. They are page caps — the width the whole layout is allowed to occupy, grids and images and cards included — and nothing about that is a function of type size. The rem case for those is much weaker, and px is the more honest unit for a limit on how far a page may sprawl. Both the unit and the group name are open, and they are the same question: panel and content were never really measures, so calling them that is what made the unit look settled.

Which measures earn their place

content is on 77 bands — every band on every page — and panel on 29. prose and wide have no consumers at all. The scale had the wrong members, not the wrong values.

prose is the interesting absence. Nothing sets a measure on text in this system — a paragraph never carries a max-width; its measure comes from the lane it sits in, so a 2|1 band inside a content cap yields a text column of about 46rem without anyone naming it. A prose cap is a second mechanism for a job the lane already does, which is the same objection that removed vertical padding from nested Stacks.

Both are kept — unused is allowed, undeliverable is not — but they are on notice, and the likelier outcome is renaming rather than deletion. panel arrived by being needed; the two that were guessed at are the two nobody reached for.