# Video Template Matrix

> **Reframe (2026-04-26).** What follows is two orthogonal axes — video type × render style × delivery — totaling 11 × 9 × 6 = 594 cells. After the recognition recorded in [`docs/multiplane_substrate.md`](multiplane_substrate.md), these are best read as **594 configurations of one engine**, not 594 distinct cells. The engine is a multiplane (z-ordered flat layers + camera traversal + per-layer modulation under attentional constraint). Every video-type is a particular layer stack + camera path + modulation profile; every style is a per-layer rendering choice; every platform is an output-time aspect/duration constraint. The matrix is the configuration space; the multiplane primitive is the engine.

The studio is two orthogonal axes, not one menu:

- **Video type** — the *what*. Brain-rot short, music video, news report, product comparison ("Birkin vs Hermès"), explainer, character intro.
- **Render style** — the *how it looks*. Pixel art, watercolor, Van Gogh, cel-shaded, vector flat, Lego/voxel, photoreal 3D.

Plus a third **delivery target** axis (TikTok 9:16, Reels 4:5, Shorts 9:16, YouTube 16:9, Twitter 1:1) which is mostly aspect-ratio + duration cap, not a real architectural axis — so it's handled as an output-spec post-process, not a separate template.

Any cell of the (video-type × style × delivery) cube should be a one-flag invocation:

```bash
python -m tv.studio.render_project comparison_birkin.project.yaml \
    --style van_gogh --platform tiktok
```

This document is the catalog of what already exists, what's named-but-unbuilt, and what's missing entirely. **It is the source of truth for the template build sequence.**

---

## Axis 1 — Video types

### Existing in `engine/parameter_vocab.yaml`

The 14 genre presets named in `parameter_vocab.yaml:161-192`. Most are slot-lists, not full pipelines.

| Preset | Status | Pipeline | Platform fit |
|---|---|---|---|
| `news_report` | ✅ shipped | `tv/studio/brief_to_project.py` | YouTube long, Shorts cuts |
| `silent_film` | ✅ shipped | `tv/silent_film.py` (Shoreline Ape) | YouTube long |
| `character_intro` | ✅ shipped | `tv/studio/brief_to_project.py` | Reels, Shorts |
| `shorts_brainrot` | ✅ shipped | `tv/studio/brief_to_project.py` + brainrot v5 | TikTok, Reels, Shorts |
| `music_video_parallel` | 📝 named | needs Phase 6 (CLIP match + tracer + librosa) | YouTube, Reels |
| `documentary` | 📝 named | needs Phase 5 (sources) | YouTube long |
| `explainer` | 📝 named | needs Phase 5 (data_viz module) | YouTube, Shorts |
| `editorial_cartoon` | 📝 named | needs caricature humanoid + dream_insert | Twitter, Reels |
| `video_essay` | 📝 named | needs Phase 5 (internet_archive source) | YouTube long |
| `glitch_essay` | 📝 named | extend brainrot effects to full-runtime | YouTube short |
| `abstract_art` | 📝 named | needs `abstract_figure` template | YouTube, Reels |
| `audio_reactive` | 📝 named | needs Phase 6 (audio_track + librosa) | YouTube |
| `vlog` | 📝 named | needs Phase 5 (user_camera source) | YouTube |
| `gaming_commentary` | 📝 named | needs `overlay` source + Phase 5 | YouTube |
| `feature_film` | 📝 named | structured (acts/sequences/scenes), needs Phase 9 (Haiku arc) | YouTube |
| `ambient_long_form` | 📝 named | needs `feedback_echo` foldtoy | YouTube background |

### Missing — to be added

| Preset | Why we need it | Slot list |
|---|---|---|
| `comparison_review` | "Birkin vs Hermès" / luxury-product / two-thing comparisons. High Reels/Shorts demand. | `humanoid(reporter)`, `web_image(item_a)`, `web_image(item_b)`, `parallel_pair`, `data_viz(specs)`, `lower_third` |
| `unboxing` | Single-product narrative. | `humanoid(reporter)`, `web_image(product, multi-angle)`, `tracer(zoom_path)`, `lower_third` |
| `tier_list` | "S-tier to F-tier" ranking videos. | `humanoid(narrator)?`, `web_image(items[])`, `grid_layout(tiers)`, `lower_third` |
| `recipe_short` | Cooking / how-to with steps. | `web_image(ingredients)`, `web_image(steps[])`, `humanoid(narrator)?`, `lower_third(timer)` |
| `react_video` | Picture-in-picture commentator + content. | `humanoid(reporter)`, `web_image|video(content)`, `pip_layout`, `lower_third` |
| `news_explainer_60s` | Compressed news_report for vertical. | inherits `news_report`, `target_duration_s: 60`, `aspect: 9:16` |
| `before_after` | Before/after split-screen, transformation videos. | `web_image(before)`, `web_image(after)`, `wipe_transition`, `humanoid(narrator)?` |
| `top_n_list` | "Top 5 ___" countdown. | `web_image(items[5])`, `humanoid(narrator)?`, `counter_overlay`, `data_viz(rank)` |

These eight aren't speculation — they're the bulk of TikTok/Reels/Shorts traffic. Without them, the studio can ship news but not the formats the platforms reward.

---

## Axis 2 — Render styles

### Backends in `engine/render_registry.yaml`

| Backend | Style family | Status | Resolutions | Compute | Notes |
|---|---|---|---|---|---|
| `pixel_pillow` | pixel_art | ✅ shipped | 16/48/128/512 | CPU | Stardew-lineage, current default |
| `blender_headless` | multipolygon | 🔧 MVP | 480–2160 | CPU/GPU | 3D + toon, MakeHuman base, Phase 4 polish |
| `svg_cairo` | vector | 📝 planned | any | CPU | Vector flat, browser-friendly |
| `cel_shader` | cel | 📝 planned | 720/1080/1440 | CPU/GPU | Anime/cartoon. Blender + toon + outline pass |
| `watercolor_procedural` | painterly | 📝 planned | 720/1080 | CPU | Cairo + stroke-synthesis foldtoy |
| `passthrough_image` | photographic | 📝 planned | source | CPU | Real photos, stock footage |

### Style YAMLs in `tv/styles/`

| Style YAML | Backend | Status | Description |
|---|---|---|---|
| `pixel_art_warm.yaml` | `pixel_pillow` | ✅ shipped | Stardew-lineage 8-bit, prose description |
| `mushroom_institute.yaml` | `pixel_pillow` (inherits pixel_art_warm) | ✅ shipped, locked | Cohesion 0.872, parameterized |

### Missing — named in user requests

| Style YAML | Backend needed | Effort | Notes |
|---|---|---|---|
| `painterly_van_gogh` | `watercolor_procedural` (extended) | Phase 4.5 | Stroke-synthesis with thick impasto + swirl primitives. Reuses watercolor backend with stroke-shape param. |
| `painterly_watercolor` | `watercolor_procedural` | Phase 4.5 | Already planned, paint-bleed + wet-edge primitives |
| `cel_shaded_anime` | `cel_shader` | Phase 4.5 | Toon shader + Freestyle line renderer |
| `vector_flat` | `svg_cairo` | Phase 4.5 | Already planned |
| `voxel_blocks` | `blender_headless` (voxel mode) | Phase 4.5 | Lego/Minecraft register. Cube primitives at gridsize=64. |
| `claymation` | `blender_headless` (rough-displace) | Phase 5 | Subdivision + noise displacement, soft shadows. Wallace-and-Gromit register. |
| `paper_cutout` | `svg_cairo` (layered) | Phase 5 | Monty-Python flat layers + drop shadows |
| `comic_halftone` | `svg_cairo` (halftone fill) | Phase 5 | Lichtenstein / comic-book register, Ben-Day dots |
| `cymatic_abstract` | `svg_cairo` (audio-driven) | Phase 6 | Audio-reactive geometric, paired with `audio_reactive` preset |
| `photoreal_3d` | `blender_headless` (Cycles) | Phase 4 | Already named in humanoid.yaml |

---

## Axis 3 — Delivery platforms

Platforms are NOT separate templates. They're aspect-ratio + duration constraints applied at output time.

| Platform | Aspect | Duration cap | Safe-area margins | Hook timing |
|---|---|---|---|---|
| TikTok | 9:16 (1080×1920) | 60–180 s | top 230px, bottom 180px (UI overlay) | hook in <2s |
| Reels (IG) | 9:16 (1080×1920) | 90 s | top 220px, bottom 220px | hook in <3s |
| Shorts (YT) | 9:16 (1080×1920) | 60 s | top 200px, bottom 320px (subscribe bar) | hook in <3s |
| YouTube long | 16:9 (1920×1080) | unlimited | none | hook in 8–15s |
| Twitter / X | 1:1 (1080×1080) or 16:9 | 140 s (free) | none | hook in <3s |
| Instagram feed | 4:5 (1080×1350) | 60 s | none | hook in <3s |

These become a `platform:` field on the project YAML's `output:` block:

```yaml
output:
  platform: tiktok        # implies 9:16, ≤180s, captions in safe area
  fps: 24
  resolution: [1080, 1920]   # auto-set from platform if omitted
```

The renderer respects safe-area margins by constraining captions to the central band.

---

## The matrix — what works with what

Rows = video types. Columns = styles. ✅ shippable today, 🔧 in MVP, 📝 needs the named backend.

|  | pixel_art_warm | mushroom_institute | watercolor | van_gogh | cel_shaded | vector_flat | voxel_blocks | photoreal_3d | claymation |
|---|---|---|---|---|---|---|---|---|---|
| news_report | ✅ | ✅ | 📝 | 📝 | 📝 | 📝 | 📝 | 🔧 | 📝 |
| silent_film | ✅ | ✅ | 📝 | 📝 | 📝 | 📝 | 📝 | 🔧 | 📝 |
| character_intro | ✅ | ✅ | 📝 | 📝 | 📝 | 📝 | 📝 | 🔧 | 📝 |
| shorts_brainrot | ✅ | ✅ | 📝 | 📝 | 📝 | 📝 | 📝 | 🔧 | 📝 |
| music_video_parallel | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| comparison_review | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| explainer | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| top_n_list | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| react_video | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| recipe_short | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |
| feature_film | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 | 📝 |

Today the green box is `{news_report, silent_film, character_intro, shorts_brainrot} × {pixel_art_warm, mushroom_institute}`. Eight cells. Everything else is missing **either** a video-type pipeline **or** a style backend, and most cells are missing both.

The matrix has 11 × 9 = 99 cells. Nine green, ninety pending.

---

## Build sequence

Two parallel tracks. Each track unlocks a row or column band of the matrix.

### Track V — Video-type pipelines (rows)

Order chosen by platform demand × engineering reuse.

1. **`comparison_review`** — Highest TikTok/Reels demand, reuses news_report cast + adds `parallel_pair` layout. **2–3 days.** Unlocks Birkin-style content immediately.
2. **`top_n_list`** — Highest YouTube/Shorts demand, reuses news_report + counter overlay. **2 days.**
3. **`react_video`** — Picture-in-picture pattern, reuses humanoid + new `pip_layout` source. **2–3 days.**
4. **`recipe_short`** — Reuses web_image + step counter. **2 days.**
5. **`unboxing`** + **`before_after`** — Variants on web_image + tracer. **2–3 days each.**
6. **`music_video_parallel`** — Phase 6 dependency (Phase 6 has CLIP + librosa + tracer). **1–2 weeks** (full Phase 6).
7. **`explainer`** + **`documentary`** — Phase 5 dependency (sources + data_viz). **1 week** after Phase 5.
8. **`feature_film`** — Phase 9 dependency. **2 weeks** after Phase 9.

### Track S — Style backends (columns)

Order chosen by reuse × user demand.

1. **`watercolor_procedural`** — Already planned. Cairo + stroke-synthesis foldtoy. **3–4 days for MVP.**
2. **`painterly_van_gogh`** — Extends watercolor backend with thick impasto + swirl. **2 days after watercolor lands.**
3. **`svg_cairo` + `vector_flat`** — Already planned. Cairo over our existing primitives. **3 days.**
4. **`cel_shader` + `cel_shaded_anime`** — Blender toon + Freestyle. **3–4 days** (Blender backend reuse).
5. **`voxel_blocks`** — Blender voxel grid. Lego register. **3 days** (Blender backend reuse).
6. **`paper_cutout`** — SVG layered. **2 days.**
7. **`comic_halftone`** — SVG halftone fill. **2 days.**
8. **`photoreal_3d`** — Cycles realism. **1 week** (lighting + materials).
9. **`claymation`** — Blender displace + soft. **3 days.**
10. **`cymatic_abstract`** — Audio-driven SVG. Phase 6 dependency. **2–3 days** after Phase 6.

### Critical-path proposal (4 weeks)

| Week | V-track | S-track |
|---|---|---|
| 1 | `comparison_review` + `top_n_list` | `watercolor_procedural` MVP |
| 2 | `react_video` + `recipe_short` | `painterly_van_gogh` + `svg_cairo` |
| 3 | `unboxing` + `before_after` | `cel_shader` + `voxel_blocks` |
| 4 | `news_explainer_60s` + `tier_list` | `paper_cutout` + `comic_halftone` |

**End of week 4:** matrix has 12 video-types × 9 styles green. **108 callable combinations.**

---

## Implementation pattern

Every video-type adds:

1. **`engine/templates/{video_type}.yaml`** — slot list + parameter ranges (mirror humanoid.yaml structure)
2. **`tv/studio/brief_to_project.py`** — preset entry mapping English → ProjectSpec
3. **`tv/studio/projects/_demo_{video_type}.project.yaml`** — concrete demo
4. **Smoke test** — `python -m tv.studio.render_project _demo_{video_type}.project.yaml`

Every style adds:

1. **`tv/styles/{style_id}.yaml`** — parameterized style descriptor (mirror mushroom_institute.yaml)
2. **`backends/{backend_id}/__init__.py`** — `render_scene(scene_yaml, style_yaml, frame_index) → PIL.Image`
3. **`engine/render_registry.yaml`** entry — backend metadata
4. **Cross-style smoke** — render `procedural_cast_smoke` in the new style, side-by-side with shipped pixel_art

Every platform adds:

1. **One row in `engine/parameter_vocab.yaml::output_platforms`** — aspect, duration cap, safe-area
2. **One conditional in `tv/studio/render_project.py`** — apply safe-area constraint at compose time

---

## Pricing alignment

The matrix maps to the pricing tiers:

- **Creator $29/mo** — top 4 video types × 2 shipped styles (the green corner today)
- **Channel $99/mo** — all 12 video types × 5 styles (week-4 milestone)
- **Studio $499/mo** — all + custom template authoring + custom style YAML uploads

Brain rot generator is its own slice: `shorts_brainrot × {pixel_art_warm, mushroom_institute}` at v5 free, v3⊕v4 hybrid at premium.

---

## Photoreal scaffold (2026-04-26)

The photoreal axis is no longer ceded. Photorealism is procedural — a stack of PBR shaders + HDRI lighting + subdivision surfaces + Filmic tone mapping, all of which Blender's Cycles already implements. The studio's `backends/blender_headless/` had Cycles wired in v0.3; the photoreal extension scaffolds atop it.

Files shipped (scaffold, not production-tuned):
- `backends/blender_headless/bpy_photoreal.py` — Principled BSDF + HDRI + subdivision + Filmic, reuses geometry from `bpy_humanoid.py`
- `backends/blender_headless/scene_builder.py` — translates studio character YAML + scene_name + camera_state into a Blender scene dict
- `tv/styles/photoreal_3d.yaml` — style descriptor with per-archetype PBR overrides (humanoid / letterform / mushroom_creature) and HDRI lookup table
- `engine/render_registry.yaml` — `blender_headless` entry now declares `modes: [toon, photoreal_pbr]` with status `mvp_with_photoreal_scaffold`

Resource pipeline:
- User populates `store/cold/hdri/` with CC0 HDRIs from Polyhaven (graceful procedural-sky fallback when missing)
- User populates `store/cold/pbr_materials/` with AmbientCG materials (planned Day 5 of sprint)
- MakeHuman integration planned Day 2 of sprint

The photoreal_3d column is now scaffolded. Filling it to production quality is a focused 1-week sprint (per `tv/styles/photoreal_3d.yaml::sprint_status`). The architecture's claim to compete on the photorealism axis at 1/100,000th the per-second cost of neural inference is now structurally enforceable, not aspirational.

---

## Multiplane operators (Phase 1 shipped 2026-04-26)

Three new operators live on `tv/camera.py::dolly_through` and are applied per-layer in `tv/scenes/layered.py::LayeredScene.render`:

| Operator | Project YAML param | What it does |
|---|---|---|
| Z-axis dolly | `start_z`, `end_z` | Camera translates through the layer stack; per-layer scale grows as camera approaches; layers passed by camera are clipped |
| Atmospheric depth | `atmospheric_strength` | Per-layer haze + cream-tint multiply scaled by z-distance from camera |
| Focal sharpness | `focus_z`, `focus_strength` | Gaussian blur per layer, sigma ∝ \|layer.z − focus_z\| |

Use:

```yaml
- type: line
  speaker: editor_prime
  text: "Verdict: Constance."
  scene_name: shoreline
  camera_move: dolly_through
  camera_params:
    start_z: 0.0
    end_z: 0.45
    focus_z: 0.85
    focus_strength: 0.6
    atmospheric_strength: 0.7
```

See [`tv/multiplane_smoke_test.py`](../tv/multiplane_smoke_test.py) for a 5×5 visual verification panel of each operator independently and combined.

The Birkin demo's verdict line uses all three engaged — proof of the matrix-week-1 deliverable + multiplane phase-1 closure in one render.

---

## Cast extension — alphabet (planned)

26 letter-characters (A–Z) with 2D + 3D realizations, integrated as cast for any video type. See [docs/alphabet_cast.md](alphabet_cast.md). Adds five letter-native video types: `letters_argue`, `alphabet_top_n`, `letter_review`, `phonics_explainer`, `letter_brainrot`. Phase 1–5 ~3.5 working days; Phase 6 (semantic upgrade per SporeOS letters-as-runtime) blocked on user operative definitions.

---

## Open decisions

1. **Comparison-review priority** — confirm this is the first new template (Birkin / Hermès / luxury comparison). Highest revenue match given how saturated TikTok product-comparison content is.
2. **Style-first or video-type-first** — Track S unlocks columns, Track V unlocks rows. Running both in parallel is the plan above. If only one track can run at a time, Track V ships more SKUs faster but at the same look; Track S ships fewer but more visually distinctive videos. Default: parallel.
3. **Van Gogh vs watercolor first** — Van Gogh inherits watercolor; watercolor is the prerequisite. So watercolor first, then Van Gogh as a 2-day extension.
4. **Lego/voxel — Blender or Pillow voxel?** Blender voxel is more correct but Pillow could fake it for pixel-style with cube tiles. Default: Blender once that backend is past MVP.
5. **Where does `editorial_cartoon` fit?** It's already in the parameter vocab but not in this build sequence. Probably Track V week 5 (caricature humanoid is a separate sprite mint).

---

*Last updated 2026-04-25. This is the plan; gaps and changes go directly into the matrix above.*
