AI Skill Report Card

Building Müller Brockmann Grids

A89·Aug 14, 2026·Source: Web
Markdown
--- name: building-muller-brockmann-grids description: Builds editorial/magazine/report webpages on a genuine Müller-Brockmann modular grid (International Typographic Style) rather than a decorative imitation — one CSS-variable source of truth, a toggleable grid overlay sharing the content's box, subgrid "bands" snapping every element to column lines, an 8px baseline lock, and runtime optical alignment that puts display type's ink (not its box) on the grid line, plus a Puppeteer harness that proves 0px adherence. Use when building magazine spreads, editorial/report layouts, or Swiss/International Typographic Style pages; when asked for a "grid system," "grid overlay toggle," or "align everything to the grid"; and when diagnosing the two classic failures — a grid overlay that looks "slapped on top / misaligned," or large display type that looks "off the grid" even though its bounding box sits on a column line. ---
14 / 15
Bash
python3 grid_tokens.py --scaffold --cols 12 --baseline 8 --gutter 24 --margin 64 --maxw 1440 --accent "#e4002b" > page.html

This emits a full HTML page with:

  • :root CSS variables (--cols, --gutter, --margin, --bl, --lh, --maxw) as the single source of truth
  • .grid/.band subgrid scaffold for placing content by column line
  • .guides overlay CSS living inside the same content box as the content
  • Toggle JS (button + G key) that fades the overlay on/off
  • Optical-alignment JS that nudges display type so its ink, not its box, sits on the grid

Then verify it:

Bash
CHROME=/path/to/chrome PUP=/path/to/puppeteer-core node verify_grid.js page.html --widths=1440,1180,900

A clean run prints col=0px overlay=0px baseline≤4px ink=0pxGRID VERIFY: PASS.

Recommendation
Add a brief troubleshooting table mapping verify_grid.js output deltas to likely root causes for faster diagnosis.
14 / 15

Progress:

  • Step 1: Decide the field — 12-column + 8px baseline (general default) or 6×6/4×8 modular field grid (visible rows). Pick palette: white/near-black/one red accent. Pick a grotesque (Inter/Helvetica Now/Archivo) + a mono for folios/captions.
  • Step 2: Generate scaffold with grid_tokens.py, passing real cols/baseline/gutter/margin/maxw/accent. It warns if gutter/margin aren't baseline multiples — fix until clean.
  • Step 3: Build each spread as full-width sections, each with its own .grid + .guides pair. Place every element (headline, paragraph, image, caption) with grid-column: <start> / <end> inside a .band.
  • Step 4: Lock vertical rhythm — line-heights are px multiples of --bl (not unitless, especially on display type), margins/padding are baseline multiples, media heights are multiples of the leading (e.g. 240/360/432/480px).
  • Step 5: Confirm the overlay is a child of the SAME .wrap/content box as the content, not a full-width sibling of the section — this is the #1 cause of "slapped on top" misalignment.
  • Step 6: Wire the optical-alignment JS to run after document.fonts.ready and on resize, targeting masthead/numerals/section headlines — the elements whose scale makes side-bearing visible.
  • Step 7: Publish, then run verify_grid.js at widths both above and below --maxw. Read back a top-left zoom-crop screenshot to eyeball masthead vs body vs column line.
  • Step 8: Fix any nonzero deltas at the source (tokens, band spans, or font used for optical measurement) and re-verify.
Recommendation
Include a minimal snippet of the optical-alignment JS itself (not just its description) so the mechanism is verifiable inline.
18 / 20

Example 1: Input: "Build a magazine-style report page on a Swiss grid with a toggleable grid overlay." Output: A 12-col/8px-baseline scaffold from grid_tokens.py --scaffold, spreads built as .band subgrids, headline placed grid-column: 1 / 7, a .guides div nested inside the same .wrap as the content (not a page-width sibling), a G-key/button toggle fading body.grid-on .guides, and optical-alignment JS shifting the masthead's margin-left by its negative actualBoundingBoxLeft so the "H" ink — not its box — sits on column line 1. Verified with verify_grid.js at 1440/1180/900 showing col=0px overlay=0px baseline≤4px ink=0px.

Example 2: Input: "The grid overlay looks slapped on top and misaligned on wide screens." Output: Diagnosis per §2.2 — the content is centered in a max-width container while .guides is a full-width sibling of the section, so above --maxw the two no longer share column positions. Fix: move .guides inside the same .wrap, draw its columns with left/right: var(--margin) and the identical repeat(var(--cols),1fr) + column-gap: var(--gutter) used by the content grid. Re-verify at a width above --maxw to confirm overlay=0px.

Example 3: Input: "The big headline 'H' looks off the grid even though DevTools shows its box on the column line." Output: Diagnosis per §2.6 — box-on-grid ≠ ink-on-grid; the glyph's left side-bearing offsets the visible ink from the box edge at large sizes. Fix: run the canvas-measurement JS (using the actually-loaded webfont, not a fallback) to compute actualBoundingBoxLeft for the first character and set margin-left to cancel it. Re-verify with the "optical ink" check, excluding this element from the plain box-adherence check.

Recommendation
Clarify what happens when grid_tokens.py's baseline-multiple warning fires — show an example of the warning message and the corrected invocation.
  • One source of truth: every grid parameter as a CSS variable in :root; content and overlay both read the same variables — never hand-author the overlay separately.
  • Place elements by column LINE (grid-column: start / end) inside subgrid .bands, never by eyeballed percentages or pixel offsets.
  • Line-heights on display type must be explicit px multiples of the baseline unit, not unitless — unitless line-height on large type pushes the box off-grid.
  • Media (images/video) heights should be multiples of the leading so both top and bottom land on baseline lines.
  • Palette discipline: white paper, near-black ink, one accent (red is canonical). No warm-cream backgrounds, no blue/purple gradients.
  • Flush-left, ragged-right type; hierarchy via scale and weight, not color; a grotesque sans for display/body, a mono for folios/captions/annotations.
  • When rasterizing (headless screenshots, cairosvg, image-gen references), embed the real font (e.g. Liberation Sans or an actual Helvetica/Arimo TTF) — a generic Helvetica/Arial CSS stack silently falls back to Noto Sans and reads wrong.
  • Verify at multiple widths, including both above and below --maxw, to catch centered-container drift that only appears on wide viewports.
  • When checking column adherence, compute BOTH column-start and column-end line sets — an item spanning "to line N" ends at the far side of the gutter, so single-edge math falsely reports an error.
  • Overlay as a full-width sibling of the content section instead of a child of the same content box — causes "slapped on top" misalignment on any viewport wider than --maxw.
  • Treating box-alignment as sufficient for large display type — glyph side-bearing means the ink can be visibly off-grid even when the CSS box is exactly on a column line. Always run optical alignment on masthead/numeral/headline-scale elements.
  • Measuring optical alignment with the wrong font (e.g. headless Chrome without the webfont installed, falling back to a different grotesque) — side-bearing is font-specific, so a fallback font gives a wrong nudge. Embed the real font for offline verification.
  • Unitless line-heights on large display type, breaking the baseline lock.
  • Decorative grid lines drawn once and left static, rather than a live overlay computed from the same variables as the layout — drifts the moment margins or column counts change.
  • Skipping verification at widths above --maxw, missing the exact scenario that exposes centered-container drift.
  • Defaulting to warm-cream backgrounds or blue/purple gradients — breaks the restrained white/black/red Swiss palette.
0
Grade AAI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
14/15
Examples
18/20
Completeness
18/20
Format
14/15
Conciseness
13/15