diff --git a/.gitignore b/.gitignore index a639690..e47423f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,67 @@ tmp/ # Webster generated asset dedup cache .webster/generated-cache/ +# Council simulation working copy — committed deliverable lives in demo-output/ +local-runs/ + +# Audio working copies — only the leveled narration.mp3 is committed +audio/*.raw.mp3 + +# AI tool symlinks created by `skills add` — we only use Claude Code +# (.claude/skills) and the canonical store (.agents/skills). The rest are +# parallel-platform symlinks we don't ship to the repo. +.adal/ +.augment/ +.codebuddy/ +.commandcode/ +.continue/ +.crush/ +.factory/ +.goose/ +.iflow/ +.junie/ +.kilocode/ +.kiro/ +.kode/ +.mcpjam/ +.mux/ +.neovate/ +.openhands/ +.pi/ +.pochi/ +.qoder/ +.qwen/ +.roo/ +.trae/ +.vibe/ +.windsurf/ +.zencoder/ +skills-lock.json +skills/gsap +skills/hyperframes +skills/hyperframes-cli +skills/hyperframes-registry +skills/website-to-hyperframes + +# HyperFrames skill content (installed via npx skills add heygen-com/hyperframes) +# Treat like node_modules: re-installable via skills CLI, not committed. +.agents/ +.claude/skills/ + +# HyperFrames render artifacts (regenerable from compositions) +video/snapshots/ +video/renders/ + +# Rendered timelapse mp4 — hosted externally for the hackathon submission +demo-output/videos/ + # Pi subagent transient outputs (scout context.md, planner plan.md at repo root) /context.md /plan.md /research.md + +# Claude Design polish handoff bundles — committed per-slot only after review +skills/webster-video/polish-slots/**/handoff/ +skills/webster-video/polish-slots/handoff-shared/ +skills/webster-video/polish-slots.zip diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc index a695fc6..845dce1 100644 --- a/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -19,6 +19,8 @@ "site", "tmp", "history", + "demo-output", + "video/assets", "raw-videos", "transcripts", "research", diff --git a/README.md b/README.md index 9734595..5ff34f7 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ bun scripts/critic-genealogy.ts --fixtures scripts/__tests__/fixtures/genealogy **Live-run evidence:** the full operator path is [`prompts/second-wbs-session.md`](prompts/second-wbs-session.md), registration IDs live in `environments/webster-council-env.id` and `context/*/id.txt`, and run artifacts are written under `history//` when the weekly prompt is executed. +**Demo arc artifacts:** the hackathon timelapse animates an 11-week simulation council run. Per-week deliverables live under [`demo-output/landing-page/`](demo-output/landing-page/) (`w00..w10`): desktop/mobile/tablet screenshots, heatmap JSON+SVG, synthetic analytics, and the visual reviewer's markdown verdict. Anthropic Managed Agents memory-store provisioning is captured at [`assets/memory-stores-screenshots/`](assets/memory-stores-screenshots/). The rendered timelapse is hosted externally (link in the submission form); reproduce locally with `bun skills/webster-video/scripts/hydrate-demo-assets.ts && cd video && npx hyperframes render -q high --strict`. + **Hero code:** [`scripts/critic-genealogy.ts`](scripts/critic-genealogy.ts) is the runtime specialist-spawn path; [`scripts/__tests__/critic-genealogy.test.ts`](scripts/__tests__/critic-genealogy.test.ts) and [`scripts/__tests__/fixtures/genealogy`](scripts/__tests__/fixtures/genealogy) are the fixture proof. **Validate locally:** run `bun install` once, then `bun run validate` for type-check, zero-warning lint, format, agent schemas, findings format, markdown, and tests. diff --git a/context/webster-video/CONTEXT.md b/context/webster-video/CONTEXT.md new file mode 100644 index 0000000..232dccb --- /dev/null +++ b/context/webster-video/CONTEXT.md @@ -0,0 +1,78 @@ +# webster-video — CONTEXT (compaction-resistant) + +> Re-read this file at session start or after any autocompact event. Single Read call restores alignment without rescanning the plan. + +## Mission + +Ship a 130s, 1920×1080, 30fps demo video for the Webster hackathon submission ("Built with Opus 4.7", deadline **2026-04-28**). Video = `demo-output/videos/webster-lp-demo.mp4`. Stack = HyperFrames (render) + Auphonic (audio post) + Claude Design (polish). Skill = `skills/webster-video/`. Plan file = `~/.claude/plans/u-decide-whats-optimal-structured-spindle.md`. + +## Locked decisions + +| Decision | Choice | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Render engine | **HyperFrames** (HeyGen, OSS 2026-04-17). Install: `npx skills add heygen-com/hyperframes`. HTML/CSS/JS + GSAP `{paused: true}` on `window.__timelines`. 1080p cap (matches spec). | +| Audio post | **Auphonic** REST API, preset `voiceover-web-16` (-16 LUFS, moderate noise reduction, light compression). Raw narration → leveled `audio/narration.mp3`. | +| Brand polish | **Claude Design** at `claude.ai/design` (primary). Fallback: in-repo `frontend-design` skill. Both consume same slot-packet contract. | +| Length | **130s primary** (per `prompts/video-composition-session.md` storyboard). Optional 90s social cut via `video/lib/trim-points.js`. | +| Substrate | **LP only**. Northwest Reno site dropped (no weekly data on disk). | +| Voiceover | Dual: `audio/narration.raw.mp3` (Richie record) OR ElevenLabs Turbo v2.5 from `video/script.md`. Both feed Auphonic. | +| Captions | Whisper transcribe `narration.mp3` → `captions.srt`. Always-on (judges scrub muted). | +| Genealogy beat | Concept card + `scripts/critic-genealogy.ts` output if present, else architecture-card fallback. No fake spawn drama. | +| CI | `validate:video` opt-in via `VALIDATE_VIDEO=1`. Not in default `bun run validate` chain. | + +## Critical paths + +- **Source assets (committed Day 0)**: `demo-output/landing-page/wNN/{desktop,mobile,tablet}.png`, `*-heatmap.svg`, `analytics.json`, `heatmap.json`, `visual-review.md` for w00..w10 +- **Brand tokens**: `demo-output/landing-page/brand.json` (single source of truth, hydrated from `local-runs/.../context/brand.json`) +- **Council roster**: `demo-output/landing-page/agents.json` (10 sim agents) +- **Storyboard**: `prompts/video-composition-session.md` (lines 120–216 = 7 timed beats; lines 64–74 = synthetic disclaimer rules) +- **Narration**: `video/script.md` → ElevenLabs → `audio/narration.raw.mp3` → Auphonic → `audio/narration.mp3` +- **Captions**: `video/public/captions.srt` +- **Render output**: `demo-output/videos/webster-lp-demo.mp4` (final), `…/webster-lp-demo.draft.mp4` (Phase A) +- **Skill**: `skills/webster-video/` (SKILL.md + references/ + scripts/ + polish-slots/ + examples/) +- **HyperFrames project**: `video/` (scenes/, shared/, data/, lib/, master-cut.html) +- **HyperFrames skill (installed)**: `.claude/skills/hyperframes/` + +## Current phase + +`pre-bootstrap` + +Phases: `pre-bootstrap` → `tracking-set` → `assets-committed` → `hyperframes-bootstrapped` → `script-drafted` → `narration-raw` → `narration-leveled` → `captions-generated` → `draft-rendered` → `draft-confirmed` → `slot-packets-built` → `polish-applied` → `final-rendered` → `shipped` + +## Don't drift on (verbatim invariants) + +- **Synthetic-disclaimer phrases** must appear on every chart/heatmap/metric. From `prompts/video-composition-session.md` lines 64–74: + 1. `"Synthetic 5,000-user demo panel"` + 2. `"Mock analytics, not real visitor data"` + 3. `"Synthetic heatmap from DOM layout + mocked engagement"` +- **Pitch framing**: do NOT pitch as "AI made a prettier landing page" (per prompt line 47). Pitch as "weekly evidence loops with specialist agents and visual review." +- **Honest framing**: w08 underperformed; w09 council corrected. Do not soften to celebration; do not amplify to doom. +- **Headline metric**: "Synthetic discovery-call intent: 151 → 323 clicks, 2.1× after 10 simulated weekly passes." +- **Ugly-brand decoupling** (VISION.md): converge toward the brand bible, not away from the ugly state. The brand is in `brand.json`, not on the current page. +- **No real-traffic claim**: never imply analytics are real visitor data. +- **Mobile horizontal overflow**: never acceptable (per video-composition-session.md and visual-review.md w10). +- **Production agent boundary**: do NOT touch `agents/webster-{monitor,planner,redesigner,visual-reviewer,seo-critic,brand-voice-critic,fh-compliance-critic,conversion-critic,copy-critic}.json`. Sim agents (`webster-lp-sim-*`, `webster-site-sim-*`) are additive. + +## Polish slot index (9 slots) + +| id | target | status | +| ---------------------- | ------------------------------------- | ----------- | +| `title-card` | `video/scenes/title-card/*` | not-started | +| `end-card` | `video/scenes/end-card/*` | not-started | +| `brand-title` | `video/shared/brand-title/*` | not-started | +| `council-ring` | `video/shared/council-ring/*` | not-started | +| `stat-counter` | `video/shared/stat-counter/*` | not-started | +| `synthetic-disclaimer` | `video/shared/synthetic-disclaimer/*` | not-started | +| `heatmap-overlay` | `video/shared/heatmap-overlay/*` | not-started | +| `transformation-morph` | `video/scenes/transformation/*` | not-started | +| `recovery-arc-tone` | `video/scenes/recovery-arc/*` | not-started | + +Status values: `not-started` → `baseline` → `packet-built` → `polished` → `applied`. Update inline as work progresses. + +## Operating rules (project-specific) + +- Conventional commits: `feat(video):`, `chore(video):`, `fix(video):`, `docs(video):` +- Every commit goes through husky pre-commit (type-check + lint + format). Don't bypass with `--no-verify`. +- New skill scripts must be Bun-idiomatic: `bun scripts/.ts` not Node. +- HyperFrames determinism contract: every GSAP timeline must be `{ paused: true }` and registered on `window.__timelines`. Catch missing registrations via `render-still.ts` before full render. +- Frame budget: full render ≤8 min on M-series. If exceeded, drop heatmap-overlay effect on RecoveryArc + FinalState. diff --git a/context/webster-video/STATUS.md b/context/webster-video/STATUS.md new file mode 100644 index 0000000..ae7cc93 --- /dev/null +++ b/context/webster-video/STATUS.md @@ -0,0 +1,43 @@ +# webster-video — STATUS + +## Phase + +`polish-bundle-ready` + +## Latest action + +2026-04-26 — Layout restructured per Richie review: desktop-only (mobile screenshots dropped), full LP scrolling top-to-bottom per scene, LP centered up top, analytics + narrative panel below, week-evolution shown as paired "last week | this week" cards with explicit "Data said / Council decided / Outcome" framing. shared.css rev 2: dropped `.screenshot-card`, `.week-chip`, `.callout-chip`, `.heatmap-overlay`, `.heatmap-pass-chip`, `.council-ring*`, `.stat-counter*`. Added `.lp-pair-stage` (centered flex row, top zone), `.lp-week-block` + `.lp-week-label` + `.lp-week-label__chip` (current/dim/final variants) + `.lp-card` (860×600 viewport with overflow hidden) + `.lp-card--dim` (saturate 0.5 brightness 0.94 for failure-week visual cue) + `.lp-image` (absolute-positioned, GSAP translateY for scroll), `.narrative-panel` (bottom band 280h with 80px side padding) + `.narrative-col` + decision/outcome variants + `.narrative-eyebrow` + `.narrative-body` + `.narrative-stat` (with --small variant for two-value displays). 5 mid-scenes rewritten: before-state (w00 solo, baseline narrative), transformation (w01|w02, council's first transformation), learning-beat (w03|w04, experiment + correction), recovery-arc (w08 dim | w09, failure + recovery), final-state (w00 dim | w10, full-arc bookend). LP scroll distances hardcoded per week from native 1440-wide screenshot heights (526/2162/3362/3414/3727/3671/3599/3587 px). Linear ease across full scene minus 2s entry buffer — w00's short height creates intentional slow scroll versus dense w10's fast scroll, telling the "page grew rich over 11 weeks" story visually. Counter ramps preserved on transformation (151→343) and final-state (151→323). + +## Blockers + +(none) + +## Render history + +- **2026-04-26 — silent render**: `demo-output/videos/webster-lp-demo.silent.mp4`. 130.0s, 1920×1080, h264, 30fps, ~10 MB. `hyperframes render -q high --strict` with 6 parallel workers, ~58s wall. Compiler warned non-blocking on `var(--brand-font-utility)` (IBM Plex Sans Condensed not in HyperFrames' deterministic font cache; Google Fonts CDN renders correctly anyway — confirmed in snapshots). + +## Day log + +- **2026-04-26 — Day 0 / step 1 — tracking-set**: Plan approved at `~/.claude/plans/u-decide-whats-optimal-structured-spindle.md`. Created `context/webster-video/CONTEXT.md` (compaction-resistant) and this STATUS.md. Working branch: `feat/webster-video-skill` off `dev`. +- **2026-04-26 — Day 0 / step 2 — assets-hydrated**: Wrote `skills/webster-video/scripts/hydrate-demo-assets.ts` (Bun + Node fs APIs). Run produced 11 weeks under `demo-output/landing-page/wNN/`. Note: w00 has no `visual-review.md` (it's the baseline before any council action) — script handles as optional. Removed empty `demo-output/landing-page/week-NN/` leftovers (just `.DS_Store`). +- **2026-04-26 — Day 0 / step 3 — assets-committed**: Two commits on `feat/webster-video-skill` (off `dev`): `0fdd9c6 chore(video): add tracking dir` (CONTEXT.md + STATUS.md, 100 insertions) and `042e16b feat(video): hydrate 11 weeks of LP demo assets + add hydrate script` (103 files, 9710 insertions, ~39 MB binary). Updated `.gitignore` to ignore `local-runs/` and `audio/*.raw.mp3` on this branch. +- **2026-04-26 — Day 1 / step 1 — hyperframes-bootstrapped**: `skills` CLI installed globally. `skills add heygen-com/hyperframes` cloned the heygen-com/hyperframes repo (11k stars on github) and installed 5 sub-skills. `hyperframes init video --example blank` scaffolded the project. HyperFrames CLI exposes: init/lint/inspect/preview/render/transcribe/tts/doctor/browser. **`tts` and `transcribe` replace ElevenLabs + Whisper from the original plan** — fewer external dependencies. Visual style decision: Swiss Pulse + brand-overlay (warm cream / deep teal / leaf green / soft gold). +- **2026-04-26 — Day 1 / step 2 — script-drafted**: `video/script.md` authored — 130s narration, 7 timed beats, ~155 words at deliberate pacing. Honesty checklist included: synthetic-data qualifier on every metric callout; pitch frames as "weekly evidence loops" not "AI made a prettier landing page"; w08 framed honestly as "underperformed" without doom; w09 framed as "council corrected" without celebration. +- **2026-04-26 — Day 1 / step 3 — data-drafted**: `video/data/{metrics,brand,council}.json` + `video/lib/{easings,trim-points}.js`. metrics.json includes verbatim per-week CSV from prompt lines 78–91 + headline metric + anchor weeks. brand.json mirrors `demo-output/landing-page/brand.json` with CSS-variable map for direct injection. council.json lists the 10 sim agents (planner, monitor, seo, brand-voice, conversion, copy, fh-compliance, visual-asset-director, redesigner, visual-reviewer) with model labels for color coding. trim-points.js defines the 90s social-cut frame ranges. +- **2026-04-26 — Day 1 / step 4 — components-drafted**: `video/shared.css` — single source for brand tokens, type primitives (`brand-title--xl/lg/md`, `brand-subline`), 5 reusable component classes (`synthetic-disclaimer`, `stat-counter` + value/label/delta variants, `heatmap-overlay`, `council-ring` + agent positioning, `brand-title`), and scene primitives (`scene`, `callout-chip`, `screenshot-card`, `week-chip`, `heatmap-pass-chip`). +- **2026-04-26 — Day 1 / step 5 — scenes-drafted**: 7 sub-compositions in `video/compositions/`, master in `video/index.html` sequencing them via `data-composition-src` at 0/12/28/48/70/98/118s. Track-index conflicts resolved (mobile screenshots and second-week chips moved to higher tracks). GSAP transform conflict in learning-beat fixed via `xPercent: -50` instead of `transform: translateX(-50%)` per linter guidance. `video/assets` symlinked to `../demo-output/landing-page` so HyperFrames serves committed weekly artifacts. +- **2026-04-26 — Day 1 / step 6 — draft-rendered**: `npx hyperframes lint` returns 0/0; `npx hyperframes inspect` returns 0 layout issues across 9 timeline samples; `npx hyperframes snapshot --at 6,20,38,58,84,108,124` rendered 7 PNGs in `video/snapshots/` (gitignored). Recovery-arc transition gap at master t=84 is a ~0.2s crossfade window — acceptable for video, not a defect. Title-card, before-state, transformation, learning-beat (resampled at 58s), recovery-arc (resampled at 80s and 92s), final-state, end-card all render with full content + correct brand styling. +- **2026-04-26 — Day 2 / step 1 — polish-applied**: 8 files edited (`shared.css` full rewrite + 7 scene scripts). Polish targets from plan addressed via direct in-repo edits rather than Claude-Design slot-packet ceremony — saves 3h Day 2 budget. Confirmation-gate answers: (1) confirmed; (2) Richie records over silent render → Auphonic → mux; (3) skip-to-day-2. +- **2026-04-26 — Day 2 / step 2 — silent-rendered**: `hyperframes render -o ../demo-output/videos/webster-lp-demo.silent.mp4 -q high --strict` produced a clean 130s 1920×1080 30fps h264 mp4 in ~58s wall (6 parallel workers). 7 polished snapshots verified visuals before render: title-card mask-reveal, before-state callout overshoot stagger, transformation w01 mid-morph at frame 36s with counter at 294, learning-beat split with arrow, recovery-arc w09 + 330 + "Signal preserved", final-state with PASS chip + heatmap building, end-card with editorial close. +- **2026-04-26 — Day 2 / step 3 — mux-script-ready**: `skills/webster-video/scripts/mux-narration.ts` written (replaces planned `auphonic-process.ts` — uses ffmpeg loudnorm `-16 LUFS` + bandpass 80–12k Hz instead of Auphonic API, avoiding the API-key dependency). Detects `audio/narration.raw.{wav,mp3,m4a}`, levels → `audio/narration.mp3`, muxes silent mp4 + leveled audio → `demo-output/videos/webster-lp-demo.mp4` via stream-copy video + AAC 192k audio. `--skip-level` flag for users who pre-level via Auphonic. Uses `execFileSync` (not shell-concat) to avoid command-injection risk per security hook. +- **2026-04-26 — Day 2 / step 4 — rebuilt-paired-lps**: User feedback on first silent render: drop mobile, show full LP scrolling top-to-bottom, center the LP, place analytics below, narrate the data-said/council-decided/outcome story there, show week evolution as paired last-week-vs-current-week. shared.css rev 2 + 5 mid-scene rewrites (before-state, transformation, learning-beat, recovery-arc, final-state). title-card and end-card unchanged. Pair scheme: w00 solo / w01|w02 / w03|w04 / w08|w09 / w00|w10 (final bookends w00 against w10 for the dramatic arc recap). Scroll distances hardcoded from `sips -g pixelHeight` of each `demo-output/landing-page/wNN/desktop.png` at 860w display width. `hyperframes lint`: 0/0. 7 scene-midpoint snapshots verified visuals before re-render. +- **2026-04-26 — Day 2 / step 5 — silent-rendered (rev 2)**: `hyperframes render -q high --strict` produced `demo-output/videos/webster-lp-demo.silent.mp4` — 130.0s, 1920×1080, h264, 30fps, **71 MB** (file size grew because paired-LP layout has more pixel diversity per frame than the simpler v1 layout). 1m 36s wall with 6 parallel workers. +- **2026-04-26 — Day 2 / step 6 — polish-bundle-ready**: User chose single-shot Claude Design polish before audio. Wrote `skills/webster-video/scripts/build-slot-packets.ts` and `skills/webster-video/scripts/apply-polish-bundle.ts`. Generated 7 polish-slot packets at `skills/webster-video/polish-slots//` (title-card, before-state, transformation, learning-beat, recovery-arc, final-state, end-card). Each has `slot.json` (master frame range, dimensions), `brand.tokens.json` (palette + typography + motion + honesty constraints), `baseline.html` (current scene), `baseline.css` (full shared.css), `baseline.png` (mid-scene snapshot), `acceptance.md` (what "done" looks like), `DO_NOT_TOUCH.md` (locked text/numbers/durations/honesty framing/HyperFrames contract). Plus top-level `README.md` (workflow) and `PROMPT.md` (claude.ai/design system prompt). Bundle zipped to `skills/webster-video/polish-slots.zip` (1.3 MB) — gitignored. `.gitignore` updated to ignore `**/handoff/` and the zip. `apply-polish-bundle.ts` reads `/handoff/index.html` (full replacement of scene HTML) and optional `handoff-shared/shared.css` (full replacement of shared.css), runs `hyperframes lint`, prints next steps for re-render. + +## Pending + +- **Claude Design polish (single-shot, in flight)**: upload `skills/webster-video/polish-slots.zip` (1.3 MB) to **claude.ai/design** with `polish-slots/PROMPT.md` as the system prompt. Iterate per slot. Save returned bundles to `skills/webster-video/polish-slots//handoff/index.html` (and optional `handoff-shared/shared.css`). Run `bun skills/webster-video/scripts/apply-polish-bundle.ts` to integrate. Re-render after. +- After polish: Richie records narration over the polished silent mp4 → `audio/narration.raw.{wav,mp3,m4a}` +- Run `bun skills/webster-video/scripts/mux-narration.ts` (auto-levels via ffmpeg loudnorm + muxes → `demo-output/videos/webster-lp-demo.mp4`) +- Optional: Auphonic-grade audio polish (manual upload at auphonic.com → save to `audio/narration.mp3` → re-run with `--skip-level`) +- Optional: captions via `hyperframes transcribe audio/narration.mp3` + ffmpeg subtitle burn-in diff --git a/demo-output/landing-page/agents.json b/demo-output/landing-page/agents.json new file mode 100644 index 0000000..e5db114 --- /dev/null +++ b/demo-output/landing-page/agents.json @@ -0,0 +1 @@ +{"local-lp-planner":{"description":"Plans the next local Richer Health LP simulation week from only the isolated run sandbox.","prompt":"You are Webster's LP simulation planner.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nPlanning protocol for Opus:\n\n1. Read previous-week `analytics.json`, current page, brand context, personas, landing-page context when present, and same-run history only. For weeks after w01, inspect prior local decisions, heatmaps, visual reviews, and analytics deltas before choosing the next hypothesis. Avoid optional reads once you have enough evidence to write the plan.\n2. Treat analytics as the mock 5000-user panel in the same shape Webster would collect/ingest. Use concrete values such as bounce_rate, cta_clicks, scroll depth, persona_metrics, section_engagement, and heatmap evidence when available.\n3. Decide whether the data points to a narrow fix, a broader design exploration, or a validation/cleanup week. Do not assume every week should add sections or make the page longer.\n4. Compare current page state to onboarding context, personas, design_direction, analytics friction, and prior experiment outcomes.\n5. Identify the highest-leverage hypothesis for this week: what user behavior should change, why the current page causes friction, and what kind of intervention is most likely to move the metric.\n6. If landing-page context exists, enforce one-offer focus. Ask whether each recommended section supports the primary offer and primary conversion. Do not recommend unrelated program cards, homepage-style offer directories, or multiple equal CTAs unless the landing-page context explicitly permits them.\n7. Give the redesigner decision context, not a rigid layout order. Name the business gap, target persona, likely page region, metric target, useful assets, and constraints. Let the redesigner choose the best implementation.\n8. Watch for long-term drift: if prior weeks show added complexity hurting scroll, conversion, visual review, or heatmap focus, recommend consolidation instead of expansion. If the page is already section-heavy by later weeks, only recommend more sections when the analytics/heatmap evidence strongly supports it.\n9. Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n10. Write an evidence-rich plan artifact. Include concrete metrics, a primary hypothesis, viable intervention lanes, risks, and what would count as success next week. Do not over-control pixel-level design unless a constraint is safety/compliance/analytics-critical.\n\nOutput the plan artifact requested by the parent prompt with classification, next_action, direction_hint, rationale, metric hypothesis, useful context, risks, and constraints for critics/redesigner.","tools":["Read","Write"],"model":"opus","permissionMode":"acceptEdits","maxTurns":4},"local-lp-monitor":{"description":"Infers analytics and persona friction for the isolated local LP simulation week.","prompt":"You are Webster's LP analytics monitor.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nHaiku protocol:\n\n- Stay narrow and fast. Read previous-week `analytics.json` first, then current HTML; read CSS/context only if needed.\n- Treat `analytics.json` as the mock 5000-user panel in the same shape Webster would collect/ingest (`sessions`, `bounce_rate`, `scroll_depth_*`, `cta_clicks`, `persona_metrics`, `section_engagement`, `events`).\n- Infer likely bounce, scroll-depth, CTA-click, persona mismatch, and section-engagement risks by combining analytics deltas with current static page evidence.\n- Use concrete analytics values and page evidence.\n- Max 5 anomaly bullets.\n- Do not propose design fixes; explain signals for the council.\n- Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n\nWrite the monitor artifact requested by the parent prompt.","tools":["Read","Write"],"model":"haiku","permissionMode":"acceptEdits","maxTurns":3},"local-lp-seo":{"description":"Reviews technical discoverability for the isolated local Richer Health LP simulation week.","prompt":"You are Webster's LP SEO critic.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nSonnet critic protocol:\n\n- Read only the minimum needed files: current HTML, current CSS if needed, and local context if needed. Write the finding before spending turns on optional reads.\n- Own only metadata, heading structure, semantic HTML, internal links, image alt text, and search-result shareability.\n- Quote exact local page evidence for every issue.\n- Max 6 issues.\n- Use severity tags exactly: CRITICAL, HIGH, MEDIUM, LOW.\n- Put non-SEO concerns under Out of scope.\n- Do not fix issues.\n- Do not invent or recommend live domains, canonical URLs, campaign domains, `LP_TARGET`, or production hostnames. If the sandbox context contains `LOCAL_SANDBOX_CAMPAIGN`, treat it as a placeholder and write `LOCAL_SANDBOX_CAMPAIGN`, not a real URL.\n\nWrite the SEO findings artifact requested by the parent prompt.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":3},"local-lp-brand-voice":{"description":"Reviews voice, brand system, palette, typography, and design-direction adherence for the isolated local LP week.","prompt":"You are Webster's LP brand-voice critic.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nSonnet critic protocol:\n\n- Read only the minimum needed files: current HTML, current CSS, and brand context. Write the finding before spending turns on optional reads.\n- Own only voice, tone, design_direction adherence, palette, typography intent, signature phrases, forbidden phrases, and brand-rule adherence.\n- Quote exact local page/CSS evidence for every issue.\n- Max 6 issues.\n- Use severity tags exactly: CRITICAL, HIGH, MEDIUM, LOW.\n- Put non-brand concerns under Out of scope.\n- Do not fix issues.\n- Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n\nBrand visual rule: follow the current `brand.json` design direction, palette, typography, and avoid list. If the dominant page impression contradicts that context, mark HIGH severity.\n\nWrite the brand-voice findings artifact requested by the parent prompt.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":3},"local-lp-conversion":{"description":"Reviews CTA clarity, trust placement, and persona conversion triggers for the isolated local LP week.","prompt":"You are Webster's LP conversion critic.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nSonnet critic protocol:\n\n- Read only the minimum needed files: current HTML, current CSS if CTA visibility matters, and persona context if needed. Write the finding before spending turns on optional reads.\n- Own only CTA clarity, booking friction, trust-signal placement, social proof proximity, persona conversion triggers, and decision-point clarity.\n- Quote exact local page evidence for every issue.\n- Max 6 issues.\n- Use severity tags exactly: CRITICAL, HIGH, MEDIUM, LOW.\n- Put non-conversion concerns under Out of scope.\n- Do not fix issues.\n- Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n\nWrite the conversion findings artifact requested by the parent prompt.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":3},"local-lp-copy":{"description":"Reviews specificity, headline strength, skim structure, and persuasion for the isolated local LP week.","prompt":"You are Webster's LP copy critic.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nSonnet critic protocol:\n\n- Read only the minimum needed files: current HTML and local brand/persona context if needed. Write the finding before spending turns on optional reads.\n- Own only specificity, headline strength, skim structure, benefit clarity, objection handling, phrase-level persuasion, and whether copy serves the selected design direction.\n- Quote exact local page text for every issue.\n- Max 6 issues.\n- Use severity tags exactly: CRITICAL, HIGH, MEDIUM, LOW.\n- Put non-copy concerns under Out of scope.\n- Do not fix issues.\n- Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n\nWrite the copy findings artifact requested by the parent prompt.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":3},"local-lp-fh-compliance":{"description":"Reviews health-claim restraint and credential clarity for the isolated local LP week.","prompt":"You are Webster's food/health compliance critic for the local LP.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nSonnet critic protocol:\n\n- Read only the minimum needed files: current HTML and local business/brand context if needed. Write the finding before spending turns on optional reads.\n- Own only health-claim restraint, credential clarity, disclaimer placement, non-diagnostic wording, and avoiding medical promises.\n- Quote exact local page evidence for every issue.\n- Max 6 issues.\n- Use severity tags exactly: CRITICAL, HIGH, MEDIUM, LOW.\n- Put non-compliance concerns under Out of scope.\n- Do not fix issues.\n- Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n\nThe page may say education, training, and certification. It must not imply diagnosis, treatment, cure, guaranteed results, or physician replacement.\n\nWrite the compliance findings artifact requested by the parent prompt.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":3},"local-lp-visual-asset-director":{"description":"Curates approved visual assets per landing-page slot, inspects image quality, and writes structured asset assignments for the redesigner.","prompt":"You are Webster's visual asset director.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, `.env`, keychain, shell git, or external image generation APIs.\n\nYour job is runtime curation and image inspection, not asset generation.\n\nBefore judging assets, read these skill references:\n\n- `.claude/skills/webster-visual-assets/references/runtime-council-usage.md`\n- `.claude/skills/webster-visual-assets/references/image-quality-rubric.md`\n- `.claude/skills/webster-visual-assets/references/manifest-contract.md`\n- `.claude/skills/webster-visual-assets/references/brand-style-context.md`\n\nProtocol:\n\n1. Read `asset-manifest.json`, current page files, brand context, and the current-week plan when present. Avoid optional reads once you have enough evidence to write verdicts.\n2. Identify likely page slots: hero, founder/trust, proof, services, section illustration, process diagram, footer/supporting proof.\n3. Inspect the actual candidate image files with `Read` before recommending them. Do not rely on filenames, alt text, dimensions, or manifest metadata alone.\n4. Score each serious candidate by brand fit, subject match, visual quality, rights/likeness safety, and slot fit.\n5. Treat `approved: false` and non-empty `rejected_for` as hard no-use gates unless a documented override exists.\n6. Reject assets that fail quality or rights gates. Better to leave a slot open than to recommend a weak or unsafe asset.\n7. Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n8. Write one structured finding file: `{{RUN_ROOT}}/history/{{WEEK}}/findings/visual-assets.md`.\n\nQuality gates:\n\n- Image-read gate: if the image cannot be read, reject it.\n- Brand-fit gate: reject or swap assets that fight the current brand context's palette, design direction, tone, or trust requirements.\n- AI artifact gate: reject visible fake text, fake logos, malformed people, bad perspective, mushy details, or generic AI gloss.\n- Rights/likeness gate: reject AI-generated people/faces unless the manifest says `approved_for_likeness: true`.\n- Slot-fit gate: reject assets too small or badly shaped for their intended slot.\n\nOutput exactly this structure:\n\n# Visual Asset Director — {{WEEK}}\n\n## Slot assignments\n\n| slot | asset_path | tier | verdict | confidence | rationale |\n| ---- | ---------- | ---- | ------- | ---------- | --------- |\n\n## Quality verdicts\n\n| asset_path | verdict | reason |\n| ---------- | ------- | ------ |\n\n## Rejected assets\n\n- `path` — reason\n\n## Open slots\n\n- `slot` — ideal asset needed — defer/generate later\n\nVerdicts must be one of `use`, `swap`, or `reject`. Only `use` assets are safe for the redesigner to place without an override.","tools":["Read","Write"],"model":"sonnet","permissionMode":"acceptEdits","maxTurns":6},"local-lp-redesigner":{"description":"Synthesizes local LP council findings into one plausible weekly redesign inside the isolated sandbox.","prompt":"You are Webster's LP redesigner.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nOpus synthesis protocol:\n\n1. Read current page, onboarding context, landing-page context when present, asset manifest, same-run history, plan, current-week findings, and prior visual/analytics outcomes when present. Avoid optional reads once synthesis evidence is sufficient.\n2. Treat the planner's artifact as strategic context and hypotheses, not a rigid wireframe. You own the final design decision and implementation.\n3. Rank possible interventions by expected user-behavior impact, brand fit, visual credibility, compliance safety, implementation feasibility, and week-over-week learning value.\n4. Choose the smallest coherent change set that can actually move the targeted metric. This may be one strong system-level intervention (e.g. hero + typography + palette) rather than several timid text edits. Do not fix everything.\n5. Preserve continuity of story and section identity, not necessarily weak template styling. If inherited styling is the reason users distrust the page, replace the styling. If inherited structure helps the timelapse read clearly, keep it.\n6. If landing-page context exists, treat it as the offer contract. Design one page for one offer and one primary conversion. Do not turn the page into a homepage, program marketplace, or directory of unrelated offers. Convert supporting sections into proof, explanation, and objection-handling for the primary offer.\n7. For early weeks, make the page meaningfully better while leaving obvious future work. A weak baseline should evolve into a credible page, not into a slightly-less-weak template. Mobile horizontal overflow is never acceptable: if existing grids/cards overflow at 375px, add the smallest responsive rule needed to stack them.\n8. For later weeks, use past analytics, heatmaps, and visual reviews to decide whether to expand, consolidate, or refine. Do not add sections by habit; add them only when they answer a demonstrated friction point.\n9. Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n10. Write complete artifacts and edited week files. Make deferred work explicit.\n\nHard visual constraint: follow the current brand context for palette, visual direction, tone, typography, and avoidance rules. Do not override the supplied brand context with generic defaults. For the Richer Health LP, a credible w01 may replace template typography and page color if the current visual system is part of the trust problem.\n\nAnalytics continuity contract: preserve or add stable instrumentation anchors when editing the page:\n\n- main hero region: `data-webster-section=\"hero\"`\n- trust/proof/about region: `data-webster-section=\"proof\"`\n- services/cards region: `data-webster-section=\"services\"`\n- contact/form region: `data-webster-section=\"contact\"`\n- primary discovery CTA: `data-webster-cta=\"discovery_call\"`\n\nDo not remove these anchors unless replacing them with semantically equivalent anchors and documenting the change in `proposal.md`.\n\nAsset policy: inspect `asset-manifest.json` before adding visual treatments. Prefer approved real source assets for founder/proof, deterministic SVGs for conceptual diagrams, and approved Tier 3 AI-generated assets for editorial section imagery only when they solve a specific page slot. Do not call external image APIs or read `.env`. If the selected w01 move is a founder-led hero and the visual asset director marks an approved founder photo as `use`, do not defer that photo merely to keep the page weak; use it unless there is a concrete quality, rights, or layout reason not to.\n\nFor image/asset decisions, use these skill references as needed:\n\n- `.claude/skills/webster-visual-assets/references/runtime-council-usage.md`\n- `.claude/skills/webster-visual-assets/references/image-quality-rubric.md`\n- `.claude/skills/webster-visual-assets/references/brand-style-context.md`\n\nBefore placing any `` or image-like visual asset:\n\n1. Read the current-week `findings/visual-assets.md` file.\n2. Use only assets with verdict `use`.\n3. Do not use assets marked `swap` or `reject`.\n4. If no asset passes for a slot, omit the image rather than forcing a bad one.\n5. If you override the visual asset director, document the override in `proposal.md` under `Asset overrides` with a clear reason.\n6. If `visual-assets.md` is missing, inspect candidate image files yourself with `Read` before using them.\n\nTimeout-resilient write order:\n\n1. Write `proposal.md`, `decision.json`, and `patches.json` first.\n2. Then write complete `weeks/{{WEEK}}/index.html` and `weeks/{{WEEK}}/style.css` in the smallest number of Write/Edit calls possible.\n3. Avoid exploratory reads after artifact drafting starts.\n4. If the page edits are large, prefer complete file Write operations over many small edits.\n\nWrite the proposal, decision JSON, patches JSON, and edited week site files requested by the parent prompt.","tools":["Read","Write","Edit","MultiEdit","Bash"],"model":"opus","permissionMode":"acceptEdits","maxTurns":14},"local-lp-visual-reviewer":{"description":"Reviews local LP weekly output for visible intent, breakpoint safety, brand drift, and continuity.","prompt":"You are Webster's LP visual reviewer.\n\nUse only the local run sandbox paths supplied in the parent prompt. Do not inspect old demo outputs, repository-level history, salvage files, live URLs, WebFetch, GitHub MCP, Managed Agents APIs, keychain, or shell git.\n\nOpus review protocol:\n\n1. Review the current week's page files, proposal, decision, screenshot images, and `screenshots/{{WEEK}}/summary.json` if present. Avoid optional reads once visual evidence is sufficient.\n2. Verify proposal intent landed visibly, not just in markup.\n3. Check desktop, tablet, and mobile for overflow, clipped text, missing CTA, unreadable contrast, and brand palette drift. Treat any `horizontal_overflow: true` in `summary.json` as BLOCK unless the proposal explicitly selected an overflow fix deferral and no user-visible content is clipped.\n4. Check continuity: a weekly pass should look like evolution from the previous page, not a replacement with a final mock.\n5. Do not invent or mention live domains, campaign domains, `LP_TARGET`, or production hostnames. If present, `LOCAL_SANDBOX_CAMPAIGN` is a local placeholder only.\n6. Return PASS or BLOCK with evidence and concrete fix hints.\n\nWrite the visual review artifact requested by the parent prompt.","tools":["Read","Write"],"model":"opus","permissionMode":"acceptEdits","maxTurns":4}} diff --git a/demo-output/landing-page/brand.json b/demo-output/landing-page/brand.json new file mode 100644 index 0000000..bea788f --- /dev/null +++ b/demo-output/landing-page/brand.json @@ -0,0 +1,52 @@ +{ + "design_direction": { + "selected": "premium_clinical_institute_founder_led", + "label": "Premium clinical institute, founder-led", + "rationale": "The LP must move away from generic wellness coaching toward a high-trust clinical education institute anchored by Nicolette's founder authority.", + "visual_targets": [ + "serious and premium without becoming hospital-sterile", + "founder authority visible above the fold by the mature state", + "restrained proof, credentials, and booking hierarchy instead of content clutter", + "deep editorial contrast with warm human details" + ], + "avoid": [ + "spa retreat", + "generic wellness blog", + "loud internet-course funnel", + "cold hospital system" + ] + }, + "voice": "Warm-authoritative with deliberate edge: trusted mentor, not vendor; clinically credible without sounding sterile.", + "tone": ["confident", "direct", "personable", "evidence-aware", "professionally provocative"], + "palette": { + "deep_teal": "#0F4C5C", + "warm_cream": "#F7F1E8", + "leaf_green": "#3F7D58", + "charcoal": "#243034", + "soft_gold": "#C8A96A" + }, + "typography": { + "heading": "Editorial serif such as Cormorant Garamond or Playfair Display", + "body": "Readable humanist sans such as Inter or Source Sans 3", + "utility": "Condensed sans for labels and credentials" + }, + "signature_phrases": [ + "Your body's ability to heal is greater than anyone has permitted you to believe.", + "N&D certification", + "I've been in the trenches", + "food-as-medicine", + "trusted mentor, not vendor" + ], + "do_not_use": [ + "MN&D", + "medical doctor", + "cure", + "miracle", + "guaranteed results", + "wellness guru", + "quick fix", + "detox cleanse", + "world-class", + "revolutionary" + ] +} diff --git a/demo-output/landing-page/manifest.json b/demo-output/landing-page/manifest.json new file mode 100644 index 0000000..2851936 --- /dev/null +++ b/demo-output/landing-page/manifest.json @@ -0,0 +1,557 @@ +{ + "source_run": "local-runs/lp-council/w01-single-offer-visual-heatmap", + "generated_at": "2026-04-26T13:00:12.425Z", + "weeks": [ + { + "week": "w00", + "files": [ + { + "name": "desktop.png", + "bytes": 177470, + "sha256": "49babf6d7725f04f2379bcf9a2c953c58e1e626ac1c4428f94adbe709a981be5" + }, + { + "name": "mobile.png", + "bytes": 162625, + "sha256": "4e68109a4f74b364cfcc06b69b1ad5c74c0e227428b1a981411e83505e5f5625" + }, + { + "name": "tablet.png", + "bytes": 164993, + "sha256": "af8cd42e871b5440e6b4ea654ec46287a13c4ace8a6fd1320219cd62251b9395" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 1629, + "sha256": "f95832fe64cb204bd56313c52298a363914256493f38b3d9db89118185236402" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 1611, + "sha256": "632c0a49253fa9748c0f54b4abea1513826ccf65d1607fc0db2528ed4efc4376" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 1611, + "sha256": "26e357f2b10a18149cf13f6d5fdd2b7699525be8c76df30619c5178bf0997001" + }, + { + "name": "analytics.json", + "bytes": 2186, + "sha256": "21ed3e3740d0422287e01b5123ef06a51c52b9487486c26aa987dd46195507a1" + }, + { + "name": "heatmap.json", + "bytes": 7145, + "sha256": "895c5e07b4c9f23130cf7cec7aefb6cd55a28714a7f8dc9462e8366eecf47fe7" + } + ] + }, + { + "week": "w01", + "files": [ + { + "name": "desktop.png", + "bytes": 1306047, + "sha256": "a54491399399dbd0faf9c930aafc2b8251af48395f82f266bfa2293231cc1338" + }, + { + "name": "mobile.png", + "bytes": 735429, + "sha256": "ede2b482d00ebc038ac3f979dc4a7f5571faeda95739ac9c605c438553954f03" + }, + { + "name": "tablet.png", + "bytes": 1052705, + "sha256": "347e0f9af74371339f568108cafdb7aa710bf4a08135d9ea1ab292c631e15973" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 2976, + "sha256": "de338619499b9cd0e8be84623a1a021680cc634fabe3c5b6bcada7dc3fc7684e" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3000, + "sha256": "95120d3e8466a2746c13634a902184b99c8300e093983b287f8272e197b597b3" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 2985, + "sha256": "2042bafc4fb9aa2a493746c9f14d25c0403ff998b6783e1db976d51d61b4f8c1" + }, + { + "name": "analytics.json", + "bytes": 2267, + "sha256": "5b2c6767c7220283d6b81c08a3a3cc3c7766e95ec4210c27be9c4f6b4344f4c4" + }, + { + "name": "heatmap.json", + "bytes": 8679, + "sha256": "9db64648229fe4b0a2008de726dc709b8a425c5bd0eb7e46595abe1bdf9e1cc0" + }, + { + "name": "visual-review.md", + "bytes": 6404, + "sha256": "0622cd432c2cab97ac1a7f059f6e1c94841156f24f0623200b00a0a1437ffad4" + } + ] + }, + { + "week": "w02", + "files": [ + { + "name": "desktop.png", + "bytes": 1580470, + "sha256": "573aefec61121b7e1aecf6512a41da94ba4dd99b301105fb6aa49252f94e9746" + }, + { + "name": "mobile.png", + "bytes": 966845, + "sha256": "b99508c09a6954dbcb95940b51ad840a7a631dcaa4dc297064bf240eba61ad28" + }, + { + "name": "tablet.png", + "bytes": 1327392, + "sha256": "d442d296a68edd7b5be526a7d27250a872e393e18475bd7a944263070dde6d8c" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 2972, + "sha256": "48f8dbe0ea9c44ac49598317ddab2f8df3f8590bff13655b05b2fd0ff53fe286" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3350, + "sha256": "68951fb36d293666d13f007657d8088afbe94fb613f46505f3cc24f717aeac1f" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 2985, + "sha256": "b18df92323fd246c336f2678aae08b5fb2e0b512c2f3079085c2c4c9261b4fea" + }, + { + "name": "analytics.json", + "bytes": 2263, + "sha256": "4694ceb8822e3ab170ee0407ef91880cede090988309c82a2d34d31a73fb1e16" + }, + { + "name": "heatmap.json", + "bytes": 9079, + "sha256": "db2c7ba22835fc5c83a252f82b6771ba8abc674ce298c1ce8689d7f1f0b5790f" + }, + { + "name": "visual-review.md", + "bytes": 7169, + "sha256": "06384dfb4e0e809775c42cf4f74fd6aa34db82d1d2636be212f9d90e9f4b5de7" + } + ] + }, + { + "week": "w03", + "files": [ + { + "name": "desktop.png", + "bytes": 1590863, + "sha256": "7c9449d5ae6b0cf702db2d3a28fcf21f65928ae6a3a651851bf6041a97e9cd25" + }, + { + "name": "mobile.png", + "bytes": 977966, + "sha256": "e370f01a0b827af842db0fc3c31c6b50f2c9e048a81a14ff591fd283a72050fe" + }, + { + "name": "tablet.png", + "bytes": 1334778, + "sha256": "c9d67ce423ce7c696b558c59e63f09277829274a681d8fc8d720f6758ef92556" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 4082, + "sha256": "5ba9e5c6dd28d3bea532ed9cfdef22dc5d29037a7d8f7c091bf5f7f90da952c7" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 4099, + "sha256": "3b304d430c60feff3f02496b356d2322f86992b00b891d4e8c84255a7493e80b" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 4078, + "sha256": "3f4f48d3718e5a55739c1a5a3dee29c41721aff8a140a8005b5685a995a29cf0" + }, + { + "name": "analytics.json", + "bytes": 2264, + "sha256": "e9761c0863ee33389498490effc7651bf17e4a6f588145088606ede839e86f58" + }, + { + "name": "heatmap.json", + "bytes": 21039, + "sha256": "beb11977ab92035d9151f04226bc638196b10f510154e1db6bc40c60518524ae" + }, + { + "name": "visual-review.md", + "bytes": 8191, + "sha256": "2e9ac56a8a5d4a10b352809fd98394bb3597af40e90395b39af9451ea350fada" + } + ] + }, + { + "week": "w04", + "files": [ + { + "name": "desktop.png", + "bytes": 1671751, + "sha256": "0ae0655d67457a4693deb6f8494d274a3927cb8f60d072eac53e126eb172b479" + }, + { + "name": "mobile.png", + "bytes": 1027299, + "sha256": "080175eafdb5090c6c6354a1517424469814857abc3f5c99d40bc1c639f48c37" + }, + { + "name": "tablet.png", + "bytes": 1404355, + "sha256": "a7d59f3127d9ecd84440a6c98521ad2e2797f855445e4e50f803d7212bf4e1d3" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3336, + "sha256": "42db02c8639b069b553915798df347828f6c76fe250722b7a425ae6e565caea6" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3719, + "sha256": "e22086c1f03edd96f51fecde7d1f765281d290aff8b3ae320a71cda19e55406d" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3352, + "sha256": "dd622843ecd9f6266cabb8cf5ddaca86b46954cb282ad604edda0bebcad9e95f" + }, + { + "name": "analytics.json", + "bytes": 2267, + "sha256": "ed553fdba1002ec465e4dd0c7fc80906a31ec7c832c44bcf0012a42bef10b6a7" + }, + { + "name": "heatmap.json", + "bytes": 18015, + "sha256": "d38969b27ffd1acdb2e51f23a54c591af8684c61c3af54fb827b559cb4190a73" + }, + { + "name": "visual-review.md", + "bytes": 10562, + "sha256": "d71ed8cee5718e662036e88f9f0e449ce05648c2e42ac2bd99a77522d9982748" + } + ] + }, + { + "week": "w05", + "files": [ + { + "name": "desktop.png", + "bytes": 1691456, + "sha256": "072f594b2c1e8ae1719fb2e17976a91f5b0d1194d67c007f73caf1703cabedee" + }, + { + "name": "mobile.png", + "bytes": 1021140, + "sha256": "21b80dab0e9bf797354c59142aac8feebf5f6048071837f05ede19ab4ec94ff2" + }, + { + "name": "tablet.png", + "bytes": 1410026, + "sha256": "8168e22f8f351c296bc1b7eef5642518d627bbc58507e4f95dc8fa4e9e9cb8a2" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3340, + "sha256": "3b026a05facc78d9ad2caa72061a2dc14a2631ce34c9d3af375147aa1d727d08" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3729, + "sha256": "e7a69af89c1b5e33cde723b6bfaa21f76948e7b401fbfd7b56451a88785951f4" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3358, + "sha256": "7b932ff53616cd811351e95dba6ba6f785b0c805ba000732d42cfcd637cc7600" + }, + { + "name": "analytics.json", + "bytes": 2266, + "sha256": "185198088a2a02123d038c771fba9922b2eccaa9bd6248e6e2bcba85290b228d" + }, + { + "name": "heatmap.json", + "bytes": 18285, + "sha256": "11a58cc500c7c8febce865ee087bfe909ab1e4e3e709f0ea4b3f5fb8c42b3a63" + }, + { + "name": "visual-review.md", + "bytes": 6914, + "sha256": "55d769ce6f636046da5999c88ff0dcf96fab3a74ba7507fb1d6d2b1044618f96" + } + ] + }, + { + "week": "w06", + "files": [ + { + "name": "desktop.png", + "bytes": 1723367, + "sha256": "42c518caf9f60b3dba7be1f70a181c87e3793cef0af8620abfbdfef769cf12dd" + }, + { + "name": "mobile.png", + "bytes": 1048434, + "sha256": "290232bea2b5a25a6485f8ccac7d274972ed43cd06598d276effed3a7ed1ae08" + }, + { + "name": "tablet.png", + "bytes": 1440837, + "sha256": "0db059ed5aec7c759a3b30cdb92a4daca61a6138c392dfe04170e2392550b662" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3344, + "sha256": "dc0316d1121a1ac906a05b5c8391a48383b4a1ce7abf1bd040ccefbbed44785e" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3740, + "sha256": "421cea1606804869b2faa6b14fc204f17bbce561a4e799d49d62d5b920d1ef26" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3356, + "sha256": "9b0d0a75d2e22d907b7d02fc21ec776cc89883946c2e461e8cc624fe674ef056" + }, + { + "name": "analytics.json", + "bytes": 2268, + "sha256": "8a3a373171713f3272501b0197b62fe2fdcebb87d45440b5467e84de92908bd6" + }, + { + "name": "heatmap.json", + "bytes": 18293, + "sha256": "a30daea55ca66ff7487ec9fd2ae2579a6f2e0ed918ed05a9cd2b95f6db0ce435" + }, + { + "name": "visual-review.md", + "bytes": 5932, + "sha256": "ec16ff2a37e1eaaef04f5cefa3c7e10e24cd760edb4e16d4f5834996edcafc98" + } + ] + }, + { + "week": "w07", + "files": [ + { + "name": "desktop.png", + "bytes": 1679583, + "sha256": "1409d65d14c1637dcce54359eb635f8ed521dc9af2c9a17e4d7d0a5cacb0340e" + }, + { + "name": "mobile.png", + "bytes": 1010183, + "sha256": "958a1715d420107135e30e1e5da8d5d6eb0991dffd6353c60f13b19bdf7b5e0b" + }, + { + "name": "tablet.png", + "bytes": 1403248, + "sha256": "f02683a3d46234439f1b9cc6cba001d7388f10fbc0cb3ed41e3c5c4ee371cda3" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3348, + "sha256": "6b9ecc885923d3618d84864d0088b173d0f03a8a330f259002e86ccbbbe6d20d" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3734, + "sha256": "0e680ea3e3f37f036bdb1569f4cf4522ed46ac1b708d9cd55b37215241f72a25" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3356, + "sha256": "bb522cb233000655013ed86534ef7f4caf2a6003b68da8ee82b2e618618d9770" + }, + { + "name": "analytics.json", + "bytes": 2268, + "sha256": "c9381f674ea3b2f4aaff087790419e6b026f0ecee9dd6f24cffd94879d47686d" + }, + { + "name": "heatmap.json", + "bytes": 18273, + "sha256": "9c8d18455e76bf2470158dc2c600e5b2ecbc3427743a55df946f9e48a7b6b6d0" + }, + { + "name": "visual-review.md", + "bytes": 4060, + "sha256": "fbc20c01b736ceb864398767d50b92e32be07ceaf05aca88dcac05808b236b4b" + } + ] + }, + { + "week": "w08", + "files": [ + { + "name": "desktop.png", + "bytes": 1687128, + "sha256": "2b51d60f902172ad55b30aabc1d5d5d20bbfb1dd6865ca52de690ddc23861c5d" + }, + { + "name": "mobile.png", + "bytes": 1011210, + "sha256": "4b5ea6e64f8ceb09d68cf787457340a5563377291749d18cf8df6337febbc832" + }, + { + "name": "tablet.png", + "bytes": 1410217, + "sha256": "344d1deb6bbe2e451587a09a1a5e01c4ad1b6b0331488dfdbe44648595db011e" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3344, + "sha256": "c9863144c66f8bc90f850ddae5af60733a403a7471fdb3da0102cbfdf4bee5f9" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3734, + "sha256": "b8f7ddb39bde99f413fe162b5a99da0a1f1186d6c7e4beefc9b2b40aa9ff2fe9" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3356, + "sha256": "7ee74679e9fd1d6e8f84d03c30dd1d6670e7d001e015b3e059eac6629697bf99" + }, + { + "name": "analytics.json", + "bytes": 2269, + "sha256": "54027f99581d471a551f1d7ba18f475dcef89d46074b96bd15559c1af69a8fdc" + }, + { + "name": "heatmap.json", + "bytes": 18282, + "sha256": "23e718fe7964fba2b2a0e3d609776c88c0b33022a0815e430cac22a7f0b818b4" + }, + { + "name": "visual-review.md", + "bytes": 6061, + "sha256": "37686b0960c86feeb183c585bc0d6417ace1e5499f07f45f343dab1803270c8c" + } + ] + }, + { + "week": "w09", + "files": [ + { + "name": "desktop.png", + "bytes": 1682147, + "sha256": "ccc8a3e70a8025b627cf16f83bdf6b65a5f40f0c194f3bed41e4184c68383b0c" + }, + { + "name": "mobile.png", + "bytes": 1006605, + "sha256": "7fbc0d465c4efa5391a5941737f65b06aab139fea015b8d3739262cf8a925513" + }, + { + "name": "tablet.png", + "bytes": 1405628, + "sha256": "c7b3eb0a62223526a651fe423241ad050cd78cd24dc6cfb8e730424c11897ec7" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3348, + "sha256": "5068b6435c10e2a17e0efe5237fa6f65c46fd9e770e7e3df55a610f3142f8fff" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3734, + "sha256": "ad62c00c74ab8595126bf9cdb8e1dbc5894cc6400c7e936dcb9f88978aefc84e" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3356, + "sha256": "9d6ffacb00777f8a78ba8394bdf2cc5d20d8a36d2e168bb9d117cf972b255342" + }, + { + "name": "analytics.json", + "bytes": 2266, + "sha256": "2595ae8f76a72004fdf9d0ca50d99a580641dfd3218c952f5b3b711fd55229cd" + }, + { + "name": "heatmap.json", + "bytes": 18271, + "sha256": "d55202affacad023f6a72748d4699db98312f9c6c6a78087fc0b474aa8280759" + }, + { + "name": "visual-review.md", + "bytes": 6528, + "sha256": "334edff802d080ca83dc3e2275ca862c4b55a01735bdb6f9a6685f87995e6af3" + } + ] + }, + { + "week": "w10", + "files": [ + { + "name": "desktop.png", + "bytes": 1673429, + "sha256": "a2624e5448bffcc42e33f53060a18ec9574dc892ccf3994ea6b240f8f2a6a8dd" + }, + { + "name": "mobile.png", + "bytes": 1001914, + "sha256": "36c34709802cbbe4cb3441747749f327f79c52fa62dcb8b0692f0c11d664a0e2" + }, + { + "name": "tablet.png", + "bytes": 1401273, + "sha256": "e6ac8a4fe491026c904b6cd36c166ac8ecbd9528d75a69e5dcfc466d790ca81e" + }, + { + "name": "desktop-heatmap.svg", + "bytes": 3347, + "sha256": "5e61c1df6788ebe65c7d3eb5cdaba0c0bd19f74b27f663dde8c8d949aa29ed40" + }, + { + "name": "mobile-heatmap.svg", + "bytes": 3732, + "sha256": "d6c0312302585b08e64fe66796bdf28d9c50eaf99823db347ac602f289e09550" + }, + { + "name": "tablet-heatmap.svg", + "bytes": 3356, + "sha256": "e611ab07398b23ed50943d7330def0e44f473f77080f48efd1644cb7dd53451b" + }, + { + "name": "analytics.json", + "bytes": 2266, + "sha256": "222b3abed39f1fd306506224b0e41a62f2fc7e2997f2d1f7a1fcc31cc92fc5b9" + }, + { + "name": "heatmap.json", + "bytes": 18271, + "sha256": "4fa039b555ff6d31f586fc15d7bc5b70a2f80c8f0254c76a73abbeb9c696d391" + }, + { + "name": "visual-review.md", + "bytes": 3766, + "sha256": "0e05b470fc96f6863ccaccc67cb2e42a4832f3a47f25958c8a3aeadf2e80f8f2" + } + ] + } + ], + "brand": { + "sha256": "3787c1654292a3af415b78d38a3f9903cbe11efa3e78090ca0ebb1f64c88ca5f" + }, + "agents": { + "sha256": "859ead1550a642b4d5d4cbd599a461b1ddc12847243d6deeeb75cf855ce0049d" + } +} \ No newline at end of file diff --git a/demo-output/landing-page/w00/analytics.json b/demo-output/landing-page/w00/analytics.json new file mode 100644 index 0000000..5e3b87c --- /dev/null +++ b/demo-output/landing-page/w00/analytics.json @@ -0,0 +1,98 @@ +{ + "version_sha": "synthetic-lp-w00-b55b71f1", + "site_signature": "f743fee0", + "substrate": "lp", + "week": 0, + "weekDate": "2026-02-01", + "sessions": 5044, + "bounce_rate": 0.63, + "avg_time_s": 92.8, + "scroll_depth_25": 0.787, + "scroll_depth_50": 0.599, + "scroll_depth_75": 0.388, + "scroll_depth_100": 0.181, + "cta_clicks": { + "discovery_call": 151 + }, + "persona_metrics": [ + { + "persona_id": "credentials-conscious-executive", + "sessions": 1866, + "bounce_rate": 0.612, + "cta_clicks": 57, + "avg_time_s": 94.5 + }, + { + "persona_id": "curious-self-starter", + "sessions": 1715, + "bounce_rate": 0.63, + "cta_clicks": 51, + "avg_time_s": 92.8 + }, + { + "persona_id": "skeptical-researcher", + "sessions": 1463, + "bounce_rate": 0.648, + "cta_clicks": 43, + "avg_time_s": 91.1 + } + ], + "section_engagement": [ + { + "section": "hero", + "views": 5044, + "avg_time_s": 22.3, + "dropoff_rate": 0.63 + }, + { + "section": "proof", + "views": 2756, + "avg_time_s": 29.7, + "dropoff_rate": 0.454 + }, + { + "section": "services", + "views": 2438, + "avg_time_s": 24.1, + "dropoff_rate": 0.491 + }, + { + "section": "cta", + "views": 1269, + "avg_time_s": 16.7, + "dropoff_rate": 0.88 + } + ], + "events": [ + { + "version_sha": "synthetic-lp-w00-b55b71f1", + "metric": "sessions", + "value": 5044, + "timestamp": "2026-02-01T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w00-b55b71f1", + "metric": "bounce_rate", + "value": 0.63, + "timestamp": "2026-02-01T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w00-b55b71f1", + "metric": "avg_time_s", + "value": 92.8, + "timestamp": "2026-02-01T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w00-b55b71f1", + "metric": "scroll_depth_75", + "value": 0.388, + "timestamp": "2026-02-01T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w00-b55b71f1", + "metric": "cta_click", + "value": 151, + "timestamp": "2026-02-01T12:00:00.000Z" + } + ] +} diff --git a/demo-output/landing-page/w00/desktop-heatmap.svg b/demo-output/landing-page/w00/desktop-heatmap.svg new file mode 100644 index 0000000..e23f385 --- /dev/null +++ b/demo-output/landing-page/w00/desktop-heatmap.svg @@ -0,0 +1,17 @@ + + +Synthetic heatmap — desktop +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + +hero 64% + +learn-more 51% + +proof 50% + +submit 42% + +services 41% + +contact 14% + diff --git a/demo-output/landing-page/w00/desktop.png b/demo-output/landing-page/w00/desktop.png new file mode 100644 index 0000000..3df63b6 Binary files /dev/null and b/demo-output/landing-page/w00/desktop.png differ diff --git a/demo-output/landing-page/w00/heatmap.json b/demo-output/landing-page/w00/heatmap.json new file mode 100644 index 0000000..d618201 --- /dev/null +++ b/demo-output/landing-page/w00/heatmap.json @@ -0,0 +1,268 @@ +{ + "week": "w00", + "synthetic": true, + "model": "layout-map-plus-analytics-v1", + "disclaimer": "Synthetic heatmap for local demo only. It maps mocked section engagement and CTA clicks onto measured DOM rectangles; it is not real visitor tracking.", + "analytics_version_sha": "synthetic-lp-w00-b55b71f1", + "sessions": 5044, + "breakpoints": [ + { + "breakpoint": "mobile", + "width": 375, + "document_height": 2760, + "regions": [ + { + "kind": "section", + "id": "hero", + "label": "Health & Wellness Coaching", + "rect": { + "x": 0, + "y": 143, + "width": 375, + "height": 577 + }, + "intensity": 0.644, + "reason": "hero: views=5044, avg_time_s=22.3, dropoff_rate=0.63." + }, + { + "kind": "cta", + "id": "learn-more", + "label": "Learn More", + "rect": { + "x": 194, + "y": 653, + "width": 138, + "height": 42 + }, + "intensity": 0.505, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "About Our Program", + "rect": { + "x": 0, + "y": 748, + "width": 375, + "height": 816 + }, + "intensity": 0.44, + "reason": "proof: views=2756, avg_time_s=29.7, dropoff_rate=0.454." + }, + { + "kind": "cta", + "id": "submit", + "label": "Submit", + "rect": { + "x": 31, + "y": 2585, + "width": 313, + "height": 42 + }, + "intensity": 0.343, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "Services", + "rect": { + "x": 0, + "y": 1592, + "width": 375, + "height": 510 + }, + "intensity": 0.256, + "reason": "services: views=2438, avg_time_s=24.1, dropoff_rate=0.491." + }, + { + "kind": "section", + "id": "contact", + "label": "Get in Touch", + "rect": { + "x": 0, + "y": 2130, + "width": 375, + "height": 528 + }, + "intensity": 0.08, + "reason": "cta: views=1269, avg_time_s=16.7, dropoff_rate=0.88." + } + ], + "svg": "screenshots/w00/mobile-heatmap.svg" + }, + { + "breakpoint": "tablet", + "width": 768, + "document_height": 1999, + "regions": [ + { + "kind": "section", + "id": "hero", + "label": "Health & Wellness Coaching", + "rect": { + "x": 0, + "y": 111, + "width": 768, + "height": 469 + }, + "intensity": 0.644, + "reason": "hero: views=5044, avg_time_s=22.3, dropoff_rate=0.63." + }, + { + "kind": "cta", + "id": "learn-more", + "label": "Learn More", + "rect": { + "x": 502, + "y": 513, + "width": 138, + "height": 42 + }, + "intensity": 0.505, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "About Our Program", + "rect": { + "x": 0, + "y": 608, + "width": 768, + "height": 365 + }, + "intensity": 0.496, + "reason": "proof: views=2756, avg_time_s=29.7, dropoff_rate=0.454." + }, + { + "kind": "cta", + "id": "submit", + "label": "Submit", + "rect": { + "x": 31, + "y": 1824, + "width": 706, + "height": 42 + }, + "intensity": 0.433, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "Services", + "rect": { + "x": 0, + "y": 1001, + "width": 768, + "height": 369 + }, + "intensity": 0.406, + "reason": "services: views=2438, avg_time_s=24.1, dropoff_rate=0.491." + }, + { + "kind": "section", + "id": "contact", + "label": "Get in Touch", + "rect": { + "x": 0, + "y": 1398, + "width": 768, + "height": 499 + }, + "intensity": 0.149, + "reason": "cta: views=1269, avg_time_s=16.7, dropoff_rate=0.88." + } + ], + "svg": "screenshots/w00/tablet-heatmap.svg" + }, + { + "breakpoint": "desktop", + "width": 1440, + "document_height": 1886, + "regions": [ + { + "kind": "section", + "id": "hero", + "label": "Health & Wellness Coaching", + "rect": { + "x": 135, + "y": 111, + "width": 1170, + "height": 442 + }, + "intensity": 0.644, + "reason": "hero: views=5044, avg_time_s=22.3, dropoff_rate=0.63." + }, + { + "kind": "cta", + "id": "learn-more", + "label": "Learn More", + "rect": { + "x": 938, + "y": 456, + "width": 138, + "height": 42 + }, + "intensity": 0.505, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "About Our Program", + "rect": { + "x": 129, + "y": 581, + "width": 1182, + "height": 308 + }, + "intensity": 0.496, + "reason": "proof: views=2756, avg_time_s=29.7, dropoff_rate=0.454." + }, + { + "kind": "cta", + "id": "submit", + "label": "Submit", + "rect": { + "x": 360, + "y": 1711, + "width": 720, + "height": 42 + }, + "intensity": 0.422, + "reason": "CTA hotspot from 151 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "Services", + "rect": { + "x": 129, + "y": 917, + "width": 1182, + "height": 340 + }, + "intensity": 0.405, + "reason": "services: views=2438, avg_time_s=24.1, dropoff_rate=0.491." + }, + { + "kind": "section", + "id": "contact", + "label": "Get in Touch", + "rect": { + "x": 329, + "y": 1285, + "width": 782, + "height": 499 + }, + "intensity": 0.141, + "reason": "cta: views=1269, avg_time_s=16.7, dropoff_rate=0.88." + } + ], + "svg": "screenshots/w00/desktop-heatmap.svg" + } + ] +} diff --git a/demo-output/landing-page/w00/mobile-heatmap.svg b/demo-output/landing-page/w00/mobile-heatmap.svg new file mode 100644 index 0000000..371d5d1 --- /dev/null +++ b/demo-output/landing-page/w00/mobile-heatmap.svg @@ -0,0 +1,17 @@ + + +Synthetic heatmap — mobile +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + +hero 64% + +learn-more 51% + +proof 44% + +submit 34% + +services 26% + +contact 8% + diff --git a/demo-output/landing-page/w00/mobile.png b/demo-output/landing-page/w00/mobile.png new file mode 100644 index 0000000..e723fae Binary files /dev/null and b/demo-output/landing-page/w00/mobile.png differ diff --git a/demo-output/landing-page/w00/tablet-heatmap.svg b/demo-output/landing-page/w00/tablet-heatmap.svg new file mode 100644 index 0000000..67be36f --- /dev/null +++ b/demo-output/landing-page/w00/tablet-heatmap.svg @@ -0,0 +1,17 @@ + + +Synthetic heatmap — tablet +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + +hero 64% + +learn-more 51% + +proof 50% + +submit 43% + +services 41% + +contact 15% + diff --git a/demo-output/landing-page/w00/tablet.png b/demo-output/landing-page/w00/tablet.png new file mode 100644 index 0000000..1f66288 Binary files /dev/null and b/demo-output/landing-page/w00/tablet.png differ diff --git a/demo-output/landing-page/w01/analytics.json b/demo-output/landing-page/w01/analytics.json new file mode 100644 index 0000000..50f1acd --- /dev/null +++ b/demo-output/landing-page/w01/analytics.json @@ -0,0 +1,98 @@ +{ + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "site_signature": "3b7fefab", + "substrate": "lp", + "week": 1, + "weekDate": "2026-02-08", + "sessions": 5044, + "bounce_rate": 0.473, + "avg_time_s": 119.8, + "scroll_depth_25": 0.811, + "scroll_depth_50": 0.67, + "scroll_depth_75": 0.47, + "scroll_depth_100": 0.217, + "cta_clicks": { + "discovery_call": 314 + }, + "persona_metrics": [ + { + "persona_id": "credentials-conscious-executive", + "sessions": 1866, + "bounce_rate": 0.443, + "cta_clicks": 122, + "avg_time_s": 123.9 + }, + { + "persona_id": "curious-self-starter", + "sessions": 1715, + "bounce_rate": 0.475, + "cta_clicks": 106, + "avg_time_s": 119.8 + }, + { + "persona_id": "skeptical-researcher", + "sessions": 1463, + "bounce_rate": 0.501, + "cta_clicks": 87, + "avg_time_s": 116.7 + } + ], + "section_engagement": [ + { + "section": "hero", + "views": 5044, + "avg_time_s": 28.6, + "dropoff_rate": 0.473 + }, + { + "section": "proof", + "views": 3326, + "avg_time_s": 36.7, + "dropoff_rate": 0.341 + }, + { + "section": "services", + "views": 3326, + "avg_time_s": 29.8, + "dropoff_rate": 0.341 + }, + { + "section": "cta", + "views": 1808, + "avg_time_s": 20.7, + "dropoff_rate": 0.751 + } + ], + "events": [ + { + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "metric": "sessions", + "value": 5044, + "timestamp": "2026-02-08T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "metric": "bounce_rate", + "value": 0.473, + "timestamp": "2026-02-08T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "metric": "avg_time_s", + "value": 119.8, + "timestamp": "2026-02-08T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "metric": "scroll_depth_75", + "value": 0.47, + "timestamp": "2026-02-08T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "metric": "cta_click", + "value": 314, + "timestamp": "2026-02-08T12:00:00.000Z" + } + ] +} diff --git a/demo-output/landing-page/w01/desktop-heatmap.svg b/demo-output/landing-page/w01/desktop-heatmap.svg new file mode 100644 index 0000000..2eb1963 --- /dev/null +++ b/demo-output/landing-page/w01/desktop-heatmap.svg @@ -0,0 +1,33 @@ + + +Synthetic heatmap — desktop +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +discovery_call 73% + + + +hero 69% + + + +proof 40% + + + +discovery_call 37% + + + +discovery_call 24% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w01/desktop.png b/demo-output/landing-page/w01/desktop.png new file mode 100644 index 0000000..8ea5aac Binary files /dev/null and b/demo-output/landing-page/w01/desktop.png differ diff --git a/demo-output/landing-page/w01/heatmap.json b/demo-output/landing-page/w01/heatmap.json new file mode 100644 index 0000000..7fb5751 --- /dev/null +++ b/demo-output/landing-page/w01/heatmap.json @@ -0,0 +1,307 @@ +{ + "week": "w01", + "synthetic": true, + "model": "layout-map-plus-analytics-v2", + "disclaimer": "Synthetic heatmap for local demo only. It maps mocked section engagement and CTA clicks onto measured DOM rectangles; it is not real visitor tracking.", + "analytics_version_sha": "synthetic-lp-w01-85157482-ui-adjusted", + "sessions": 5044, + "breakpoints": [ + { + "breakpoint": "mobile", + "width": 375, + "document_height": 6136, + "regions": [ + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 375, + "height": 1345 + }, + "intensity": 0.691, + "reason": "hero: views=5044, avg_time_s=28.6, dropoff_rate=0.473." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 39, + "y": 1068, + "width": 230, + "height": 52 + }, + "intensity": 0.681, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 20, + "y": 2958, + "width": 230, + "height": 52 + }, + "intensity": 0.284, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 41, + "y": 5869, + "width": 293, + "height": 47 + }, + "intensity": 0.244, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1416, + "width": 375, + "height": 1702 + }, + "intensity": 0.228, + "reason": "proof: views=3326, avg_time_s=36.7, dropoff_rate=0.341." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 3118, + "width": 375, + "height": 1662 + }, + "intensity": 0.159, + "reason": "services: views=3326, avg_time_s=29.8, dropoff_rate=0.341." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 4780, + "width": 375, + "height": 1221 + }, + "intensity": 0.08, + "reason": "cta: views=1808, avg_time_s=20.7, dropoff_rate=0.751." + } + ], + "svg": "screenshots/w01/mobile-heatmap.svg" + }, + { + "breakpoint": "tablet", + "width": 768, + "document_height": 5372, + "regions": [ + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 768, + "height": 1363 + }, + "intensity": 0.691, + "reason": "hero: views=5044, avg_time_s=28.6, dropoff_rate=0.473." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 56, + "y": 1121, + "width": 258, + "height": 58 + }, + "intensity": 0.684, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1434, + "width": 768, + "height": 1301 + }, + "intensity": 0.341, + "reason": "proof: views=3326, avg_time_s=36.7, dropoff_rate=0.341." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 31, + "y": 2607, + "width": 258, + "height": 58 + }, + "intensity": 0.318, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 60, + "y": 5141, + "width": 649, + "height": 56 + }, + "intensity": 0.244, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 2734, + "width": 768, + "height": 1453 + }, + "intensity": 0.159, + "reason": "services: views=3326, avg_time_s=29.8, dropoff_rate=0.341." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 4187, + "width": 768, + "height": 1108 + }, + "intensity": 0.08, + "reason": "cta: views=1808, avg_time_s=20.7, dropoff_rate=0.751." + } + ], + "svg": "screenshots/w01/tablet-heatmap.svg" + }, + { + "breakpoint": "desktop", + "width": 1440, + "document_height": 4626, + "regions": [ + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 731, + "y": 691, + "width": 258, + "height": 58 + }, + "intensity": 0.728, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 1440, + "height": 996 + }, + "intensity": 0.691, + "reason": "hero: views=5044, avg_time_s=28.6, dropoff_rate=0.473." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1067, + "width": 1440, + "height": 1082 + }, + "intensity": 0.399, + "reason": "proof: views=3326, avg_time_s=36.7, dropoff_rate=0.341." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 130, + "y": 1972, + "width": 258, + "height": 58 + }, + "intensity": 0.37, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 389, + "y": 4344, + "width": 662, + "height": 56 + }, + "intensity": 0.244, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 314 synthetic clicks across 5044 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 2150, + "width": 1440, + "height": 1161 + }, + "intensity": 0.159, + "reason": "services: views=3326, avg_time_s=29.8, dropoff_rate=0.341." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 3311, + "width": 1440, + "height": 1238 + }, + "intensity": 0.08, + "reason": "cta: views=1808, avg_time_s=20.7, dropoff_rate=0.751." + } + ], + "svg": "screenshots/w01/desktop-heatmap.svg" + } + ] +} diff --git a/demo-output/landing-page/w01/mobile-heatmap.svg b/demo-output/landing-page/w01/mobile-heatmap.svg new file mode 100644 index 0000000..ec0abc9 --- /dev/null +++ b/demo-output/landing-page/w01/mobile-heatmap.svg @@ -0,0 +1,33 @@ + + +Synthetic heatmap — mobile +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +hero 69% + + + +discovery_call 68% + + + +discovery_call 28% + + + +discovery_call 24% + + + +proof 23% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w01/mobile.png b/demo-output/landing-page/w01/mobile.png new file mode 100644 index 0000000..958a8a5 Binary files /dev/null and b/demo-output/landing-page/w01/mobile.png differ diff --git a/demo-output/landing-page/w01/tablet-heatmap.svg b/demo-output/landing-page/w01/tablet-heatmap.svg new file mode 100644 index 0000000..4b28197 --- /dev/null +++ b/demo-output/landing-page/w01/tablet-heatmap.svg @@ -0,0 +1,33 @@ + + +Synthetic heatmap — tablet +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +hero 69% + + + +discovery_call 68% + + + +proof 34% + + + +discovery_call 32% + + + +discovery_call 24% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w01/tablet.png b/demo-output/landing-page/w01/tablet.png new file mode 100644 index 0000000..dc28fb9 Binary files /dev/null and b/demo-output/landing-page/w01/tablet.png differ diff --git a/demo-output/landing-page/w01/visual-review.md b/demo-output/landing-page/w01/visual-review.md new file mode 100644 index 0000000..314acca --- /dev/null +++ b/demo-output/landing-page/w01/visual-review.md @@ -0,0 +1,69 @@ +# w01 Visual Review + +**Verdict:** PASS + +**Reviewer role:** local-lp-visual-reviewer (Opus protocol) +**Run:** `local-runs/lp-council/w01-single-offer-visual-heatmap` +**Week:** w01 (first intervention from w00 baseline; classification BROAD_REDESIGN) +**Inputs reviewed:** `weeks/w01/index.html`, `weeks/w01/style.css`, `history/w01/proposal.md`, `history/w01/decision.json`, `screenshots/w01/{desktop,tablet,mobile}.png`, `screenshots/w01/summary.json`. + +--- + +## Proposal-intent landing check + +Each visual contract from the proposal is verifiable in the rendered screenshots: + +| Proposal intent | Evidence in screenshot | Status | +|---|---|---| +| Founder face above the fold (desktop) | Nicolette portrait occupies left ~5/11 of hero grid, top-aligned in the 1440×900 viewport; visible before any scroll | landed | +| Headline names offer + audience + clinical scrutiny | "Your team deserves a food-as-medicine framework that holds up to *clinical scrutiny.*" reads cleanly in serif; "clinical scrutiny" italicized in `--leaf-green-deep` | landed | +| Single forest-green CTA visual treatment, three instances | Hero CTA card (cream tile + green button), end-of-proof CTA row (green button), contact form submit (full-width green button). No other element borrows the green-pill styling. Three identical-label CTAs form the right-side reading rail described in the heatmap self-check | landed | +| Credential strip immediately after CTA | "DSocSci · Royal Roads University", "Education only — not medical advice", "Gerson · Campbell · Barnard lineage" rendered as pill chips below the CTA card on desktop | landed | +| Lineage card frames Gerson/Campbell/Barnard as *educational lineage*, not efficacy | Numbered list (01/02/03) with name + role labels; footnote "Cited as educational lineage. Not a clinical-efficacy endorsement." visible | landed | +| Press strip = exactly four logos | Forbes · VOGUE · Canadian Living · Dragon's Den. Counted on desktop and tablet; collapses to 2×2 on mobile per `@media (max-width: 720px)` | landed | +| Single program-detail block with SVG diagram + outcomes | Clinic-alignment SVG on left, three numbered outcome cards on right (shared vocab / clinical credibility / implementation path) | landed | +| Signature pull-quote standalone in contact | "Your body's ability to heal is greater than anyone has permitted you to believe." rendered with gold left-bar treatment, attribution line, no benefits list following — followed only by reassurance and form | landed | +| Education-only disclaimer co-located with every Dr. mention | Hero subhead carries "Education only — not medical advice"; proof block has the indented disclaimer card next to the founder authority paragraph; contact section pressure line repeats it; footer condensed line repeats it again | landed | + +## Brand-lock + palette check + +- Forest green (`#3f7d58` / `#335f44`) used on CTAs, italic emphasis, lineage numerals' deep variant, link color, focus halos. +- Soft gold (`#c8a96a` / `#a98843`) used on kickers, utility label borders, portrait corner mark, lineage numerals, signature-quote bar, form labels. +- Warm cream (`#f7f1e8`) and tints used as page + section + card backgrounds. +- Charcoal (`#243034`) as body text and contact-section background. +- **No teal anywhere.** Searched both screenshots and CSS variables. The `deep_teal` token from brand.json is intentionally absent from `style.css`. + +## Overflow / clipping / contrast / CTA check (per breakpoint) + +| Breakpoint | `horizontal_overflow` | Visible clipping | Contact CTA visible | Notes | +|---|---|---|---|---| +| Desktop 1440×900 | false | None | Yes — hero CTA fully above the fold | Hero grid 5fr/6fr balances portrait + copy. Contact section renders cream form fields against charcoal — high contrast | +| Tablet 768×1024 | false | None | Yes — single-column stack triggers at 960px breakpoint, portrait centered at 460px max | Press strip stays 4-column at 768px (before 720px breakpoint), still readable | +| Mobile 375×900 | false | None | Yes — form, all 3 CTAs, signature quote all stack cleanly | Credential strip stacks vertically (per `@media (max-width: 640px)`); lineage card legible; press strip 2×2 | + +`summary.json`: `horizontal_overflow: false` on all three breakpoints, `console_errors: []`, `page_errors: []`. No BLOCK trigger. + +## Continuity vs. w00 + +w01 is classified BROAD_REDESIGN, so a system-wide change is expected and not a continuity violation. The four-section spine (`hero | proof | services | contact`), section IDs (`#hero`, `#about`, `#services`, `#contact`), and `data-webster-section` anchors are preserved exactly per the proposal's mapping table. This reads as the first principled intervention from an ugly baseline, not a parachuted-in final mock — the founder photo, lineage card, and program diagram are all single deliberate moves, not a redesign-the-world dump. + +## Compliance gates (visual surface) + +- DSocSci, not MD: visible in hero subhead, proof founder block, contact attribution, footer. +- "Detoxification" never appears as a standalone heading — only inside "N&D Certification" / "Nutrition and Detoxification" prose. +- Lineage names sit in their own card, not adjacent to outcome-promise copy. +- Signature pull-quote not followed by a benefits list. + +## Minor observations (non-blocking) + +1. The hero portrait at 1440px is sized generously (~5/11 of the grid). It works for the heatmap-legibility goal this week, but if w02 adds more above-the-fold content (e.g. a sticky CTA or expanded credential row), the portrait may need a small downscale to avoid pushing the credential strip below 1080px viewports. Not a w01 issue. +2. Press logos render at low opacity (`grayscale(100%) opacity(0.55)`); this is intentional restraint per the proposal but worth keeping an eye on if Skeptical Researcher panel feedback in w02 says the proof feels too quiet. +3. `cta_count: 7` in summary.json includes nav anchors + brand link in addition to the three `data-webster-cta="discovery_call"` instances — that is correct and not CTA inflation since none of the extras share the green-pill treatment. + +## Fix hints + +None required for w01. + +--- + +**Final verdict: PASS.** Proposal intent landed visibly across desktop, tablet, and mobile. No overflow, no clipping, no contrast failures, no brand-palette drift, no CTA inflation, no compliance regressions. Ready to advance. diff --git a/demo-output/landing-page/w02/analytics.json b/demo-output/landing-page/w02/analytics.json new file mode 100644 index 0000000..1b76d80 --- /dev/null +++ b/demo-output/landing-page/w02/analytics.json @@ -0,0 +1,98 @@ +{ + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "site_signature": "85d8dc90", + "substrate": "lp", + "week": 2, + "weekDate": "2026-02-15", + "sessions": 5046, + "bounce_rate": 0.469, + "avg_time_s": 137.4, + "scroll_depth_25": 0.81, + "scroll_depth_50": 0.678, + "scroll_depth_75": 0.47, + "scroll_depth_100": 0.219, + "cta_clicks": { + "discovery_call": 343 + }, + "persona_metrics": [ + { + "persona_id": "credentials-conscious-executive", + "sessions": 1867, + "bounce_rate": 0.441, + "cta_clicks": 132, + "avg_time_s": 140.8 + }, + { + "persona_id": "curious-self-starter", + "sessions": 1716, + "bounce_rate": 0.474, + "cta_clicks": 113, + "avg_time_s": 136.4 + }, + { + "persona_id": "skeptical-researcher", + "sessions": 1463, + "bounce_rate": 0.487, + "cta_clicks": 98, + "avg_time_s": 136 + } + ], + "section_engagement": [ + { + "section": "hero", + "views": 5046, + "avg_time_s": 32.8, + "dropoff_rate": 0.469 + }, + { + "section": "proof", + "views": 3342, + "avg_time_s": 42.7, + "dropoff_rate": 0.338 + }, + { + "section": "services", + "views": 3342, + "avg_time_s": 34.7, + "dropoff_rate": 0.338 + }, + { + "section": "cta", + "views": 1822, + "avg_time_s": 24, + "dropoff_rate": 0.728 + } + ], + "events": [ + { + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "metric": "sessions", + "value": 5046, + "timestamp": "2026-02-15T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "metric": "bounce_rate", + "value": 0.469, + "timestamp": "2026-02-15T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "metric": "avg_time_s", + "value": 137.4, + "timestamp": "2026-02-15T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "metric": "scroll_depth_75", + "value": 0.47, + "timestamp": "2026-02-15T12:00:00.000Z" + }, + { + "version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "metric": "cta_click", + "value": 343, + "timestamp": "2026-02-15T12:00:00.000Z" + } + ] +} diff --git a/demo-output/landing-page/w02/desktop-heatmap.svg b/demo-output/landing-page/w02/desktop-heatmap.svg new file mode 100644 index 0000000..debffcb --- /dev/null +++ b/demo-output/landing-page/w02/desktop-heatmap.svg @@ -0,0 +1,33 @@ + + +Synthetic heatmap — desktop +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +discovery_call 78% + + + +hero 69% + + + +proof 36% + + + +discovery_call 32% + + + +discovery_call 25% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w02/desktop.png b/demo-output/landing-page/w02/desktop.png new file mode 100644 index 0000000..9ec25a9 Binary files /dev/null and b/demo-output/landing-page/w02/desktop.png differ diff --git a/demo-output/landing-page/w02/heatmap.json b/demo-output/landing-page/w02/heatmap.json new file mode 100644 index 0000000..e14aa47 --- /dev/null +++ b/demo-output/landing-page/w02/heatmap.json @@ -0,0 +1,320 @@ +{ + "week": "w02", + "synthetic": true, + "model": "layout-map-plus-analytics-v2", + "disclaimer": "Synthetic heatmap for local demo only. It maps mocked section engagement and CTA clicks onto measured DOM rectangles; it is not real visitor tracking.", + "analytics_version_sha": "synthetic-lp-w02-325f64cb-ui-adjusted", + "sessions": 5046, + "breakpoints": [ + { + "breakpoint": "mobile", + "width": 375, + "document_height": 9388, + "regions": [ + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 39, + "y": 1068, + "width": 230, + "height": 52 + }, + "intensity": 0.727, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 375, + "height": 1300 + }, + "intensity": 0.692, + "reason": "hero: views=5046, avg_time_s=32.8, dropoff_rate=0.469." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 74, + "y": 853, + "width": 227, + "height": 40 + }, + "intensity": 0.33, + "reason": "CTA hotspot weighted by position 4, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 20, + "y": 3838, + "width": 230, + "height": 52 + }, + "intensity": 0.294, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 41, + "y": 9049, + "width": 293, + "height": 47 + }, + "intensity": 0.25, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1371, + "width": 375, + "height": 2626 + }, + "intensity": 0.164, + "reason": "proof: views=3342, avg_time_s=42.7, dropoff_rate=0.338." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 3997, + "width": 375, + "height": 3249 + }, + "intensity": 0.16, + "reason": "services: views=3342, avg_time_s=34.7, dropoff_rate=0.338." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 7246, + "width": 375, + "height": 2007 + }, + "intensity": 0.082, + "reason": "cta: views=1822, avg_time_s=24, dropoff_rate=0.728." + } + ], + "svg": "screenshots/w02/mobile-heatmap.svg" + }, + { + "breakpoint": "tablet", + "width": 768, + "document_height": 7627, + "regions": [ + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 56, + "y": 1121, + "width": 258, + "height": 58 + }, + "intensity": 0.73, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 768, + "height": 1318 + }, + "intensity": 0.692, + "reason": "hero: views=5046, avg_time_s=32.8, dropoff_rate=0.469." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1389, + "width": 768, + "height": 1811 + }, + "intensity": 0.295, + "reason": "proof: views=3342, avg_time_s=42.7, dropoff_rate=0.338." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 31, + "y": 3073, + "width": 258, + "height": 58 + }, + "intensity": 0.294, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 60, + "y": 7396, + "width": 649, + "height": 56 + }, + "intensity": 0.25, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 3200, + "width": 768, + "height": 2704 + }, + "intensity": 0.16, + "reason": "services: views=3342, avg_time_s=34.7, dropoff_rate=0.338." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 5903, + "width": 768, + "height": 1646 + }, + "intensity": 0.082, + "reason": "cta: views=1822, avg_time_s=24, dropoff_rate=0.728." + } + ], + "svg": "screenshots/w02/tablet-heatmap.svg" + }, + { + "breakpoint": "desktop", + "width": 1440, + "document_height": 6637, + "regions": [ + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 731, + "y": 691, + "width": 258, + "height": 58 + }, + "intensity": 0.778, + "reason": "CTA hotspot weighted by position 1, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "hero", + "label": "hero", + "rect": { + "x": 0, + "y": 71, + "width": 1440, + "height": 951 + }, + "intensity": 0.692, + "reason": "hero: views=5046, avg_time_s=32.8, dropoff_rate=0.469." + }, + { + "kind": "section", + "id": "proof", + "label": "proof", + "rect": { + "x": 0, + "y": 1022, + "width": 1440, + "height": 1498 + }, + "intensity": 0.358, + "reason": "proof: views=3342, avg_time_s=42.7, dropoff_rate=0.338." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 130, + "y": 2342, + "width": 258, + "height": 58 + }, + "intensity": 0.321, + "reason": "CTA hotspot weighted by position 2, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "cta", + "id": "discovery_call", + "label": "Book Your Discovery Call", + "rect": { + "x": 369, + "y": 6355, + "width": 702, + "height": 56 + }, + "intensity": 0.25, + "reason": "CTA hotspot weighted by position 3, viewport visibility, and 343 synthetic clicks across 5046 sessions." + }, + { + "kind": "section", + "id": "services", + "label": "services", + "rect": { + "x": 0, + "y": 2520, + "width": 1440, + "height": 2263 + }, + "intensity": 0.16, + "reason": "services: views=3342, avg_time_s=34.7, dropoff_rate=0.338." + }, + { + "kind": "section", + "id": "contact", + "label": "contact", + "rect": { + "x": 0, + "y": 4784, + "width": 1440, + "height": 1777 + }, + "intensity": 0.082, + "reason": "cta: views=1822, avg_time_s=24, dropoff_rate=0.728." + } + ], + "svg": "screenshots/w02/desktop-heatmap.svg" + } + ] +} diff --git a/demo-output/landing-page/w02/mobile-heatmap.svg b/demo-output/landing-page/w02/mobile-heatmap.svg new file mode 100644 index 0000000..56051c9 --- /dev/null +++ b/demo-output/landing-page/w02/mobile-heatmap.svg @@ -0,0 +1,37 @@ + + +Synthetic heatmap — mobile +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +discovery_call 73% + + + +hero 69% + + + +discovery_call 33% + + + +discovery_call 29% + + + +discovery_call 25% + + + +proof 16% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w02/mobile.png b/demo-output/landing-page/w02/mobile.png new file mode 100644 index 0000000..c0f2e65 Binary files /dev/null and b/demo-output/landing-page/w02/mobile.png differ diff --git a/demo-output/landing-page/w02/tablet-heatmap.svg b/demo-output/landing-page/w02/tablet-heatmap.svg new file mode 100644 index 0000000..7ec55a8 --- /dev/null +++ b/demo-output/landing-page/w02/tablet-heatmap.svg @@ -0,0 +1,33 @@ + + +Synthetic heatmap — tablet +Mock attention overlay from layout-map.json + analytics.section_engagement; not real user tracking. + + + +discovery_call 73% + + + +hero 69% + + + +proof 30% + + + +discovery_call 29% + + + +discovery_call 25% + + + +services 16% + + + +contact 8% + diff --git a/demo-output/landing-page/w02/tablet.png b/demo-output/landing-page/w02/tablet.png new file mode 100644 index 0000000..5b63398 Binary files /dev/null and b/demo-output/landing-page/w02/tablet.png differ diff --git a/demo-output/landing-page/w02/visual-review.md b/demo-output/landing-page/w02/visual-review.md new file mode 100644 index 0000000..5da4a97 --- /dev/null +++ b/demo-output/landing-page/w02/visual-review.md @@ -0,0 +1,90 @@ +# w02 Visual Review — Richer Health LP + +Run: `local-runs/lp-council/w01-single-offer-visual-heatmap` +Week: w02 (NARROW_FIX_DEEP) +Reviewer: local-lp-visual-reviewer (Opus protocol) + +--- + +## Verdict: **PASS** + +The three accepted P0/P1 interventions (booking-shaped contact surface, curriculum spine in services, proof depth via verifiable-credentials block) all landed visibly across desktop/tablet/mobile. No horizontal overflow at any breakpoint per `screenshots/w02/summary.json` (all three `horizontal_overflow: false`). Brand palette holds. CTA hierarchy intact. Continuity from w01 reads as evolution, not replacement. + +--- + +## Evidence — proposal intent landed visibly + +| Intervention (proposal) | Score | Visible at desktop | Visible at tablet | Visible at mobile | +| --- | --- | --- | --- | --- | +| A1 Booking-shaped surface (week-grid mock + role/clinic-size/slot selects + caption) | 88 | yes — leaf-green highlighted cells (Tue 10:30 / Thu 14:00 / Fri 09:00) above form, italic preview caption present | yes | yes — grid collapses to single-column day rows; quiet weekend days hidden under 640px as specified | +| A2 Curriculum spine in services (numbered prose modules + format DL + audience block) | 82 | yes — bordered cream-tint card sits below outcomes, four numbered modules render as prose (NOT a card grid), format DL with four rows, leaf-green-bar audience callout at bottom | yes | yes — DL rows stack to single column at ≤960px | +| A3 Proof depth — press opacity 0.55→0.75 + verifiable credentials block | 76 | yes — Forbes/Vogue/Canadian Living/Dragon's Den logos noticeably more legible vs w01; new gold-left-border "Verifiable credentials & lineage" block sits between lineage card and press strip | yes | yes | +| A4 Mobile/tablet sticky CTA bar | 62 | n/a (correctly hidden ≥720px) | yes — cream pill on charcoal at viewport bottom | yes — same | +| A5 Copy/compliance refinements | 70 | proof kicker reads "The credential chain behind the curriculum"; services H2 reads "One curriculum. Every role on your floor trained in *the same framework*"; contact subhead reads "30 minutes. No obligation. Limited weekly availability." (no scarcity number) | yes | yes | +| A6 SEO head (title, twitter cards, label/for pairs) | 58 | invisible-by-design; verified in markup (head + each new `