Session handover — 2026-07-06 pt3¶
Continues from session-2026-07-06-pt2-handover.md (WCP content fix + ADR-0009
accepted + Slice 1). This half: executed ADR-0009 Slice 2a — the
emit/consume half of Capture v2. One commit on master, pushed: dec213b.
What changed — where to look¶
-
ADR-0009 Slice 2a (
dec213b) — site-level design tokens now flowdesign.json → emitSiteCss → per-site CSS override, wired into both lanes. Network-free; zero visual change until adesign.jsonexists (Slice 2b's extended capture populates it). New:lib/design-derive.js(pure deriver,_raw→ bounded buckets),lib/design-derive.validate.mjs(27 checks),scripts/emit-design-json.js(derivedesign.jsonfrom storedtheme.json_raw, no re-crawl).theme.jsgainsemitSiteCss+ tokenizes the brand CTA corner as--btn-radius. Callers:emit.js#emitProject,emit-theme-css.mjs(+designPathFor). Slice tracker split into 2a (done) / 2b (planned) indecisions/0009-target-output-architecture.md; the token table + cascade note landed inaesthetic-token-contract.md. -
Scope finding that sharpened the 2a/2b boundary. The hoped-for "derive real tokens from the existing
theme.json" didn't pan out: the stored_rawsamples carry noborderRadius/boxShadow(capture never grabbed them) and Wix<section>padding is0(rhythm lives on inner spacers). So the capture work moved wholly to Slice 2b; 2a is purely the emit/consume plumbing (mirrors Slice 1: ship the consumer with safe defaults, capture feeds it later). No contract change — the confirmed done-criteria already used a hand-authoreddesign.jsonas the shift demo. -
New known-pattern —
known-patterns.md"A per-site CSS override must be UNLAYERED to beat an unlayered:rootdefault —@layerloses". The load-bearing implementation call: an@layer siteoverride would silently lose toemitGlobalCss's unlayered:rootdefaults, soemitSiteCssappends an unlayered:rootand wins by source order.
Verified¶
- Zero-regression:
emitGlobalCssdiff (HEAD vs current, nodesign.json) is only the--btn-radiusdefault + two4px→var(--btn-radius)swaps; computed values identical (Slice-1's declaration-level bar).emitSiteCss(null) === ''. - Shift demo: a bounded
design.json(pill / lg / airy / flat) emits the correct unlayered:rootoverride block. - Both lanes (Phase 3 regression check on shared
emitGlobalCss): real CMSemit-theme-css.mjsoutput diffs against HEAD by exactly the three expected lines and nothing else; per-siteemit.jsloads clean. Validate script: 27/27.
Next priority¶
ADR-0009 Slice 2b — Capture v2 (the capture half). Extend the Playwright
capture() (lib/theme-extractor.js) to record real borderRadius +
boxShadow on button/card and the effective section-band rhythm (not the
0-padding <section> element — measure the inner spacer / band), then re-crawl
garvanbay + WCP so design.json carries real bounded tokens (today
emit-design-json.js yields empty tokens → no override, correctly). Then the
per-section style records + classifiers (alignment, image side, columns,
density, header/topbar) into capture-section-backgrounds.js, riding the
existing section-tone join rails. Slice 3 threads those section props into
blocks.
Carried/open (unchanged from pt2, see known-issues): 3 WCP logo-strip
placeholders; cross-account sharding unproven; non-fatal Map/Prose/Features
build errors; per-site static-build @source gap; per-site static
noindex,nofollow launch blocker.