|
| 1 | +--- |
| 2 | +name: landing-ab |
| 3 | +description: Build every landing page "self-driving" per the 5-level PostHog ladder (Angus Sewell field guide, 2026-07-03). Use whenever Nate asks to build, make, create, ship, spin up, redo, or redesign a landing page, marketing site, marketing page, splash page, one-pager, waitlist page, lead-magnet page, promo page/site, coming-soon page, or product page — or wants A/B testing, PostHog, analytics, heatmaps, session replay, conversion optimization, feature flags, or per-visitor personalization added to an existing page. Also invocable directly as /landing-ab. |
| 4 | +--- |
| 5 | + |
| 6 | +# /landing-ab — self-driving landing pages |
| 7 | + |
| 8 | +Every landing page ships able to watch, test, and rebuild itself. No more frozen billboards. |
| 9 | + |
| 10 | +**Source of truth:** `/Users/nathandavidovich/BRAIN2/02-Sources/SRC-2026-07-03-self-driving-landing-page.md` (archived PDF alongside). The ladder: L1 Static → L2 Watch → L3 Test → L4 Auto-iterate → L5 Personalize. |
| 11 | + |
| 12 | +## Non-negotiable defaults on every new landing-page build (L1+L2 baked in) |
| 13 | + |
| 14 | +1. **Tag the primary CTA** with `class="signup-cta"` — turns the L3 A/B test into a two-minute flag edit instead of a redeploy. |
| 15 | +2. **Wire PostHog at build time**, not later: |
| 16 | + ```js |
| 17 | + // npm i posthog-js — in <head>/app entry (static page: HTML <script> snippet from PostHog docs) |
| 18 | + import posthog from 'posthog-js' |
| 19 | + posthog.init('<YOUR_PROJECT_KEY>', { |
| 20 | + api_host: 'https://us.i.posthog.com', // MUST match key region (US/EU) or 401s + no data |
| 21 | + defaults: '2026-05-30', |
| 22 | + enable_heatmaps: true |
| 23 | + }) |
| 24 | + ``` |
| 25 | + Ask Nate once for the PostHog project key + region. Unknown → leave `<YOUR_PROJECT_KEY>` and flag it in `docs/LP-OPS.md`. |
| 26 | +3. **Stub the experiment flag hook** so L3 is pre-wired: |
| 27 | + ```js |
| 28 | + posthog.onFeatureFlags(function () { |
| 29 | + if (posthog.getFeatureFlag('landing-ab') === 'test') { |
| 30 | + // render version B |
| 31 | + } |
| 32 | + }) |
| 33 | + ``` |
| 34 | +4. **Light mode default** — never ship `prefers-color-scheme: dark` as default (standing rule `feedback_never_dark_mode`). |
| 35 | +5. **Drop `docs/LP-OPS.md`** into the repo (see template below) so the optimization loop survives the session. |
| 36 | + |
| 37 | +Division of labor: `copywriting` owns the words, `high-end-visual-design` / `ui-ux-pro-max` own the look — this skill owns instrumentation + the optimization loop. |
| 38 | + |
| 39 | +## docs/LP-OPS.md template (generate per repo, fill in repo/URL specifics) |
| 40 | + |
| 41 | +- **L3 · Run an A/B test:** add `disable_web_experiments: false` to init → PostHog Toolbar → Experiment → New → pick `signup-cta` → edit variant B → set primary metric → Launch (auto 50/50). Call it ONLY at **95%+ chance to win AND ≥50 exposures/variant**. Set run length BEFORE launch; don't peek — early stops ship false winners. |
| 42 | +- **L4 · Weekly optimizer loop:** connect PostHog MCP read-only: |
| 43 | + `claude mcp add --transport http posthog "https://mcp.posthog.com/mcp?readonly=true" -s user` |
| 44 | + Weekly agent prompt: |
| 45 | + ``` |
| 46 | + You're my landing-page optimizer. Using the PostHog MCP (read-only), pull results |
| 47 | + for experiment 'landing-ab'. If a variant has >95% chance to win and ≥50 |
| 48 | + exposures/variant, reply with: the winner, the % lift, and ONE specific change to |
| 49 | + test next. Wait for my "approved". On approval, edit the page in GitHub repo |
| 50 | + [me/site], open a PR, summarize. Never merge without my approval. |
| 51 | + ``` |
| 52 | + Schedule via GitHub Actions cron (Claude Code headless). Keep the human-approval gate; write access only on the deploy step. |
| 53 | +- **L5 · Personalize:** capture interest signals (`posthog.capture('viewed_pricing')`) → dynamic cohort ("performed X in last 30 days") → multivariate flag `lp-personalize` with JSON payload per variant, release condition targeted at the cohort: |
| 54 | + ```js |
| 55 | + posthog.onFeatureFlags(function () { |
| 56 | + const r = posthog.getFeatureFlagResult('lp-personalize') |
| 57 | + if (r?.payload) applyContent(r.payload) // payload = { hero, cta, showPricing } |
| 58 | + }) |
| 59 | + ``` |
| 60 | + GDPR: cookies + GeoIP are personal data — consent banner before L5. Need real volume per cohort before trusting a tailored variant. |
| 61 | +
|
| 62 | +## After the page ships |
| 63 | +
|
| 64 | +Offer once, one line: "Ladder next steps — L3 A/B now, L4 weekly optimizer (PostHog MCP + Actions cron), L5 per-cohort personalization?" |
| 65 | +
|
| 66 | +## Existing pages |
| 67 | +
|
| 68 | +Invoked on an already-live page: retrofit in ladder order — tag CTA → add PostHog → then whatever level Nate asked for. Never skip L2; everything above it is blind without data. |
0 commit comments