Foundations
Spacing
Scale
An 8-point grid, from 8 to 64. Every space between and inside elements is one of these steps; 4 is a half step, for the tightest pairs only, like an icon and its label. The bars show how often the app uses each step today.
space-18ptIcon to label; rows in a list; title to its metadata.
space-216ptCard padding; between blocks inside a card.
space-324ptScreen gutters; between cards.
space-432ptBetween groups of cards.
space-540ptBetween sections of a screen.
space-648ptAbove a screen's first section.
space-756ptLarge breaks; matches the button height.
space-864ptThe largest break; hero spacing.
Off the grid, in the app today
The app grew before the grid. Move these to the nearest step when you next touch the screen they're on.
| Value | Uses | Move to |
|---|---|---|
| 10 | 65 | 8 |
| 14 | 45 | 16 |
| 12 | 41 | 8 or 16 |
| 6 | 24 | 8 |
| 18 | 19 | 16 |
| 20 | 14 | 24 |
Sizes
14
Button radius
Theme.radiusButtons and wells.
24
Card radius
designedCards. Padding 16, so what sits inside gets 24 − 16 = 8.
22
Dialog radius
BusyOverlay · ConfirmDialogFloating panels over a scrim.
56
Button height
Theme.buttonHeightPrimary pill buttons.
38
Compact button
PillButton(compact:)Drawn height; the target is still 44.
44 × 44
Touch target
.frame(minHeight: 44)The HIG minimum, for every control, whatever is drawn.
24
Screen gutter
TopBarHorizontal padding at the screen edge.
1
Hairline
strokeBorder(lineWidth: 1)Outlines on buttons and cards.
Concentric corners
A shape inside another shares its center of curvature: its radius is the outer radius minus the padding between them. A card with radius 24 and padding 16 gives what's inside it radius 8. This is how iOS draws its own nested shapes, and SwiftUI can do the arithmetic itself with ConcentricRectangle and containerShape(_:).
Touch targets
Every control gets at least 44 × 44 points to land on, whatever it draws. Players reach for the screen while standing over an instrument holding a mallet, which is not the moment for a six-point miss.