Spacing

Generated from DESIGN_SYSTEM.md

Rules

8-point grid. Every margin, padding, gap, and fixed size must be a multiple of 8pt/px. 4pt/px is the only allowed exception — for micro-adjustments between tightly-coupled elements only.

TokenValueTailwindiOS (AppTheme.Spacing)Android (Dimens)Use
space-14pt/pxp-1, gap-1xs (4pt)spacing_xsMicro-adjustment between coupled items
space-28pt/pxp-2, gap-2sm (8pt)spacing_smItems within a tight group
space-416pt/pxp-4, gap-4md (16pt)spacing_mdStandard gutter, card padding
space-624pt/pxp-6, gap-6lg (24pt)spacing_lgBetween groups, section gaps
space-832pt/pxp-8, gap-8xl (32pt)spacing_xlMajor section separation
space-1040pt/pxp-10, gap-10xxl (40pt)spacing_xxlHero padding
space-1248pt/pxp-12, gap-12xxxl (48pt)spacing_xxxlMaximum section breathing room

Standard gutters:

  • Page horizontal padding: 16pt/px (space-4, px-safe / md)
  • Card internal padding: 16pt/px (space-4)
  • List item vertical padding: 8–12pt/px (space-2 to space-3)
  • Nav item vertical padding: 8pt/px (space-2)
  • Section gap: 24pt/px (space-6)

Section panel padding — two canonical tiers (web; do NOT hand-roll per section):

A content section in a widget-panel / card-panel uses exactly one of three padding utilities. widget-panel itself carries NO padding, so the tier is always explicit. This replaced the prior drift (p-4 / p-5 / p-6 / pt-5 pb-4 px-4 all coexisting).

TierUtilityValueUse
XS (tight strip)section-pad-xsp-3 (12pt)Strip widgets whose own cards carry the weight; chrome must not waste space — finance index strip. Near the briefing player's tightness.
SM (compact)section-pad-smpx-4 pt-5 pb-4 (16 / top 20 / bottom 16)Compact widgets — weather, profile completion. Matches the weather card's tuned balance (the 20pt top is a deliberate 4pt exception so a header doesn't kiss the edge).
LG (content)section-pad-lgp-4 md:p-6 (16→24pt)Content sections — mate, hub, news, lens, charts.

A tight strip section (XS) pairs with HorizontalCardRail bleed="xs" so the cards still reach the panel edge despite the small padding. Special chrome opts out of all three: the top briefing player and the prompt input (bespoke player/input shells), and naked panel-less sections like the series rail (w-full space-y-3, no panel to pad).

Anti-patterns:

  • A widget-panel / card-panel content section with hand-rolled p-4/p-5/p-6/pt-* pb-* px-* instead of section-pad-sm / section-pad-lg — prohibited.
  • .padding(14), px-5, gap-5 — not on the grid, prohibited
  • spacing: 10 in SwiftUI VStack — use 4 (xs) or 8 (sm)
  • Arbitrary Tailwind values like px-[18px] — extract to space-4 or space-6

Live specimens

The 8-point scaleEach bar is drawn at its token width. 4 is the only step off the 8-grid.
  • space-14px
  • space-28px
  • space-416px
  • space-624px
  • space-832px
  • space-1040px
  • space-1248px
Section padding tierswidget-panel has no padding of its own, so every section names exactly one tier.
section-pad-xs

Tight strip: its own cards carry the weight

section-pad-sm

Compact widget: weather, profile completion

section-pad-lg

Content section: 16px on phones, 24px from md