Content container

Container width

The main content area is centered within the viewport and capped at --layout-content-max-width (1140px). The sidebar sits outside this container at a fixed --sidebar-width (260px).

Text width constraint

Prose text is constrained to --layout-text-half-width (50%) of the content container. This applies to TextSection headings, body text, and any standalone paragraph. The rule exists for readability — long lines of text are harder to scan.

A legacy token --layout-text-max-width (640px) also exists. Prefer the 50% token for new components.

No grid system

There is no 12-column grid. Components use simple fractions for their internal layout — 50%, 33.333%, 25%. These are set per-component (e.g. FigmaImage variants: full, half, third, quarter).

Column gap

When a component places items side by side (columns), the gap between them is 16px (--primitive-spacing-16). This is the standard column gap across all multi-column content blocks.

ComponentGapNotes
ImageRow 16px Between FigmaImage children
ContentGuide 16px Between purpose / usage / avoid cards
ContentCard planned 16px Between card items in a row

Use --primitive-spacing-16 as the gap token when building any new component that lays out children in columns.

Content-flow vertical spacing

How it works

Wrap page content in a .content-flow container. Inside, the lobotomized owl selector (> * + *) sets margin-top on every element. Only margin-top — never margin-bottom. The first child gets zero margin.

Spacing levels

LevelTokenValueUsed by
Section --content-flow-section 96px h2 — major section breaks
Block --content-flow-block 64px h3, h4, and all block-level components (TextSection, ImageRow, ContentGuide, CodeBlock, TokenTable, etc.)
Element --content-flow-element 24px p, ul, ol — prose flow (default for all elements)
Tight --content-flow-tight 16px Heading + first child pairing — pulls the next element close to its heading

Pair rules

When a heading (h2, h3, h4) is immediately followed by any element, the next element's margin collapses to --content-flow-tight (16px). This keeps headings visually bound to their content. The rule also works when a heading is followed by a block-level component like TextSection or ImageRow.

PatternSpacingRationale
h2/h3/h4 + any element 16px Heading stays bound to its content
ImageRow + ImageRow 16px Consecutive rows read as one visual grid — gap matches the internal column gap
ImageRow + TextSection 24px Caption-style text stays close to its visuals

Specificity

Block-level component selectors use .content .content-flow > .component-class (specificity 0-3-0) to override Astro's scoped component styles (0-2-0). Pair rules use .content .content-flow > :is(h2, h3, h4) + .component-class (0-3-1) to beat the block-level override.

Layout rules

  • Text max 50% — all prose content (headings, body paragraphs) must not exceed 50% of the content container width. Enforced via --layout-text-half-width.
  • Separator OR TabToggle, never both — pages use either a <hr class="content-separator"> or a TabToggle below the PageHeader. Never combine them.
  • Special pages skip content-flow — intro pages, hub pages, and index pages (like Getting Started, Identity hub) manage their own spacing. Only standard documentation pages use .content-flow.
  • Content padding — the content area has 80px padding on top and sides, 128px on the bottom. Components don't need to add their own outer padding.

Content block inventory

These are all the block-level building blocks available for composing documentation pages. Each one participates in content-flow at the block level (64px margin-top).

BlockStatusDescription
TextSection ready Prose block with optional heading, body, and button slot. Default variant: 50% width. Card variant: fills width, vertically centered, 40px padding, 360px min-height.
ImageRow ready Flex container for FigmaImage. Supports full, half, third, quarter variants.
FigmaImage ready Single image synced from Figma via Sanity. Used inside ImageRow or standalone.
ContentGuide ready TLDR block with three neutral cards — Purpose, Usage, Avoid. Icon + optional variant-colored badges + bullet list per card.
CodeBlock ready Code snippet with optional title bar and language label.
TokenTable ready Design token list with name, value, and visual preview.
PortableText ready Renders Sanity rich text blocks as semantic HTML.
ContentCard planned Card with image, title, and description. For linking to sub-pages or related content.
ContentFeature planned Side-by-side text + image block. For hero-style feature callouts within pages.
Perex ready Large emphasized text block (headline-sm) for key brand messages. 50% width, primary color.
Thumbnail ready Clickable navigation card. Image + heading + optional description. Fills its grid cell — place inside Columns count={2} or count={3}.
DoDont ready Guideline card showing correct / incorrect usage (green / red theme). Image + icon + heading + optional description. Fills its grid cell — mix inside Columns.
DownloadButton ready Compact clickable card for downloading files. Green icon box + filename with extension + upload date. Auto-width — sits inline in content, not a grid item.
ContentPreview ready Versatile showcase box for text, SVG, or image content. Four size variants with size-aware padding. Used for brand values, taglines, logo showcases, and moodboards inside Columns.
Page tokens