Skip to content

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 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.

none0.noneNo spacing. For properties that require an explicit zero.
44px.s4Micro gap. Badge offset, icon indicator, tight visual pairs.
88px.s8Standard internal gap. Icon + label, title + subtitle.
1212px.s12Compact padding. Chips, dense list items, tight controls.
1616px.s16Standard component padding. Buttons, inputs, cards.
2020px.s20Screen horizontal margin. Content insets on standard screens.
2424px.s24Between elements within a section.
3232px.s32Between components within a screen.
4040px.s40Between sections within a screen.
4848px.s48Large structural separation between blocks.
5656px.s56Component height reference (FAB, AppBar). Use sparingly as spacing.
6464px.s64Large layout gap. Hero areas, major screen divisions.
9696px.s96Maximum spacing. Empty states, hero illustrations.

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 · 8

Between parts of one object. An icon and its label, a title and its subtitle, a badge nudged off an avatar.

Component padding

12 · 16 · 20

Between 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 · 40

Between separate objects on a screen. 24 within a section, 32 between components, 40 between sections.

Structure

48 · 56 · 64 · 96

Block 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.

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

Stellar PlanUnlimited US calls & texts
Add-onsTwo active

Billing

Card ending 6411

  1. 20 the screen margin, left and right. It is the only horizontal number on a standard screen, and it makes the usable width 320.
  2. 8 title to its supporting line. They are one object, so they take an inside-a-component gap.
  3. 24 heading to the first block. Different objects, same section.
  4. 16 between the two blocks. They are a list, not two sections.
  5. 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.

Measured off the Figma sets, not copied from a spec. This is the scale doing its job:

ComponentPaddingGap
Button Default12 / 248
List Row state layer12 / 1612
Action Card1616 (Default), 12 (others)
Action Card content stack4
Input stack4
Input field row10 / 08
Plan Selector card16 / 2012

Seven steps, drawn at their real value.

none0
sm4
md8
lg12
xl16
2xl24
full999

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.