[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71HZ1QEJ1DEP4NJCBMA0NFK":3,"skill-same:01M71HZ1QEJ1DEP4NJCBMA0NFK":68},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":46,"commitSha":47,"skillDirectory":48,"forksCount":49,"repositoryHtmlUrl":50,"repositoryHomepageUrl":51,"ownerHtmlUrl":52,"ownerBlogUrl":53,"ownerDescription":6,"updatedAt":54,"install":55,"resources":67},"01M71HZ1QEJ1DEP4NJCBMA0NFK","align-grid",null,"Build editorial\u002Fmagazine\u002Freport webpages on a GENUINE Müller-Brockmann modular grid (International Typographic Style) — not a decorative one. Encodes the discipline (columns + modules + baseline, grotesque type, flush-left, restrained black\u002Fwhite\u002Fred palette) AND the hard-won front-end engineering to make the grid real, visible, and verified: one CSS-variable source of truth, an interactive grid-toggle overlay that lives in the SAME content box as the content, subgrid \"bands\" so every element snaps to a column line, an 8px baseline lock, and runtime OPTICAL ALIGNMENT that puts display type's ink (not its box) on the line. Ships with a scaffold generator and a Puppeteer verification harness that proves 0px adherence.","danielvm-git\u002Fbigpowers","danielvm-git","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1020864?v=4","01M71H1N1CTQ529S0KN7KETVG6","Daniel V M","01M71H1N218Y3S8WHCJ58NPRSW",290,"MIT","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002F.gemini\u002Fextensions\u002Fbigpowers\u002Fskills\u002Falign-grid\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"grid","align grid","align","verified","line","modular","discipline","palette","verification","puppeteer","lock","display","black","element","end","overlay","ink","css","alignment","modules","2026-11-10 10:12:30",false,"---\nname: align-grid\nmodel: sonnet\ndescription: \"Build editorial\u002Fmagazine\u002Freport webpages on a GENUINE Müller-Brockmann modular grid (International Typographic Style) — not a decorative one. Encodes the discipline (columns + modules + baseline, grotesque type, flush-left, restrained black\u002Fwhite\u002Fred palette) AND the hard-won front-end engineering to make the grid real, visible, and verified: one CSS-variable source of truth, an interactive grid-toggle overlay that lives in the SAME content box as the content, subgrid \\\"bands\\\" so every element snaps to a column line, an 8px baseline lock, and runtime OPTICAL ALIGNMENT that puts display type's ink (not its box) on the line. Ships with a scaffold generator and a Puppeteer verification harness that proves 0px adherence.\"\ndisable-model-invocation: true\n---\n\n# Müller-Brockmann Grid Systems — built real, visible, and verified\n\nJosef Müller-Brockmann (1914–1996), Zurich; *Grid Systems in Graphic Design* (1981) is the corpus. The grid is treated as an ethic, not decoration: **\"The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice.\"** This skill encodes that discipline AND — the part most attempts get wrong — the front-end engineering to make the grid genuinely load-bearing on the web, plus a harness that PROVES it.\n\n> **HARD GATE** — Do NOT ship a grid page without running `verify_grid.js` first. A visually plausible layout is not evidence of grid adherence — the harness is. Zero failing assertions is the only passing bar.\n\n> Two real review notes this skill exists to prevent:\n> 1. *\"the grid is just slapped on top and misaligned\"* → the overlay wasn't in the same content box as the content (see §2.2).\n> 2. *\"the H in the headline is off the grid\"* → the headline's BOX was on the grid but its INK wasn't; large glyphs carry a side-bearing (see §2.6). **Box-on-grid ≠ ink-on-grid.**\n\n---\n\n## PART 1 — THE DISCIPLINE (decide before drawing)\n- **Objective order.** The grid brings \"constructive thought,\" legibility, and \"objective and functional\" design. Restraint is the point; the system, not the ego, organizes the page.\n- **Modular grid.** Divide the type area into a field of **modules** — columns AND rows — separated by consistent **gutters**, inside defined **margins**. Text and images occupy whole modules. Müller-Brockmann specimens common field counts (8 \u002F 20 \u002F 32 fields). For the web, a **12-column grid + 8px baseline** is a robust general default; a **6×6 or 4×8 modular field grid** when you want visible rows too.\n- **Baseline grid.** Vertical rhythm is sacred: **leading = a whole multiple of the baseline unit**, and every element snaps to it. This is what makes facing columns and images line up across the page.\n- **Typography.** A **grotesque sans** (Akzidenz-Grotesk \u002F Helvetica; on the web Inter, Helvetica Now, Archivo). **Flush-left, ragged-right.** Few sizes, large jumps in **scale** for hierarchy; objective, not expressive. Big **numerals\u002Fdata set large** is a signature move.\n- **Palette.** Pure white paper, near-black ink, **one accent — red is canonical**. Avoid the warm-cream \"Claude look\"; **never blue\u002Fpurple gradients** (hard house rule).\n- **White space + asymmetry.** Generous margins; asymmetric compositions held in tension by the grid.\n\n---\n\n## PART 2 — MAKE THE GRID REAL ON THE WEB (the load-bearing engineering)\n`grid_tokens.py` emits this whole scaffold correctly; the rules below are why it's built the way it is.\n\n### 2.1 One source of truth\nPut every grid parameter in `:root` CSS variables — `--cols, --gutter, --margin, --bl (baseline), --lh (leading=3×bl), --maxw`. **Content and the overlay both read these same variables.** Never hand-author the overlay separately or it will drift.\n\n### 2.2 The overlay MUST live in the SAME content box as the content  ← #1 bug\nFailure mode: content sits in a centered `max-width` container while the overlay is a **full-width sibling** of the section. On any viewport wider than `--maxw`, the centered content and the full-width overlay no longer share column positions → \"slapped on top \u002F misaligned.\"\n**Fix:** put `.guides` *inside* the same `.wrap`, and draw the column guides with `left\u002Fright = var(--margin)` and the **same** `repeat(var(--cols),1fr)` + `column-gap:var(--gutter)`. Then the overlay columns **are** the content columns at every width. Add left\u002Fright margin lines at `var(--margin)`.\n\n### 2.3 Place every element by column LINE via subgrid bands\nDon't eyeball spans. Each horizontal **band** spans all columns and re-exposes them:\n```css\n.band{grid-column:1 \u002F -1; display:grid; grid-template-columns:subgrid; column-gap:var(--gutter); align-items:start;}\n@supports not (grid-template-columns:subgrid){ .band{grid-template-columns:repeat(var(--cols),1fr);} }\n```\nChildren place with `grid-column: \u003Cstartline> \u002F \u003Cendline>` (e.g. `1 \u002F 6`, `6 \u002F 13`). Every headline, paragraph, photo, caption now snaps to identical lines.\n\n### 2.4 Lock vertical rhythm to the baseline\n- Leading = `--lh` (e.g. 24px = 3×8). **Every line-height a multiple of the baseline, in px (not unitless) for display type** — unitless line-heights on large type push the box off the grid.\n- Every margin\u002Fpadding a multiple of the baseline. Spread top\u002Fbottom padding a multiple too, so content starts on a line.\n- **Media heights = multiples of the leading** (e.g. 240\u002F360\u002F432\u002F480px) so a photo's top AND bottom both land on lines.\n- Hairline rules sit inside a baseline-height band, not free-floating.\n\n### 2.5 The toggle (sizzle within the sizzle)\nA control (button **+ `G` key**) toggles `body.grid-on`; overlay fades 0→1. Overlay draws: translucent **numbered column fields**, the **baseline** (major line every `--lh`, faint minor every `--bl`), and **margin lines**. Showing the real grid the page is built on IS the demo.\n\n### 2.6 OPTICAL ALIGNMENT — display ink, not its box  ← the subtle bug\nA 180px headline whose layout box is exactly on line 1 still looks misaligned against body text, because the letterform's **ink** is inset by its **left side-bearing**. Cure at runtime:\n```js\n\u002F\u002F after document.fonts.ready and on resize:\nvar cvs=document.createElement('canvas'),ctx=cvs.getContext('2d');\ndocument.querySelectorAll('.masthead,.numeral,.shead h2,.h2b').forEach(function(el){\n  el.style.marginLeft='0px';\n  var cs=getComputedStyle(el),ch=(el.textContent||'').trim()[0]; if(!ch) return;\n  if(cs.textTransform==='uppercase') ch=ch.toUpperCase();\n  ctx.font=cs.fontStyle+' '+cs.fontWeight+' '+cs.fontSize+' '+cs.fontFamily; ctx.textAlign='left';\n  var abl=ctx.measureText(ch).actualBoundingBoxLeft;     \u002F\u002F +ve = ink overhangs left of box\n  if(isFinite(abl)) el.style.marginLeft=abl.toFixed(2)+'px'; \u002F\u002F shift box so INK lands on the line\n});\n```\nApply to the masthead, big numerals, and section headlines. It scales with fluid type (re-runs on resize) and uses the **actually-loaded** font, so it's correct in the user's browser.\n**CRITICAL measurement caveat:** side-bearing is **font-specific**. If you measure with the wrong font you get the wrong nudge. Headless\u002Fsandbox Chrome usually lacks the webfont, so canvas falls back to a different grotesque (measured **−16px on the fallback vs −7px on real Inter** for the same `H`). To verify optics offline you must **embed the real webfont** via `@font-face` (local TTF). In production the runtime JS measures the loaded font and is correct.\n\n---\n\n## PART 3 — VERIFY (don't trust, measure)  → `verify_grid.js`\nRender with headless Chrome (Puppeteer) and assert, at **several widths including > and \u003C `--maxw`** (to catch centered-container drift, e.g. 1440 \u002F 1180 \u002F 900):\n1. **Column adherence** — every placed `.band > *` left snaps to a column START and right to a column END (~0px). **Exclude the optically-aligned display elements** from this box check (their box is intentionally side-bearing-offset; they're validated in step 4). **Gotcha:** build BOTH the column-start set and the column-end set — a grid item spanning \"to line N\" ends at the *far* side of the gutter, so single-edge math falsely reports a one-gutter error.\n2. **Overlay match** — each `.guides .col` rect equals the computed column rect (~0px).\n3. **Baseline** — text tops modulo the baseline ≈ 0 (tolerance ≈ half a baseline; the box-top is a proxy — the leading does the real work).\n4. **Optical ink** — each display element's ink-left (box − `actualBoundingBoxLeft`, real font) equals **its own** column line (nearest column-start to its box), not always line 1.\n\nSandbox Chrome flags that work: `--headless=new --no-sandbox --disable-gpu --disable-dbus --use-gl=angle --use-angle=swiftshader`. `file:\u002F\u002F` works for non-ES-module pages; the CLI `--screenshot` can hang on tall pages — drive via Puppeteer and screenshot per viewport. Read PNGs back with the image-capable Read tool to eyeball a **zoom crop of the top-left corner** (masthead vs body vs column line) — the fastest human check.\n\nA clean run looks like: `col=0px overlay=0px baseline≤4px ink=0px` → `GRID VERIFY: PASS`.\n\n---\n\n## PART 4 — CRAFT DEFAULTS (so it looks excellent, not just aligned)\n- **Palette:** white `#fff`, ink `#111`, one accent (Swiss red `#e4002b`). No warm-cream Claude look; no blue\u002Fpurple gradients.\n- **Type:** a real grotesque webfont (Inter \u002F Helvetica Now \u002F Archivo) for display + body; a **mono** (Space Mono \u002F IBM Plex Mono) for folios, captions, grid annotations — reinforces the technical register. Non-Latin via Noto Sans JP etc.\n- **Hierarchy** through scale + weight + white space, not color. Treat key data as **large numerals**. Kicker labels in mono caps. Per-spread folios.\n- **Real photography.** Ground real subjects in real photos (`SearchImages`). **Host each image via `PublishFilePublicly` and embed the `pub.hyperagent.com` URL** — a `PublishWebpage` artifact runs in a sandboxed iframe that can't authenticate thread-scoped `\u002Fapi\u002Ffiles\u002F...` URLs (broken-image trap).\n- **Type fidelity if you ever rasterize art** (cairosvg \u002F headless screenshots \u002F image-gen reference): a `Helvetica`\u002F`Arial` CSS stack silently falls back to **Noto Sans** (reads like Calibri). Render in **Liberation Sans** or an embedded Helvetica\u002FArimo TTF before trusting it. (Same trap as the optical-measurement caveat: wrong font in → wrong result out.)\n- **Spread model:** full-width sections, each its own per-spread `.grid` + `.guides`, consistent margins\u002Ffolios.\n\n---\n\n## PART 5 — WORKFLOW\n1. Pick the subject; gather real photos; host them publicly.\n2. Generate the scaffold: `python3 grid_tokens.py` (or `--scaffold` for a full page; `--cols\u002F--baseline\u002F--gutter\u002F--margin\u002F--maxw\u002F--accent` to taste; it warns if gutter\u002Fmargin aren't baseline multiples).\n3. Build spreads as **subgrid bands**; place everything by **column line**; lock spacing\u002Fline-heights\u002Fmedia heights to the **baseline**.\n4. Add the overlay (same content box) + toggle + optical-alignment JS (already in the scaffold; point its selector list at your display elements).\n5. Publish, then **verify**: `CHROME=… PUP=… node verify_grid.js \u003Cfile-or-url> --widths=1440,1180,900`. Eyeball a top-left zoom crop. Fix, republish.\n\n## SCRIPTS\n- **`grid_tokens.py`** — deterministic scaffold generator. Emits the `:root` tokens, `.grid`\u002F`.band` (subgrid) scaffold, `.guides` overlay CSS, toggle JS, and the optical-alignment JS — all wired to one source of truth. `--scaffold` emits a full minimal HTML page. No network\u002Fcredentials.\n- **`verify_grid.js`** — Puppeteer harness implementing all four checks above with the corrected both-edges column math, the optical-exclusion, per-element column-line ink targeting, and PASS\u002FFAIL output at multiple widths. Env: `CHROME` (chrome binary), `PUP` (puppeteer-core module path).\n\n## CREED\nA grid you can't toggle on and measure is a mood board, not a system. Build it from one source of truth, prove it at 0px, and align the **ink**.\n","# Müller-Brockmann Grid Systems — built real, visible, and verified\n\nJosef Müller-Brockmann (1914–1996), Zurich; *Grid Systems in Graphic Design* (1981) is the corpus. The grid is treated as an ethic, not decoration: **\"The grid system is an aid, not a guarantee. It permits a number of possible uses and each designer can look for a solution appropriate to his personal style. But one must learn how to use the grid; it is an art that requires practice.\"** This skill encodes that discipline AND — the part most attempts get wrong — the front-end engineering to make the grid genuinely load-bearing on the web, plus a harness that PROVES it.\n\n> **HARD GATE** — Do NOT ship a grid page without running `verify_grid.js` first. A visually plausible layout is not evidence of grid adherence — the harness is. Zero failing assertions is the only passing bar.\n\n> Two real review notes this skill exists to prevent:\n> 1. *\"the grid is just slapped on top and misaligned\"* → the overlay wasn't in the same content box as the content (see §2.2).\n> 2. *\"the H in the headline is off the grid\"* → the headline's BOX was on the grid but its INK wasn't; large glyphs carry a side-bearing (see §2.6). **Box-on-grid ≠ ink-on-grid.**\n\n---\n\n## PART 1 — THE DISCIPLINE (decide before drawing)\n- **Objective order.** The grid brings \"constructive thought,\" legibility, and \"objective and functional\" design. Restraint is the point; the system, not the ego, organizes the page.\n- **Modular grid.** Divide the type area into a field of **modules** — columns AND rows — separated by consistent **gutters**, inside defined **margins**. Text and images occupy whole modules. Müller-Brockmann specimens common field counts (8 \u002F 20 \u002F 32 fields). For the web, a **12-column grid + 8px baseline** is a robust general default; a **6×6 or 4×8 modular field grid** when you want visible rows too.\n- **Baseline grid.** Vertical rhythm is sacred: **leading = a whole multiple of the baseline unit**, and every element snaps to it. This is what makes facing columns and images line up across the page.\n- **Typography.** A **grotesque sans** (Akzidenz-Grotesk \u002F Helvetica; on the web Inter, Helvetica Now, Archivo). **Flush-left, ragged-right.** Few sizes, large jumps in **scale** for hierarchy; objective, not expressive. Big **numerals\u002Fdata set large** is a signature move.\n- **Palette.** Pure white paper, near-black ink, **one accent — red is canonical**. Avoid the warm-cream \"Claude look\"; **never blue\u002Fpurple gradients** (hard house rule).\n- **White space + asymmetry.** Generous margins; asymmetric compositions held in tension by the grid.\n\n---\n\n## PART 2 — MAKE THE GRID REAL ON THE WEB (the load-bearing engineering)\n`grid_tokens.py` emits this whole scaffold correctly; the rules below are why it's built the way it is.\n\n### 2.1 One source of truth\nPut every grid parameter in `:root` CSS variables — `--cols, --gutter, --margin, --bl (baseline), --lh (leading=3×bl), --maxw`. **Content and the overlay both read these same variables.** Never hand-author the overlay separately or it will drift.\n\n### 2.2 The overlay MUST live in the SAME content box as the content  ← #1 bug\nFailure mode: content sits in a centered `max-width` container while the overlay is a **full-width sibling** of the section. On any viewport wider than `--maxw`, the centered content and the full-width overlay no longer share column positions → \"slapped on top \u002F misaligned.\"\n**Fix:** put `.guides` *inside* the same `.wrap`, and draw the column guides with `left\u002Fright = var(--margin)` and the **same** `repeat(var(--cols),1fr)` + `column-gap:var(--gutter)`. Then the overlay columns **are** the content columns at every width. Add left\u002Fright margin lines at `var(--margin)`.\n\n### 2.3 Place every element by column LINE via subgrid bands\nDon't eyeball spans. Each horizontal **band** spans all columns and re-exposes them:\n```css\n.band{grid-column:1 \u002F -1; display:grid; grid-template-columns:subgrid; column-gap:var(--gutter); align-items:start;}\n@supports not (grid-template-columns:subgrid){ .band{grid-template-columns:repeat(var(--cols),1fr);} }\n```\nChildren place with `grid-column: \u003Cstartline> \u002F \u003Cendline>` (e.g. `1 \u002F 6`, `6 \u002F 13`). Every headline, paragraph, photo, caption now snaps to identical lines.\n\n### 2.4 Lock vertical rhythm to the baseline\n- Leading = `--lh` (e.g. 24px = 3×8). **Every line-height a multiple of the baseline, in px (not unitless) for display type** — unitless line-heights on large type push the box off the grid.\n- Every margin\u002Fpadding a multiple of the baseline. Spread top\u002Fbottom padding a multiple too, so content starts on a line.\n- **Media heights = multiples of the leading** (e.g. 240\u002F360\u002F432\u002F480px) so a photo's top AND bottom both land on lines.\n- Hairline rules sit inside a baseline-height band, not free-floating.\n\n### 2.5 The toggle (sizzle within the sizzle)\nA control (button **+ `G` key**) toggles `body.grid-on`; overlay fades 0→1. Overlay draws: translucent **numbered column fields**, the **baseline** (major line every `--lh`, faint minor every `--bl`), and **margin lines**. Showing the real grid the page is built on IS the demo.\n\n### 2.6 OPTICAL ALIGNMENT — display ink, not its box  ← the subtle bug\nA 180px headline whose layout box is exactly on line 1 still looks misaligned against body text, because the letterform's **ink** is inset by its **left side-bearing**. Cure at runtime:\n```js\n\u002F\u002F after document.fonts.ready and on resize:\nvar cvs=document.createElement('canvas'),ctx=cvs.getContext('2d');\ndocument.querySelectorAll('.masthead,.numeral,.shead h2,.h2b').forEach(function(el){\n  el.style.marginLeft='0px';\n  var cs=getComputedStyle(el),ch=(el.textContent||'').trim()[0]; if(!ch) return;\n  if(cs.textTransform==='uppercase') ch=ch.toUpperCase();\n  ctx.font=cs.fontStyle+' '+cs.fontWeight+' '+cs.fontSize+' '+cs.fontFamily; ctx.textAlign='left';\n  var abl=ctx.measureText(ch).actualBoundingBoxLeft;     \u002F\u002F +ve = ink overhangs left of box\n  if(isFinite(abl)) el.style.marginLeft=abl.toFixed(2)+'px'; \u002F\u002F shift box so INK lands on the line\n});\n```\nApply to the masthead, big numerals, and section headlines. It scales with fluid type (re-runs on resize) and uses the **actually-loaded** font, so it's correct in the user's browser.\n**CRITICAL measurement caveat:** side-bearing is **font-specific**. If you measure with the wrong font you get the wrong nudge. Headless\u002Fsandbox Chrome usually lacks the webfont, so canvas falls back to a different grotesque (measured **−16px on the fallback vs −7px on real Inter** for the same `H`). To verify optics offline you must **embed the real webfont** via `@font-face` (local TTF). In production the runtime JS measures the loaded font and is correct.\n\n---\n\n## PART 3 — VERIFY (don't trust, measure)  → `verify_grid.js`\nRender with headless Chrome (Puppeteer) and assert, at **several widths including > and \u003C `--maxw`** (to catch centered-container drift, e.g. 1440 \u002F 1180 \u002F 900):\n1. **Column adherence** — every placed `.band > *` left snaps to a column START and right to a column END (~0px). **Exclude the optically-aligned display elements** from this box check (their box is intentionally side-bearing-offset; they're validated in step 4). **Gotcha:** build BOTH the column-start set and the column-end set — a grid item spanning \"to line N\" ends at the *far* side of the gutter, so single-edge math falsely reports a one-gutter error.\n2. **Overlay match** — each `.guides .col` rect equals the computed column rect (~0px).\n3. **Baseline** — text tops modulo the baseline ≈ 0 (tolerance ≈ half a baseline; the box-top is a proxy — the leading does the real work).\n4. **Optical ink** — each display element's ink-left (box − `actualBoundingBoxLeft`, real font) equals **its own** column line (nearest column-start to its box), not always line 1.\n\nSandbox Chrome flags that work: `--headless=new --no-sandbox --disable-gpu --disable-dbus --use-gl=angle --use-angle=swiftshader`. `file:\u002F\u002F` works for non-ES-module pages; the CLI `--screenshot` can hang on tall pages — drive via Puppeteer and screenshot per viewport. Read PNGs back with the image-capable Read tool to eyeball a **zoom crop of the top-left corner** (masthead vs body vs column line) — the fastest human check.\n\nA clean run looks like: `col=0px overlay=0px baseline≤4px ink=0px` → `GRID VERIFY: PASS`.\n\n---\n\n## PART 4 — CRAFT DEFAULTS (so it looks excellent, not just aligned)\n- **Palette:** white `#fff`, ink `#111`, one accent (Swiss red `#e4002b`). No warm-cream Claude look; no blue\u002Fpurple gradients.\n- **Type:** a real grotesque webfont (Inter \u002F Helvetica Now \u002F Archivo) for display + body; a **mono** (Space Mono \u002F IBM Plex Mono) for folios, captions, grid annotations — reinforces the technical register. Non-Latin via Noto Sans JP etc.\n- **Hierarchy** through scale + weight + white space, not color. Treat key data as **large numerals**. Kicker labels in mono caps. Per-spread folios.\n- **Real photography.** Ground real subjects in real photos (`SearchImages`). **Host each image via `PublishFilePublicly` and embed the `pub.hyperagent.com` URL** — a `PublishWebpage` artifact runs in a sandboxed iframe that can't authenticate thread-scoped `\u002Fapi\u002Ffiles\u002F...` URLs (broken-image trap).\n- **Type fidelity if you ever rasterize art** (cairosvg \u002F headless screenshots \u002F image-gen reference): a `Helvetica`\u002F`Arial` CSS stack silently falls back to **Noto Sans** (reads like Calibri). Render in **Liberation Sans** or an embedded Helvetica\u002FArimo TTF before trusting it. (Same trap as the optical-measurement caveat: wrong font in → wrong result out.)\n- **Spread model:** full-width sections, each its own per-spread `.grid` + `.guides`, consistent margins\u002Ffolios.\n\n---\n\n## PART 5 — WORKFLOW\n1. Pick the subject; gather real photos; host them publicly.\n2. Generate the scaffold: `python3 grid_tokens.py` (or `--scaffold` for a full page; `--cols\u002F--baseline\u002F--gutter\u002F--margin\u002F--maxw\u002F--accent` to taste; it warns if gutter\u002Fmargin aren't baseline multiples).\n3. Build spreads as **subgrid bands**; place everything by **column line**; lock spacing\u002Fline-heights\u002Fmedia heights to the **baseline**.\n4. Add the overlay (same content box) + toggle + optical-alignment JS (already in the scaffold; point its selector list at your display elements).\n5. Publish, then **verify**: `CHROME=… PUP=… node verify_grid.js \u003Cfile-or-url> --widths=1440,1180,900`. Eyeball a top-left zoom crop. Fix, republish.\n\n## SCRIPTS\n- **`grid_tokens.py`** — deterministic scaffold generator. Emits the `:root` tokens, `.grid`\u002F`.band` (subgrid) scaffold, `.guides` overlay CSS, toggle JS, and the optical-alignment JS — all wired to one source of truth. `--scaffold` emits a full minimal HTML page. No network\u002Fcredentials.\n- **`verify_grid.js`** — Puppeteer harness implementing all four checks above with the corrected both-edges column math, the optical-exclusion, per-element column-line ink targeting, and PASS\u002FFAIL output at multiple widths. Env: `CHROME` (chrome binary), `PUP` (puppeteer-core module path).\n\n## CREED\nA grid you can't toggle on and measure is a mood board, not a system. Build it from one source of truth, prove it at 0px, and align the **ink**.\n",{"name":5,"model":44,"description":7,"disable-model-invocation":45},"sonnet",true,"main","72f5e4c8b43f60cf86b37078ad8cd7e22daf67aa",".gemini\u002Fextensions\u002Fbigpowers\u002Fskills\u002Falign-grid",24,"https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers","https:\u002F\u002Fdanielvm-git.github.io\u002Fbigpowers\u002F","https:\u002F\u002Fgithub.com\u002Fdanielvm-git","danielvm.net","2026-11-10 01:18:54",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":45},[57,60,63],{"tool":58,"command":59},"npx","npx skills add danielvm-git\u002Fbigpowers --skill align-grid",{"tool":61,"command":62},"bunx","bunx skills add danielvm-git\u002Fbigpowers --skill align-grid",{"tool":64,"command":65},"pnpm","pnpm dlx skills add danielvm-git\u002Fbigpowers --skill align-grid","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002F.gemini\u002Fextensions\u002Fbigpowers\u002Fskills\u002Falign-grid\u002FSKILL.md",[],[69,90,97,126,149,170],{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":80,"publishedAt":39},"01M71KBG9F8X644MJB16H4V8M7","skill-verify-fail-open-fixture","Negative-path fixture for run-skill-verify.sh — must never PASS.","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fspecs\u002Fverifications\u002Ffixtures\u002Fskill-verify-fail-open\u002FSKILL.md",[75],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[81,82,83,84,85,86,87,88,89],"fixture","open","verify","skill verify fail open fixture","skill verify","path","run","for","never",{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":39},"01M71KBE3BKEMKNE0C5DGVDWZH","negative-path","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fspecs\u002Fverifications\u002Ffixtures\u002Fnegative-path\u002FSKILL.md",[],[96,86],"negative path",{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":106,"publishedAt":39},"01M71KBBGF7Y4EB4AMHBZ8CJFC","write-document","Write, organize, and sync high-integrity technical documents using the BMAD methodology. Ensures every document is Bold, Minimal, Actionable, and Durable. Use when creating architectural docs, technical guides, or organizing the specs\u002F directory.","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fskills\u002Fwrite-document\u002FSKILL.md",[103],{"categoryNo":104,"categoryName":105,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000002","文档处理",[107,108,109,110,111,112,113,114,115,116,117,118,119,120,44,121,122,123,124,125],"write","write document","document","documents","actionable","technical","methodology","high","bmad","standard","use","when","minimal","bold","integrity","organize","sync","directory","guides",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":39},"01M71KB8TM089JJD5AY5KAFSDM","wire-observability","Add structured JSON logging, observability commands, and idempotent setup scripts to a project. Use when a project needs production-readiness instrumentation, when user wants structured logging, or as a production-readiness gate at any phase of development.","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fskills\u002Fwire-observability\u002FSKILL.md",[],[133,134,135,116,136,117,137,138,139,140,44,141,142,143,144,145,146,118,147,148],"observability","wire observability","readiness","commands","development","as","logging","add","instrumentation","at","structured logging","production-readiness","idempotent","phase","project","scripts",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":155,"publishedAt":39},"01M71KB6CNRANP449DQA3NJZ96","wire-ci","CI pipeline setup with bundled, forge-neutral templates and local validation. Detects the forge from the git remote, generates workflows for supported forges, and skips honestly for the rest. The CI equivalent of wire-observability.","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fskills\u002Fwire-ci\u002FSKILL.md",[],[156,157,158,159,160,161,162,163,164,165,166,116,167,88,133,44,168,169],"wire ci","ci","remote","local","pipeline","forge","validation","setup","templates","REST","with","ci pipeline setup","git","workflows",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":187,"publishedAt":39},"01M71KB2ZV98P03X88QR8MT9F1","visual-dashboard","Start a browser-based dashboard that visualizes architecture, implementation plans, and project status. Persists artifacts in .bigpowers\u002Fdashboard\u002F. Reads specs\u002Fstate.yaml, release-plan.yaml, epics, and planning-status via HTTP API or opencode panel.","https:\u002F\u002Fgithub.com\u002Fdanielvm-git\u002Fbigpowers\u002Fblob\u002Fmain\u002Fskills\u002Fvisual-dashboard\u002FSKILL.md",[176,179,184],{"categoryNo":177,"categoryName":178,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":180,"categoryName":181,"taxonomyType":182,"taxonomyTypeDesc":183},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",{"categoryNo":185,"categoryName":186,"taxonomyType":182,"taxonomyTypeDesc":183},"01JBSEEDCAT000000000000033","数据分析师",[188,189,190,191,192,193,194,195,196,44,197,198,199,200,201,202,203,147,204,205],"dashboard","visual","visual dashboard","status","artifacts","http","plans","planning","panel","start","release","opencode","plan","browser","api","architecture","project status","http api"]