Sizing

Colour answers what shade. Sizing answers how much space and how round — and in Tostada it lives in its own Sizing tab (Properties → Sizing), in plain numbers a beginner can read. The whole system is single-base: you set one number and everything follows, so you never audit forty paddings by hand.

One dial rescales everything

  • Spacing has a single base (4px by default). Every spacing value is the base × a number — change the base, or pick Compact / Comfortable / Spacious, and every padding and gap rescales together, live. (Under the hood each step is calc(var(--spacing) * N), so the browser does the rescaling — no per-value edits.)
  • Radius has a single base too. Drag it and every corner — buttons, inputs, cards, pills — rounds proportionally.

Spacing is named by intent

Instead of remembering raw numbers, you reach for a named intent that says where the space goes:

Intent Where it goes
inset padding inside a component (grids reuse it for their gaps)
stack vertical space above/below — between stacked things
inline horizontal space side-by-side — between things in a row

Each comes in a few t-shirt sizes (sm / md / lg …), with md as the default. Radius is even simpler: none · small · medium · full.

Layout widths

A container picks a readable content width — size-content-sm/md/lg (measured in characters, so lines stay readable) — or fills its space with size-fill.

Every element is Fit, Fill, or Fixed

(This per-component sizing is currently behind a feature flag while it stabilises.)

Borrowing Figma's vocabulary, each component sizes itself one of three ways:

  • Fit — hug the content (a button hugs its label). Components only — a container never hugs.
  • Fill — stretch to the available space (an input spans its row).
  • Fixed — keep an exact size (an avatar stays 64px).

Add min/max bounds to keep a Fill in check ("fill, but never below 240px or above size-content-lg").

Squish and stretch (advanced inset)

By default inset is square (the same padding all around). The advanced control lets a component set horizontal and vertical separately — buttons squish (more side padding than top/bottom), text fields stretch — and, deeper still, each side on its own.

What lives elsewhere

App-level breakpoints and each breakpoint's total layout width (which may be a fixed width or a full-bleed fill) are global settings owned by Layout principles, not sizing tokens. Sizing here is component-level: the spacing, radius, widths, and Fit/Fill/Fixed an individual component uses within whatever shell the layout gives it.

Make it yours

Every value is editable. Add a spacing step, a new intent value (inset-2xl), or a content width whenever you outgrow the defaults — and rename or remove the ones you don't use.