Guidelines
Layout
Every block sits on one fluid grid: 4 columns on a phone, 8 on a tablet, 12 from 990px. Gutters and section spacing grow with the screen, so a block never needs its own breakpoints for rhythm.
The grid
Set in
packages/design-system/frontend.config.json and written to :root by A17's Setup plugin: --grid-columns, --inner-gutter (between columns) and --outer-gutter (the page margin). They change at Tailwind's breakpoints, so md: and lg: line up with the grid.| Breakpoint | From | Columns | Inner gutter | Outer gutter |
|---|---|---|---|---|
xs | 0px | 4 | 16px | 20px |
sm | 544px | 4 | 24px | 32px |
md | 650px | 8 | 32px | 40px |
lg | 990px | 12 | 40px | 40px |
xl | 1300px | 12 | 40px | 40px |
xxl | 1520px | 12 | 48px | 56px |
Tailwind breakpoints: sm 544px, md 650px, lg 990px, xl 1300px, xxl 1520px.
grid-layout
grid-layout lays out --grid-columns columns with --inner-gutter between them. Resize the window: the twelve cells wrap to three rows of four on a phone and two rows of eight on a tablet.1
2
3
4
5
6
7
8
9
10
11
12
col-span-full lg:col-span-8
col-span-full lg:col-span-4
col-span-4
col-span-4
col-span-4
<section className="px-outer-gutter py-outer-2">
<div className="grid-layout gap-y-gutter">
<h2 className="f-h2 col-span-full lg:col-span-8">Selected work</h2>
<p className="f-p-md col-span-full lg:col-span-4">…</p>
</div>
</section>Column widths
w-cols-N sizes an element to N columns plus the gutters between them, without a grid parent. It reads --container-grid-columns, falling back to --grid-columns; the demo below pins it to 12. From A17's Layout plugin, with ml-cols-N and pl-cols-N to offset.w-cols-3
w-cols-6
w-cols-9
w-cols-12
ml-cols-3 w-cols-6
Outer gutter, container, breakout
px-outer-gutter gives a full-width section its page margin. container centres content inside the outer gutter; a breakout child escapes to the full viewport width, for a full-bleed image inside a contained block. Both are in styles/system/container.css.Content
<section className="container py-outer-1">
<h2 className="f-h2">Raíces</h2>
<div className="breakout">
{/* full-bleed, edge to edge */}
<Image alt="…" src={cover} />
</div>
</section>Section spacing
Vertical rhythm between sections comes from three spacing groups in
frontend.config.json, as py-, pt- and pb- utilities. outer-1 separates big moments, outer-2 is the default section, outer-3 sits between related blocks.| From | outer-1 | outer-2 | outer-3 |
|---|---|---|---|
| 0px | 64px | 48px | 32px |
| 650px | 80px | 64px | 40px |
| 990px | 96px | 80px | 48px |
| 1300px | 128px | 96px | 64px |
spacing-outer-1
spacing-outer-2
spacing-outer-3
Design frames
The frames designs start from in Figma, as tokens.json records them. The CSS grid above is what ships; the frames set the sizes the type scale is tuned at.
| Frame | Device | Width | Columns | Inner gutter | Outer gutter |
|---|---|---|---|---|---|
xs | mobile | 390px | 4 | 8px | 14px |
xl | tablet | 1024px | 6 | 16px | 16px |
xxl | desktop | 1920px | 12 | 128px | 14px |
Rules
- Every section starts with px-outer-gutter (or container) and a py-spacing-outer-* step. No one-off section padding.
- Lay out on bw-grid with col-span-* and gap-gutter, or size with w-cols-N. Don't hand-pick gaps between columns.
- Full-bleed images use breakout inside a container; they don't fight the gutter with negative margins.
- Design at the three frames (390, 1024, 1920) and check the in-betweens: the grid changes at 544, 650, 990, 1300 and 1520.