Layout & the content seam
Your template supplies the chrome (header, footer, sections). The platform supplies pages, donate, services, events, campaigns, the members area, and they render inside your template. For those pages to line up with your own sections, there is exactly one rule.
The seam: .container and .full
Section titled “The seam: .container and .full”Platform pages render through two layout intents, and your template styles them:
.container, the contained content column (text, forms, cards). This is where the vast majority of content lives..full, edge-to-edge, regardless of the container it sits in (a hero image, a colour band).
You control how they look:
- Set the width with the
--containertoken (see CSS tokens). - Add your gutter and any treatment by styling
.container(and.full) in yourtheme.css.
Because your sections and the platform’s pages both flow through .container; they line up automatically, in every template, on every page, with no per-page work.
:root:root { --container: min(1200px, 92vw); /* your content width */}.container { padding-inline: 1.5rem; /* your gutter */}Use .container in your own layout and sections too, the header inner, the footer inner, each section’s content wrapper. One container, everywhere.
Never build a parallel content container
Section titled “Never build a parallel content container”The one thing that breaks alignment is defining your own content container, a class sized off var(--container):
/* ✗ Rejected at publish. Platform pages stay on .container, so this drifts from them. */.mytheme-container { max-width: var(--container); margin: 0 auto; padding: 0 1.5rem; }Platform pages never see .mytheme-container, so your sections and our pages end up in two different columns with two different gutters. The publish validator rejects any selector other than .container/.full that sizes its width off var(--container), so this is caught the moment you upload, before review, with a message telling you to style .container instead.
If you need a full-width bar with a centred inner (an announcement rail, a stat strip), compose the seam instead of copying it, put .container on the inner element and keep your own class only for the extra styling:
<div class="mytheme-rail"> <div class="container mytheme-rail-inner">…</div></div>/* ✓ .container gives the width + gutter; your class only adds the flourish. */.mytheme-rail { background: var(--band-deep); }.mytheme-rail-inner { display: flex; justify-content: center; gap: 1.2rem; }That is the whole contract: customise the seam, never replace it. Fill it and every platform page falls into your layout, fluidly.

