Built · v1.0 · Figma board
Spacing & radius
A fixed 13-step scale built on a 4px grid. The tokens describe distances: gaps, paddings and
layout separations, across every screen in the app. They exist as variables in Figma and as an
AppSpacing ThemeExtension in Flutter, and the name is the value: spacing/16 is 16.
The scale
Section titled “The scale”The bars are drawn at their true size, so the scale you see is the scale you get. The Flutter
column is the name Kevin writes: AppSpacing.s16, never a raw 16.
Four jobs, not two
Section titled “Four jobs, not two”Every step belongs to one of four bands. This is the hierarchy: distance grows as the thing being separated grows, and you should be able to name the band before you pick the number.
Inside a component
4 · 8Between parts of one object. An icon and its label, a title and its subtitle, a badge nudged off an avatar.
Component padding
12 · 16 · 20Between a component’s edge and its content. 20 is the special case: it is the screen margin, not a component’s.
Between components
24 · 32 · 40Between separate objects on a screen. 24 within a section, 32 between components, 40 between sections.
Structure
48 · 56 · 64 · 96Block separation, reference heights, hero areas and empty states. Rare, and deliberate when it appears.
Never reach across bands to solve a layout problem. Padding a card with 32 makes it look like two components; separating two sections with 8 makes them look like one. The bands are the rule; the numbers are just where the bands land.
In place, at the floor
Section titled “In place, at the floor”A screen fragment reconstructed at 360, the device floor, with the real values marked. Every number here is a token, and nothing between them is invented.
Your plan
Renews on 14 September
Billing
Card ending 6411
- 20 the screen margin, left and right. It is the only horizontal number on a standard screen, and it makes the usable width 320.
- 8 title to its supporting line. They are one object, so they take an inside-a-component gap.
- 24 heading to the first block. Different objects, same section.
- 16 between the two blocks. They are a list, not two sections.
- 40 to the next section heading. This is the jump that says “new topic”, and it is why the two blocks above read as a group.
Everything vertical lands on a multiple of 8; 4 is reserved for micro adjustments inside a component. The grid, keylines and the two-up row live in Layout.
What the built components actually use
Section titled “What the built components actually use”Measured off the Figma sets, not copied from a spec. This is the scale doing its job:
| Component | Padding | Gap |
|---|---|---|
| Button Default | 12 / 24 | 8 |
| List Row state layer | 12 / 16 | 12 |
| Action Card | 16 | 16 (Default), 12 (others) |
| Action Card content stack | — | 4 |
| Input stack | — | 4 |
| Input field row | 10 / 0 | 8 |
| Plan Selector card | 16 / 20 | 12 |
Radius
Section titled “Radius”Seven steps, drawn at their real value.
Buttons and avatars are always full. Cards are lg or xl, and which one is
still open: the Action Card measures lg while the surface rule
asks for xl.