Layout
elements man style/layout Read as markdownLayout primitives are composition containers. This is layout.css in
@layer components.
The composition contract
One rule governs spacing in the system:
Layout containers own spacing. Components never set outer margins.
No component in the design system puts a margin on its outer element. If you
need space between two things, wrap them in a .stack or .cluster and let the
container's gap do it. This keeps components portable. The same card works
inside any layout because it never assumes a margin.
Flow primitives
.stack: vertical flow with a consistent gap between children. Gap variants
is-xs / is-sm / is-md / is-lg / is-xl / is-2xl step the gap up.
<div class="stack is-lg">
<h2>Account</h2>
<p>Manage your profile and billing.</p>
<button class="is-primary">Save</button>
</div>
.cluster: horizontal flow that wraps, vertically centered. For rows of
tags, buttons, or metadata that should wrap on narrow screens. Gap variants
is-xs, is-sm, is-md, is-lg, is-xl.
.row: horizontal flex that does not wrap. Alignment variants
is-baseline / is-start / is-end / is-stretch (default is centered).
Page structure
.page-shell: a width-constrained, centered page container with a gutter.
Width variants:
| Variant | Max width |
|---|---|
| (default) | --container-shell (72rem) |
is-narrow |
--container-sm |
is-form |
--container-2xl |
is-prose |
--container-prose (65ch) |
is-marketing |
--container-5xl |
is-wide |
--container-wide (80rem) |
is-full |
none (edge to edge) |
.page-hero: a hero block at the top of a page with generous top/bottom
padding; is-sm / is-lg adjust it. It also sets rhythm for a direct
.eyebrow, h1/.display, and .lede inside it, and constrains the lede to a
readable measure.
.section: a vertical-rhythm block between content areas; is-sm / is-lg
adjust the padding. Adjacent sections (.section + .section) get a soft top
rule automatically, so stacked sections divide themselves.
<main class="page-shell is-prose">
<div class="page-hero">
<p class="eyebrow">Changelog</p>
<h1 class="display">What's new</h1>
<p class="lede">Recent releases and fixes.</p>
</div>
<section class="section">…</section>
<section class="section">…</section>
</main>
App shell
.app: a full-height grid shell for an application layout (as opposed to a
content page).
.app.has-sidebar: adds a sidebar column. The width comes from
--sidebar-width (default 240px); set that token to change it. The layout
collapses to a single column at 48rem. .app-main is the main content column
(a flex column that won't overflow its track).
<div class="app has-sidebar" style="--sidebar-width: 280px">
<aside>…</aside>
<div class="app-main">…</div>
</div>
.app.has-sidebar is a layout grid hook, not a sidebar component. It gives
you the two-column grid and the responsive collapse. What goes in the sidebar
(navigation, its styling, any collapse toggle) is yours to build; v1 ships no
sidebar component.
Helpers
.center: flex-center on both axes; drop something in the middle of its container..divider: a visible horizontal rule (a filled 1px bar, not a border). Variants:is-soft/is-strongchange the weight, andis-verticalturns it into a vertical divider that stretches inside a.rowor.cluster.
<div class="row">
<span>Draft</span>
<span class="divider is-vertical"></span>
<span>Edited 2m ago</span>
</div>