Brik Design System
Foundation

Spacing

The 4-point grid, semantic padding and gap tokens, the device-fluid layout tier, and the primitive scale.

Spacing tokens control padding, margins, and gaps. Each token answers to exactly one axis:

AxisTokensVaries with
Density--padding-*, --gap-*[data-mode-spacing] on :root — one value at every viewport
Device--bds-page-inset, --bds-section-padding-block (the layout tier)Viewport width — fluid from mobile to desktop, never by density

No token takes both, so density modes and device modes never multiply (ADR-042).

Spacing values are multiples of 4px, with two named exceptions. npm run lint-tokens:grid reports off-grid values as warnings — it is a review aid, not a merge gate. What does block is spacing-mode-track (part of npm run validate): every [data-mode-spacing] track must stay a strictly increasing seven-rung scale with no rung at 0px, and any override it declares must be on-grid.

The two exceptions. Micro values — 0, 1px, 2px — sit below the grid's resolution. Half-steps — --space-150 / -250 / -350 / -450 (6 / 10 / 14 / 18px) — are one deliberate 2px-offset rung between each pair of 4pt rungs up to --space-500, for optical adjustments finer than a full step. Above 500 the ramp stops half-stepping. Both are Figma-backed and exempt from the grid check; a new off-grid value is not.

Semantic padding tokens

Purpose-bound spacing used in components. These values change between Base and Spacious modes.

Padding

PreviewTokenCSS VariableMaps to
padding-none--padding-nonevar(--bds-space-0)
padding-tiny--padding-tinyvar(--bds-space-200)
padding-xs--padding-xsvar(--bds-space-250)
padding-sm--padding-smvar(--bds-space-300)
padding-md--padding-mdvar(--bds-space-400)
padding-lg--padding-lgvar(--bds-space-600)
padding-xl--padding-xlvar(--bds-space-800)
padding-huge--padding-hugevar(--bds-space-1200)

Semantic gap tokens

Gap tokens for flex and grid layouts. Typically smaller than the equivalent padding tokens.

Gap

PreviewTokenCSS VariableMaps to
gap-none--gap-nonevar(--bds-space-0)
gap-tiny--gap-tinyvar(--bds-space-50)
gap-xs--gap-xsvar(--bds-space-100)
gap-sm--gap-smvar(--bds-space-150)
gap-md--gap-mdvar(--bds-space-200)
gap-lg--gap-lgvar(--bds-space-400)
gap-xl--gap-xlvar(--bds-space-600)
gap-huge--gap-hugevar(--bds-space-800)

Spacing modes

Three named modes plus default modulate --padding-* and --gap-*:

  • Default (no attribute) — values from figma-tokens.css base. Used by product apps.
  • compact — tighter spacing for dense interfaces.
  • comfortable — moderate increase from default.
  • spacious — large increase, typical for marketing sites and .body-classed surfaces.

Mode values auto-generate at tokens/modes-spacing.css — never hand-edit. Re-run npm run build:sd-figma after a Figma mode update.

Layout tier

Two tokens set the page frame, and they are the only spacing tokens that change with the viewport. They scale smoothly between three device endpoints and stay flat above desktop.

TokenFillsMobile 320Tablet 768Desktop 1440+
--bds-page-insetpadding-inline — viewport edge ↔ content band16px (--bds-space-400)32px (--bds-space-800)96px (--bds-space-2100)
--bds-section-padding-blockpadding-block — a section's top and bottom band64px (--bds-space-1600)80px (--bds-space-1800)104px (--bds-space-2200)
.my-section {
  padding-block: var(--bds-section-padding-block);
}
.my-section__container {
  max-width: var(--bds-content-width-xl);
  margin-inline: auto;
  padding-inline: var(--bds-page-inset);
}

In TS, import pageInset and sectionPaddingBlock from @bds-tokens rather than writing the var() string inline.

Where the values come from. The Figma Foundations library has a layout collection with three modes — desktop, tablet, mobile. Each variable aliases a spacing primitive. Switch a frame's mode to mock a smaller device.

How it becomes fluid. Figma variables hold static numbers, so the build turns the three modes into one value: two clamp() segments added together, one from mobile to tablet and one from tablet to desktop. The widths are read from --breakpoint-mobile, --breakpoint-tablet and --breakpoint-wider. Output lands in tokens/layout-fluid.css — never hand-edit. Re-run npm run build:modes after a Figma change.

--bds-page-inset: calc(clamp(1rem, 0.2857rem + 3.5714vw, 2rem) + clamp(0rem, -4.5714rem + 9.5238vw, 4rem));

Never re-declare a layout-tier value in a site. No site-level clamp(), no @media override of --page-inset. The nav and every section read the same token, so they cannot drift apart. A component that needs a different step at a breakpoint picks another fixed token inside an @media on a --breakpoint-* rung — the component tokens themselves never change with viewport width.

Accessibility. Bounds are in rem, so the floors grow with the user's font size. At 320px the inset floors at 16px per side, leaving a 288px content box for WCAG 1.4.10 Reflow.

Space scale

The raw spacing scale from 0 to 176px. Semantic tokens reference these steps.

--space-0
0px
--space-25
1px
--space-50
2px
--space-100
4px
--space-150
6px
--space-200
8px
--space-250
10px
--space-300
12px
--space-350
14px
--space-400
16px
--space-450
18px
--space-500
20px
--space-600
24px
--space-700
28px
--space-800
32px
--space-900
36px
--space-1000
40px
--space-1100
44px
--space-1200
48px
--space-1300
52px
--space-1400
56px
--space-1500
60px
--space-1600
64px
--space-1700
72px
--space-1800
80px
--space-1900
84px
--space-2000
88px
--space-2100
96px
--space-2200
104px
--space-2300
112px
--space-2400
128px
--space-2500
136px
--space-2600
144px
--space-2700
152px
--space-2800
160px
--space-2900
168px
--space-3000
176px
  • Content Rhythm — the standard these tokens serve: which gap goes between which pair of elements, and where each step is set. This page is the catalog; that page is the rule.
  • Page Grid — the horizontal axis: the width-container recipe and --page-inset
  • Screen breakpoints — the --breakpoint-* rungs the layout tier's endpoints sit on
  • Cascade rules — how layers interact
  • Color tokens — semantic surface tokens that pair with these spacings
  • Typography tokens — type scale for content within these spaces

On this page

💬