Round-3 fixes from gate validation + human visual review of fresh
cropin.com and ooni.com clones:
- app.ts: section data-var rename used an unanchored substring replace,
so Tile2_data matched inside MediaTile2_data and emitted a corrupted
Mediatile2Data usage (ReferenceError at prerender). Word-boundary
regex; every map site now shares one derivation.
- graft.ts: about:blank iframes were blanket-skipped, missing the
Klaviyo newsletter form (mounted into a blank same-origin frame via
JS) — the audit's #1 complaint. Blank frames now graft; the
visibility gate still excludes 0-size tracking pixels.
- walker.ts: isVisible() now rejects boxes wholly outside the viewport
(off-left always; off-right only when the page isn't horizontally
scrollable; fixed boxes fully above/below), so a closed slide-in
drawer's contents no longer count as expected text (91.8% -> 93.4%).
- css.ts: four sizing-regime corrections — pin captured px for
circular shrink-0 slides (Splide slide chain collapsed 0x0);
flex-basis:100% for full-width shrink-0 slides; keep fixed-px grid
templates for scrolling track lists (repeat(N,1fr) squished a
50-track carousel); single full-bleed fixed track -> minmax(0,1fr);
keep authored heights whose in-flow children are fill children
(aspect-video heroes inflated 240 -> 720px); width:100% for
inset-spanned aspect boxes.
Gate scores: ooni home 88.7 -> 93.3 (responsive 32 fails -> pass),
pizza-ovens 90.8 -> 97.6 (perceptual 46.7% -> 17.2%).
107/107 compiler tests, all workspaces green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lottie-web renders vector animations from a JSON document at runtime. As
third-party JS it falls outside the declarative CSS path and the WAAPI / reveal /
marquee probes, so clones shipped the empty container and the animation was gone.
This adds a Lottie subset to Stage 5 motion: capture the deterministic part — the
source JSON (materialized local file, or inline animationData) plus playback
config — and emit a fixed DittoLottie client that re-mounts lottie-web on the
cid'd container.
Capture (compiler/src/capture/lottie.ts): in-page detector covering lottie-web's
registry (animationData in memory), <lottie-player>/<dotlottie-player>, Elementor
data-settings (source_json.url), and generic markup. Keyed by data-cid-cap.
motion.ts merges it into MotionCapture; capture.ts registers source URLs as assets
so the existing fallback fetch downloads + materializes them to /assets/cloned/lottie.
Generate (compiler/src/generate/lottie.ts): buildLottieSpec resolves cap->cid and
source URL->materialized local path (or embeds inline animationData), then emits
DittoLottie + wire/import helpers, mirroring DittoMotion. app.ts writes the
component, wires import+JSX, and injects lottie-web into the generated package.json.
Delivery (compiler/src/cli.ts): stripDeliveryDataCids now treats DittoLottie as a
runtime consumer, so its container keeps a semantic data-ditto-id anchor instead of
being stripped (without this the animation never finds its mount point).
Lottie-free clones stay byte-identical. Verified end-to-end: cloning a page with a
<lottie-player> scrapes the JSON, emits a wired DittoLottie, and lottie-web mounts
and plays the captured animation (rendered SVG viewBox matches the source JSON).
Unit tests cover buildLottieSpec resolution + drop rules.
Co-Authored-By: claude-flow <ruv@ruv.net>