# Funnel spec — low-ticket → ascension

## Model
Six-step funnel, cloned once per vertical. Steps, price points, and path
conventions are fixed; only the diagnostic tool, copy, and retainer band vary.

## Steps
1. **SALES** — free interactive diagnostic (calculator/checker). Tool output is the pitch.  
   Path: `<tool-name>/`
2. **CORE** — $27 self-serve offer, instant delivery. Order bump $17 (worksheets/templates) on the checkout page.
3. **UPSELL 1** — $47 companion tool that removes manual work from the core offer. One-click, immediate post-purchase.  
   Path: `<assist-tool>/`
4. **UPSELL 2** — $497 done-with-you case study / strategy plan. Functions as the qualifier for high ticket.  
   Path: `case-study-<vertical>/`
5. **THANK-YOU** — two variants:
   - core buyers: `<core-offer>/thank-you/` (fulfillment + onboarding)
   - $497 buyers: `case-study-<vertical>/thank-you/` (books call 1)
6. **ASCENSION** — sold on the call, no self-serve checkout:
   - implementation: flat fee, low four figures
   - retainer: recurring monthly, priced as a band; band scales with the
     economic value of the function being managed

## Price ladder (fixed per vertical)
```
main $27 | bump $17 | oto1 $47 | oto2 $497 | impl ~$3k | retainer = band
```

## Conventions
- **PATH PARITY**: marketing and fulfillment domains use identical directory
  paths; redirects from legacy `.html` filenames. One mirror map = source of truth.
  → `registry/mirror-map.json`
- **PRODUCT REGISTRY**: flat lookup `vertical × role → product_id → price`,
  stored separately from page structure so IDs can be reissued without
  touching URLs. Roles: `main`, `bump`, `oto1`, `oto2`.
  → `registry/products.json`
- **DRAFTS QUARANTINED**: alternate landers and unpriced concepts live in
  `drafts/`, excluded from the production index, never carry live checkout
  links. No product ID → stays in drafts.
- **TEST CHECKOUT**: every front-end offer has a vendor test-payment path for
  verifying flow when public checkout is gated.
- **ASCENSION TIERS** have no self-serve product IDs by design.

## Layout
```
campaigns/
├── FUNNEL.md                 ← this spec
├── index.html                ← production index (excludes drafts/)
├── registry/
│   ├── products.json         ← vertical × role → product_id → price
│   ├── mirror-map.json       ← path parity + legacy .html redirects
│   └── vertical.schema.json  ← per-vertical variable checklist
├── _template/                ← clone skeleton (replace placeholders)
│   ├── DIAGNOSTIC_TOOL/      ← step 1 sales
│   ├── CORE_OFFER/           ← step 2 core (+ bump on checkout)
│   │   └── thank-you/        ← step 5a core buyers
│   ├── ASSIST_TOOL/          ← step 3 upsell 1
│   └── case-study-VERTICAL/  ← step 4 upsell 2
│       └── thank-you/        ← step 5b $497 buyers
├── verticals/                ← one folder per live vertical (cloned from _template)
├── drafts/                   ← quarantine; no live checkout links
└── logs/
```

## Per-vertical variables to fill
| Variable | Example |
|---|---|
| `vertical_name` | `payroll` |
| `diagnostic_tool_name` + path | `wage-leak-checker` → `wage-leak-checker/` |
| `assist_tool_name` + path | `payroll-assist` → `payroll-assist/` |
| `core_offer_slug` | `wage-leak-fix` |
| `retainer_band_low` | `1500` |
| `retainer_band_high` | `4500` |
| 4 product IDs | `main`, `bump`, `oto1`, `oto2` |

Clone: copy `_template/` → `verticals/<vertical_name>/`, rename path folders,
fill `registry/products.json` + `registry/mirror-map.json`, then ship.
