The skeleton. Five breakpoints, four container widths, one 12-column grid. Everything snaps to the 4px spacing scale — margins, gutters, column gaps — so layout math stays boring and content stays readable from phone to ultrawide.
Mobile-first. Every token is a min-width query. Don't invent new ones — if a layout wants to change at an odd width, the content is probably the problem.
Four sizes. Pick by reading posture: narrow for prose, wide for dashboards, full for canvases.
At ≥ 1024px, lay content on 12 equal columns with a 16px gutter. Common splits: 12, 8 + 4, 6 + 6, 4 + 4 + 4, 3 × 4.
Hatched blocks show each of the 12 equal tracks.
One content shape, four viewports. The grid collapses from 4 tracks to 1 as the viewport narrows — never reflow by pixel-tweaking individual elements.
Scale with viewport. Gutters grow from 12px on phones to 32px on large screens.
Tight packing — most of the screen is content.
Default. Used at md and above for most grids.
Generous. For dashboards where cards need breathing room.
Marketing surfaces and hero sections. Creates formal rhythm.
What to reach for, and what to avoid.
Every layout decision lives on 1/12, 2/12, 3/12 …. Fractional widths like 7/12 and 5/12 are fine but rare — they usually signal content that wants to breathe.
If a card is 340px or 287px, something's off. Ask whether you want 3 or 4 columns, then let the grid figure out the width.
Long prose — changelog, policy pages, settings descriptions — caps at the prose container. Anything wider becomes eye-straining.
Grid-inside-grid works for one level (page → card-grid). Two levels is the max. Deeper nesting means the content model is wrong.
Empty columns on either side of a 6-wide block aren't "unused space" — they're the margin that makes the block sit properly.
Past --bp-xl, the container pins to 1440px and the viewport absorbs the extra. Full-bleed is a deliberate choice (hero, canvas), not a default.
Copy-paste into _shared.css.
/* Breakpoints — mobile-first, min-width */ --bp-sm: 480px; --bp-md: 768px; --bp-lg: 1024px; --bp-xl: 1280px; --bp-2xl: 1536px; /* Container widths */ --container-prose: 720px; /* reading */ --container-default: 1240px; /* product */ --container-wide: 1440px; /* dashboards */ --container-full: 100%; /* canvases */ /* Grid */ --grid-cols: 12; --gutter-sm: 12px; /* < md */ --gutter-md: 16px; /* md */ --gutter-lg: 24px; /* lg */ --gutter-xl: 32px; /* xl+ */ /* Page gutter (outside the grid, next to viewport edge) */ --page-gutter-sm: 20px; --page-gutter-md: 32px; --page-gutter-lg: 40px;