Skip to content

ADR-0078: Typography and motion join the list the design extract binds

Status: Accepted — amends ADR-0066, which stands Date: 2026-09-20

Decisions

D-158 The type scale is a token set, and the extract binds it

Display, heading, subheading, body and caption, defined once in @theme beside the palette, with size, weight and line height fixed per token. A surface names a token; it does not name a size. Fonts stay self-hosted — e2e/SelfHostedFont.spec.ts already fails a build that names a font host, and that assertion is unchanged by this ruling.

D-159 Motion is a token set, and the extract binds it

Two durations and one easing curve, in @theme, and three uses: hover, active, and the transition between routes. A surface that animates does it with a token. No surface invents a duration, and no surface animates anything a Handler is reading.

Context

D-142 states the bound list as a list — colour, spacing, surface treatment, card, border, radius — rather than as "the visual layer", because a named layer is a boundary somebody argues about later. Typography and motion sit outside that list, which means nothing governed them.

The prototype test asked for typography that makes a topic findable and for consistent hover and transition behaviour across cards and buttons. Both requests are about consistency, and the mechanism the repository already has for consistency is a token set with a source sweep over it: OnePalette.spec.ts is the precedent, and the ad-hoc amber-* utilities it replaced are what happens without one.

Decision

The bound list grows by two entries. The extract wins on type scale and on motion the same way it wins on colour, and loses to a ruling on contact the same way. Each token set is asserted by a source sweep in the shape of OnePalette.spec.ts: a surface using a raw Tailwind size or duration utility fails a build rather than a review.

Rejected options

  • Define our own type and motion tokens without ranking the extract for them — rejected: it ends the ad-hoc utilities but leaves the extract and the application free to disagree about type with no rule to settle it, which is the argument D-142 exists to prevent having twice.
  • Leave typography and motion unbound, decided per surface — rejected in the owner's words as exactly how the amber-* utilities got scattered in the first place.
  • Widen D-142 to "the visual layer" — rejected: D-142's own reasoning is that a named layer is a boundary somebody argues about later. Two more list entries is the amendment; a category is not.

This ruling may not be re-decided

If your change contradicts an Accepted ADR: stop and raise it. Do not implement over it. Superseding requires a new ADR that says so; never edit an Accepted one.

Consequences

Type and motion become reviewable mechanically, and a redesign of either is a token edit rather than a sweep of surfaces. Headings stop being chosen per screen.

What becomes hard: a surface with a genuine one-off typographic need has no legal way to express it, and must either earn a token or use the nearest one. That is the same cost the palette already imposes, taken deliberately.

Coverage

No upstream finding lands here. The ruling extends D-142's own argument to two more entries, on a request from the prototype test (D-104).