Grid and layout

A 12-column grid inside a 1240 px wrap with 16 px gutters on phones and 40 px on desktop; text runs at 720 px.

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

Reference

Source reference; not an executed check.

columns
12
max
"size.container.lg"
text
"size.container.md"
narrow
"size.container.sm"
gutter
{"phone":"space.scale.6","desktop":"space.scale.10"}
gap
{"phone":"space.scale.8","desktop":"space.scale.9"}
section
{"min":"space.scale.11","fluid":"5vw","max":"space.scale.12","factor":1.125}
breakpoint
"size.breakpoint.md"
header
{"phone":"size.scale.64","desktop":"space.scale.13"}

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: One native reading column

Authored by grid.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: Grid and layout · Do: One native reading column Use the full-page example to follow page links.

The actual Page body renders a readable argument within the configured grid rather than presenting serialized widths as a layout demonstration.

Do: Destination cards share the wrap

Authored by grid.ts

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

Open example: Grid and layout · Do: Destination cards share the wrap Use the full-page example to follow page links.

Two real native cards share the grid and can reflow at the existing breakpoints; viewport acceptance still requires rendered checks.

Don't: A desktop width imposed on a phone

Authored by grid.ts

Rule illustration; not an executed check. grid / grid.no-scroll

.phone-article { width: 1240px; }
The whole document must scroll sideways to read a paragraph.
This illustrated fixed-width override defeats the shared wrap and hides content outside the phone viewport.

Don't: A heading cropped to fit its column

Authored by grid.ts

Rule illustration; not an executed check. heading / heading.whole-words

.phone-column h2 { white-space: nowrap; overflow: hidden; }
The final words of the heading disappear.
Cropping the argument is not responsive layout; native wrapping and a content repair should preserve the complete heading.

Rules

RuleWhyCheck
Nothing scrolls sideways at 390 px.Horizontal scroll on phones hides content.Automated: tests/site (no horizontal overflow at 390 px)
Every element is checked at 390, 768, 1024 and 1440 px.The four widths cover phones to large desktops.Automated: tests/site/system.spec.ts

API

No props.

Contract details

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

Identity

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

Use when

  • Every section's wrap and columns. Why: One grid aligns every page.

Do not use when

  • Full-bleed fields. Why: Fields span the viewport; their content sits in the wrap.

Anatomy

PartWhat it is
wrap.wrap (layout foundation)
columns12 from 960 px
gutters16 / 40 px

Made of: nothing (a base element).

Used in: layout.

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
--w-max1240 px content
--w-text720 px text
--gutter16 / 40 px
--grid-gap24 / 32 px

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
reading text and figures in grid columnsThe consuming element's copy budget; running text uses --w-text and forms/ledes --w-narrowKeep argument and evidence in reading order. Shorten an overlong heading before changing the type scale; do not crop text to fit a column.
layout names and values (fixed Library specimen)The complete LAYOUT entry serialized from brand.ts; no editable slotRetain native widths, gutters and breakpoint values. These rows describe layout policy, not executed viewport results.

Good: “Running text at --w-text, with its figure in the remaining columns (BRAND.md)” · “Forms and ledes at --w-narrow (BRAND.md)”

Bad: “A heading cut off at the edge of a phone column” · “A desktop-width paragraph forced to scroll with the whole page”

Japanese: Japanese text uses the same grid with phrase-aware heading breaks from its existing source. Allow real Japanese content to grow and recheck narrow layouts without shrinking type or clipping words. Keep layout identifiers unchanged; this policy is not a Japanese rendering or native-review result.

Icons and illustrations

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

Decisions and exceptions

  • None.

Usage

39 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.