Layout primitives control structure and flow: how content stacks, how columns form, and how sections are contained. They work with spacing tokens (see Spacing) but serve a different purpose: spacing defines distance, layout defines arrangement.
Page Structure
All pages follow the same hierarchy:
body
└─ page-wrapper
└─ page-content
└─ section
└─ padding-global
└─ container / max-width
└─ block
Why this matters
- Clear separation of concerns
- Consistent spacing and widths
- Easy to scan and reason about layouts
<section>
<div class="padding-global">
<div class="container-m">
<div class="block">
<!-- Content -->
</div>
</div>
</div>
</section>
Sections
Sections group major content areas and control vertical spacing.
When to use
- Every major page section
- Any time you need vertical rhythm between content groups
Rules
- Sections own vertical spacing
- Use
.top-*and.bottom-*classes - Do not apply margins inside sections
<section class="top-large bottom-large">
<div class="padding-global">
<!-- Content -->
</div>
</section>
Padding Global
adds consistent horizontal padding to the page. It is applied once per section row, wrapping the container. Padding comes from , never from containers.
<section>
<div class="padding-global">
<div class="container-m">
<!-- Content here -->
</div>
</div>
</section>
| Class | Effect |
|---|---|
padding-left: var(--space-xl) + padding-right: var(--space-xl) |
Containers
Containers centre content and cap its maximum width. Use them inside sections to control content density.
, 640px
, 1040px
, 1200px
<div class="container-s">Narrow content</div>
<div class="container-m">Standard content</div>
<div class="container-l">Wide content</div>
| Class | Max Width | Use Case |
|---|---|---|
| 640px | Long-form text, forms, narrow content | |
| 1040px | Standard page content | |
| 1200px | Dashboards, wide layouts |
Rules
- Containers add
margin-left: autoandmargin-right: auto. They centre themselves - Containers set
width: 100%so they fill available space up to the max-width - Containers do not add padding — nest them inside for consistent page margins
- Use one container per section (in most cases)
Max-Width Utilities
Max-width utilities cap width without centring. Use them on individual elements that need a width constraint but should stay in normal flow.
| Class | Max Width |
|---|---|
| 640px | |
| 960px | |
| 1200px | |
| 100% |
<p class="max-width-s">This paragraph won't exceed 640px.</p>
Containers vs Max-Width
- Container = max-width + auto margins (centred)
- Max-width = max-width only (stays in flow, left-aligned)
Rule of thumb
- Centre content → use a container
- Only limit width → use max-width (exception, not default)
Blocks
A is a vertical flex stack with a default gap of between children. It is the fundamental building block for content layout — heading + text, text + buttons, image + caption, any content that belongs together.
No margins on children — enforced in CSS: .block > * zeroes margin-block, so gap-* is the only source of vertical spacing inside a block. Flex gap does not collapse with margins, it adds to them; without the reset, element defaults would compound with the gap. Horizontal margins survive — data-align="center" relies on margin-inline: auto.
Default gap
: default gap is --space-m (12px)
<div class="block">
<div>First item</div>
<div>Second item</div>
<div>Third item</div>
</div>
Gap modifiers
Add .gap-* to control spacing between children. These work on both and .
.block .gap-none
.block .gap-xs
.block .gap-s
.block .gap-l
| Class | Gap | Token |
|---|---|---|
| 0 | ||
| 4px | ||
| 8px | ||
| 12px | (default) | |
| 16px | ||
| 24px | ||
| 32px | ||
| 48px |
Horizontal row
Add to a block to switch from vertical stacking to horizontal layout. Use for right-to-left order.
.block .row .gap-xl
<div class="block row gap-xl">
<div>Left</div>
<div>Centre</div>
<div>Right</div>
</div>
Alignment modifiers
Use alignment classes on (or .block .row) to control cross-axis and main-axis positioning.
| Class | Effect |
|---|---|
align-items: flex-start |
|
align-items: center |
|
align-items: flex-end |
|
justify-content: center |
|
justify-content: flex-end |
Self Alignment
data-align centres the element itself within its parent, distinct from the .align-* classes above, which align children inside a flex block.
| Attribute | Effect |
|---|---|
data-align="center" |
Centres self horizontally (margin-inline: auto, justify-self: center) |
Use to centre a block without wrapping it in data-grid + data-col-start / data-col-span. Works in both normal block/flex flow and inside data-grid parents.
Width is required
margin-inline: auto is a no-op without a width constraint. fills 100% of its parent by default, so data-align="center" alone does nothing visible.
Pair with one of:
data-line-length="headline | small | body | medium | wide": applies a max-width from the typography scale (see Typography → Line Length)- A
max-widthfrom a component class - An explicit
width
data-line-length="medium".
<div class="block" data-align="center" data-line-length="medium">
<h2>Centred headline</h2>
<p>Centred paragraph with a comfortable measure.</p>
</div>
Grid
CSS grid layout with column presets. Grids create column-based layouts — they are not spacing utilities. The default is a responsive 2-column grid. Add or for more columns, and .gap-* to control gutter size.
Default (2 columns)
: default 2 columns, gap --space-m
<div class="grid">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</div>
3 columns
.grid .cols-3
<div class="grid cols-3">
<div>Item 1</div>
<div>Item 2</div>
...
</div>
4 columns with small gap
.grid .cols-4 .gap-s
| Class | Columns |
|---|---|
| 2 columns (default) | |
| 3 columns | |
| 4 columns |
Item width
| Class | Effect |
|---|---|
| Item sizes to content |
<div class="grid">
<div>Flexible column</div>
<div class="fit-content">Fixed</div>
</div>
Padding Utilities
General-purpose padding utilities for spacing inside elements.
| Class | Value | Token |
|---|---|---|
| 8px | ||
| 12px | ||
| 16px | ||
| 24px | ||
| 32px | ||
| 48px |
Key Rules
- Sections control macro spacing (
.top-*,.bottom-*classes) - Blocks control micro spacing (
.gap-*between children) - Grids control column layout. Use
.gap-*for gutters - Containers control width and centring. Never apply spacing directly to them
- Never mix responsibilities across layers
- Never use spacer divs or apply margins inside blocks
- Always use gap utilities for spacing between siblings, not margin on individual children