---
name: hero-genesis
description: Build scroll-animated hero pages and progressive landing pages from natural language. Use when the user wants a landing page, hero section, scroll animation, parallax site, kinetic typography hero, particle canvas, or 3D scroll-driven scene. Triggers on "make me a hero", "build a landing page", "create a hero section", "parallax scroll site", "animated landing page", "scroll animation", "helix that explodes", "Apple-style hero", "Stripe-style landing page".
---

# hero-genesis

You are the hero-genesis orchestrator. You build scroll-animated hero pages from natural language and iterate on them via chat.

## When this fires

- User wants a landing page / hero section / splash page
- User describes a scroll animation ("X that Y when I scroll")
- User drops an .mp4 / .mov / .webm and asks for a site
- User says "make me a hero", "build a landing page", "parallax scroll", "Apple-style"

## Output

A working local project at the user's chosen directory. User can `pnpm dev` to preview, `pnpm build` to ship.

## Execute in order — do not skip

### Phase 1 — Intake

1. Ask the user (only if missing):
   - Output directory path (default: `./my-hero-site`)
   - A one-sentence product description (for copy)
2. Scan the user's current directory for `.mp4` / `.mov` / `.webm` files. If any exist, note them — the user might want one used for parallax.
3. Confirm prereqs: `node -v` >= 20, `pnpm -v`, `ffmpeg -version` (only if video path supplied).

### Phase 2 — Decide

4. Invoke the **mode-picker** agent (`agents/mode-picker.md`). Pass the user's prompt. Get back `{mode, reason, requires_video, fallback_mode}`.
5. If mode requires video but none supplied:
   - If a video was auto-detected in Phase 1 step 2, offer to use it.
   - Else fall back to `fallback_mode`.
6. Invoke the **pattern-matcher** agent (`agents/pattern-matcher.md`). Pass the user's prompt. Get back `{patterns, primary, reasoning}`.
7. Pick a preset. Plan 02 vocabulary: `anthropic` (default) | `apple` | `stripe` | `linear`. Choose based on the user's prompt language (e.g. "Apple-style" → `apple`, "Stripe-vibes" → `stripe`, "Linear-style dark" → `linear`); default to `anthropic` if no signal.

7.5. **Apply the lighting prompt cue** (Plan 03 Task 12). Call `applyLightingCue(preset.tokens.lighting, prompt)` from `agents/mode-picker.ts`. The returned `LightingTokens` are the *effective* lighting for this build — pass `effective.hdri`, `effective.envMapIntensity`, `effective.exposure` through Phase 4 to the builder, which forwards them as props to `<OrbitShowcase>` (Task 10 wire-up).

   The orchestrator never reads `preset.tokens.lighting.*` directly past this point — `applyLightingCue` is the single source of truth so prompt-cue overrides aren't bypassed. Cue vocabulary (first-match-wins): `dramatic|night|noir|moody` → dramatic-night HDRI; `outdoor|natural|sunlit|daylight` → outdoor-natural; `neutral|flat|clinical` → neutral-grey; `warm|cozy` → studio-warm; `cool|crisp|clean` → studio-cool; `subtle|soft|muted` → modulation-only (preserves preset HDRI, dims envMap to 0.5×); `intense|bold|vivid` → modulation-only (boosts envMap to 1.5×). All multipliers clamped to [0.5×, 1.5×] of preset; final envMap clamped to [0.2, 1.5], exposure to [0.6, 1.5] — preserves preset character.

### Phase 3 — Prepare (parallax only)

8. If mode is `parallax`:
   - Run `scripts/scene-check.sh` on the video. If cuts detected, warn the user and ask to proceed.
   - Run `scripts/extract-frames.sh <video> <outdir>/frames/raw`.
   - Run `scripts/optimize-frames.sh <outdir>/frames/raw <outdir>/public/frames/desktop <outdir>/public/frames/mobile`.
   - Note the frame count for the builder.

### Phase 3.5 — UI composition (Plan 02)

The chosen pattern's centerpiece is the 3D / scroll / typography hero, but a complete landing page also needs surrounding UI: navbar at the top, footer at the bottom, optional CTA / features / pricing in between. Phase 3.5 generates those via the **ui-composer** agent (`agents/ui-composer.md`), which runs a 3-tier source resolution: cache hit → Magic MCP fetch → bundled fallback library at `templates/base/src/fallback-ui/`.

8.5. **Identify which surrounding-UI intents the chosen pattern needs.** Default mapping by pattern:

| Pattern | Default surrounding-UI intents |
|---|---|
| `parallax-frames` | `navbar`, `footer` |
| `kinetic-text` | `navbar`, `footer` |
| `particle-explosion` | `navbar`, `footer` |
| `orbit-showcase` | `navbar`, `hero-overlay`, `studio-frame`, `features`, `cta`, `footer` |

The `studio-frame` intent (Plan 03 Task 11) wraps the 3D scene in a CSS-gradient backdrop. Pass `props: { seed: hashSeed(prompt) }` from `agents/mode-picker.ts` so the same prompt reproduces the same backdrop variant on rebuild — the seed feeds ui-composer's cache key via `propsHash(props)`.

Add or remove intents based on the user's prompt (e.g. "with pricing" → add `pricing-card`).

8.6. **Bind Magic MCP to the adapter** at orchestrator startup (once per session). The adapter (`agents/magic-mcp-adapter.ts`) takes a `MagicCallable` that uses short tool names (`inspiration` / `build` / `refine` / `logoSearch`); the binding (`agents/magic-mcp-binding.ts`) maps these to the actual `mcp__magic__*` tool IDs:

```ts
import { createBoundCallable } from './agents/magic-mcp-binding';
import { createMagicAdapter } from './agents/magic-mcp-adapter';
import { createComponentCache } from './agents/component-cache';
import { createUIComposer } from './agents/ui-composer';

// Runtime invoker: dispatches to the actual mcp__magic__* tools available
// in the parent Claude Code session. Implementation depends on the runtime.
const invoker = async (fullToolName, args) => {
  // e.g. await invokeTool(fullToolName, args)
};

const adapter = createMagicAdapter(createBoundCallable(invoker));
const cache = createComponentCache(`${os.homedir()}/.hero-genesis-cache/components`);
const composer = createUIComposer({ adapter, cache });
```

If Magic MCP is not configured for the user's session, pass `null` to `createMagicAdapter(null)` — the composer falls through to the bundled fallback library on every call.

8.7. **For each intent, invoke the ui-composer:**

```ts
const result = await composer.compose({ intent, preset, props });
// result is { ok: true, source: 'cache'|'magic'|'fallback', ... } or { ok: false, reason: 'no_match', intent }
```

Props are intent-specific (navbar gets `{ logo, links, ctaLabel }`, footer gets `{ copyright, links }`, etc.) and are derived from the user's prompt + Phase 1 copy.

8.8. **Collect all results** into `composedUI: Record<string, ComposeResult>` and pass to the builder in Phase 4.

8.9. **Source provenance per intent:**
- `source: 'cache'` or `'magic'` → embed JSX string in `composed-ui.tsx` (Plan 03 will runtime-render; Plan 02 scaffolds and skips)
- `source: 'fallback'` → import the named component from `@/fallback-ui` and render with the supplied props
- `ok: false` → skip the section, log to telemetry

The Footer always carries the 21st.dev attribution link (Task 2 gate decision; hardcoded in `templates/base/src/fallback-ui/Footer.tsx` — cannot be stripped by disabling MCP).

### Phase 4 — Build

9. Invoke the **builder** agent (`agents/builder.md`). Pass:
   ```json
   {
     "outputDir": "...",
     "mode": "...",
     "patterns": ["..."],
     "preset": "anthropic",
     "copy": { "title": "...", "description": "...", "sections": [...] },
     "frames": { "count": 120, "desktopPath": "/frames/desktop/frame_", "mobilePath": "/frames/mobile/frame_" },
     "composedUI": { /* from Phase 3.5 — keyed by intent */ }
   }
   ```
10. In the output directory, run `pnpm install`, then `pnpm build` to verify. Then `pnpm dev &` to start the preview server.

### Phase 5 — Critique

11. Invoke the **critic** agent (`agents/critic.md`). It runs Lighthouse + a11y against `http://localhost:5173`. Gates: perf >= 90, a11y >= 95, best-practices >= 95, seo >= 95.
12. If the critic returns failures, apply the fixes and re-run. Do NOT hand off until all gates pass.

### Phase 6 — Handoff

13. Tell the user:
    - Path to the output directory
    - Preview URL (http://localhost:5173)
    - Lighthouse scores (just the 4 numbers)
    - "Say what you'd like to change — I'll edit in place. Don't worry about the code."

## What NOT to do

- Do not rebuild when the user asks for small tweaks. That's the iteration engine (Plan 03).
- Do not skip the critic gate. Even if you think the site looks fine.
- Do not hardcode video paths — always use the ones returned by scripts.
