Layout primitives

The wrap that centres content on the grid with its gutters, the plain section and section head used by hub pages, and the shared unstyled app mount inside task bodies.

Foundation · stable · v1.0.0 · owner: Site system lead · contract 19 of 20 points (open: figma)

Reference

Source reference; not an executed check.

wrap
centred, max 1240 px + gutters
section
--section padding

Do and don't

2 positive / 2 negative authored documentation examples (2 each required); 1 reference (1 required); 0 failed. References and failures do not count; this is not behavior acceptance.

Do: A heading and body inside one native wrap

Authored by layout.ts

Rendered consumer example; not an executed correctness check. titled-section Isolated document follows the browser's colour and contrast preferences. The outer theme toolbar does not control this document.

Open example: Layout primitives · Do: A heading and body inside one native wrap Use the full-page example to follow page links.

The native titled section owns one wrap and its semantic heading. The foundation supplies neither a second wrapper nor a task lifecycle.

Do: The actual page-body structure

Authored by layout.ts

Rendered consumer example; not an executed correctness check. prose-section Isolated document follows the browser's colour and contrast preferences. The outer theme toolbar does not control this document.

Open example: Layout primitives · Do: The actual page-body structure Use the full-page example to follow page links.

The native template retains reading order and its own wrap; this fragment does not claim to execute deferred landing behavior.

Don't: A wrap nested inside another wrap

Authored by layout.ts

Rule illustration; not an executed check. layout / layout.one-wrap

<section class="wrap"><div class="wrap">The same block receives gutters twice.</div></section>
The duplicated native layout responsibility would narrow the content and break alignment with adjacent sections.

Don't: Deferred content removed from the document

Authored by layout.ts

Rule illustration; not an executed check. layout / layout.progressive-landing

An offscreen section is deleted from the DOM and recreated only after scrolling.
Its headings, anchors, find results and focus targets no longer exist until then.
Progressive layout may defer rendering geometry, not the presence of the argument or its navigation targets.

Rules

RuleWhyCheck
Only top-level non-hero sections of page-landing opt into content-visibility:auto, with a named approximate block estimate and remembered measured sizes. Hash navigation and print render every section. Otherwise a focused non-hero section and its preceding sibling sections use full geometry for native focus scrolling; following sections retain auto rendering. All DOM content, anchors, find and focus remain available; unsupported browsers render normally.Long compositions may defer offscreen layout without removing content or changing the approved structure. The estimate is not an actual content-height claim.Automated: tests/site/progressive-rendering.spec.ts; tests/site/interactives.spec.ts
One wrap per block.Gutters stay 16 / 40 px.Automated: tests/site (no horizontal overflow)

API

No props.

Contract details

The full contract: identity, anatomy, variants, states, tokens, layout, motion, accessibility, content, tests

Identity

AspectValue
Idlayout
LayerFoundations
Categoryfoundation
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/foundations/layout.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26Layout primitives as one module: its markup moved out of the page builder (scripts/site) into the system.

Use when

  • Inside every template. Why: One wrap aligns every section's content.

Do not use when

  • Nested wraps. Why: A wrap inside a wrap doubles the gutters.

Anatomy

PartWhat it is
wrap.wrap
section.section
head.section-head
taskMountdiv#app.app, the shared HealthCheck and Survey mount; no intrinsic styles or lifecycle

Made of: grid.

Used in: pages directly.

Variants

VariantWhenWhy
light and darkEvery page, following the reader's setting.The same roles resolve to light or dark values, so no element chooses its own.

States

StateRendered or not applicable
defaultThe specimen.
hoverNot applicable: A foundation is not interactive.
focus-visibleNot applicable: Not focusable.
activeNot applicable: Not interactive.
disabledNot applicable: Nothing to disable.
loadingNot applicable: Values are built into the stylesheet.
emptyNot applicable: The build fails if a value is missing.
errorNot applicable: Unresolved values fail the brand gate, not the reader.
currentNot applicable: No current item.
visitedNot applicable: Not a link.
expandedNot applicable: Does not open.

Tokens

PartToken
wrap.max--w-max + 2 × --gutter
section.padding--section
section.render-estimate--section-render-estimate → --w-text (720px approximate placeholder, not a measured height)

Layout

AspectValue
breakpointsRequired review at 390, 768, 1024 and 1440 px; execution is not implied by this declaration; columns stack under 768 px; the wrap keeps a 16 px gutter on phones.
wrappingText wraps; nothing scrolls sideways.
textExpansionJapanese runs 20 to 40% longer; headings break between phrases (jaBreaks) and blocks grow downwards.

Spacing and rhythm

AspectValue
internalNot applicable: a foundation has no box of its own.
externalNot applicable.
rhythmApplies to every element that reads it.

Motion

AspectValue
NoneA foundation does not move.

Runtime and reuse

  1. Render-only element; mount any registered child enhancements separately. Preserve required Site CSS, fonts, responsive and locale rules from nativeElement.

Accessibility passport

AspectValue
roleNot rendered on the site; its specimen in the Library is a list
nameThe foundation's name
keyboardNot interactive.
focusNot focusable.
screenReaderThe specimen is a plain list of names and values.
contrastEvery text and ground pair in the palette is checked (check-brand).
targetNot a target.

Content

SlotLengthVoice
section heading and introduction (consumer-owned)Heading and the consuming template's lede/body budgetsGive each section a readable subject and keep the related introduction with it in .section-head. The layout classes do not create headings or supply text.
task body in div#app.appThe mounted HealthCheck or Survey contract's content budgetKeep the native task's instructions, controls and recovery text. The mount supplies neither content nor application lifecycle; deferred landing sections must retain their DOM content.

Good: “What happens next (Heading's section title inside one wrap)” · “One wrap per block, with the section heading before its body (layout.one-wrap)”

Bad: “A nested wrap that doubles the reading gutters” · “Removing a section's text from the DOM to defer its rendering”

Japanese: Japanese headings and body copy come from their consuming templates or task sources, with the same semantic reading order. Allow text expansion inside the existing wrap; do not hide Japanese content to preserve an estimated section height. No translation or task lifecycle API is added, and native/manual review remains separate.

Icons and illustrations

None: this element uses no icon or illustration of its own.

Decisions and exceptions

  • None.

Usage

893 owned-class occurrences in built pages plus metadata-token references in built CSS (measured by npm run site:system).

No application mechanism is declared.

Current check result: not assessed by this report. Declarations and source-file presence do not establish executed enforcement or accepted coverage.

Tests

AspectValue
unittests/unit/site-system.test.ts: renders every do and don't example through the registry and checks the classes it owns
visualNot yet: there are no screenshot baselines; the Library page is checked for sideways scroll at 1440 px by tests/site/system.spec.ts
a11ytests/site/system.spec.ts: axe (0 serious or critical) on the element's Library page in light and dark
parityscripts/site/system/check.ts: Library examples are rendered by the same render function the site imports

Figma

not-yet: The Loom Site Figma library is the last stage of the plan; this element is not mapped yet.

Open in Storybook

Start with a conversation about your system.

We read your system, show you what we found, and agree with your team what to fix first.