Files
hyperframes/skills/music-to-video/references/planning.md
T
Miao YangandClaude Opus 4.8 265b02738e style(skills): apply oxfmt to music-to-video and router docs
Fixes the Format / Preflight CI checks on the new skill files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 22:04:39 +08:00

105 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Planning (Step 3) — pick the brand, fill every frame
At Step 3 **you (the orchestrator)** turn the Step-2 skeleton into a complete, approved
`STORYBOARD.md`. You edit the **same file** in place: pick the brand spine, then for each
frame decide its **groups**, give each group a treatment, bind real beat anchors, and write
the copy.
Your mantra: **music is the spine; a template is a head start, not a cage; typography is the
floor and assets are an optional ingredient on the same beat grid.**
**You own WHAT, not HOW.** You name the template / primitives, the content, the brand, the
anchor seconds, and the intent. The frame-worker (Step 4) decides HOW — micro-timing,
realization, intra-frame cuts. **Never write millisecond tweens into the storyboard.**
## Inputs
- The Step-2 skeleton already in `STORYBOARD.md` — frames with `span_sec` + `pacing` + `mood` + `feel`.
- `audiomap.json` — timing truth; read the real anchor seconds inside each frame's span.
- [`template-catalog.md`](template-catalog.md) — the template selection menu.
- [`motion-primitive-catalog.md`](motion-primitive-catalog.md) — the free-compose menu (L0 recipes).
- [`montage.md`](montage.md) — asset treatments (only if the user supplied images/videos).
- User brief / supplied copy — topic, mood, exact words to keep.
## Step A — pick the brand spine (one preset, unmodified)
The whole video shares one type family + palette. Pick **one ready-made preset** from
`../hyperframes-creative/frame-presets/` using the preset table in
`../hyperframes-creative/references/design-spec.md` — choose by the track's mood + the brief,
and **only its fonts + colors matter** (templates own composition + motion; the preset only
sets the look). Copy it in **unmodified**:
```bash
cp ../hyperframes-creative/frame-presets/<preset>/FRAME.md "$PROJECT_DIR/frame.md"
```
Then fill the storyboard frontmatter `style` from it: the `font` from its `typography:` and a
≤46 swatch `palette` from its `colors:`. **Quote the hex / family verbatim — never invent or
round.** Every group's palette params draw from this one palette; that unity is what makes
different templates read as one piece.
## Step B — per frame, decide its groups
A frame is usually **one group** (one template or one free composition spanning the frame).
Subdivide into 2+ groups **only when a single treatment can't cover the frame** — e.g. a busy
opener plus a closing lockup. When you split, cut at a **real audiomap anchor** inside the
frame's span (a `key_moment` / `phrase` edge / onset-cluster gap), **never inside a `rolls[]`
run**, and keep every group **≥ ~1 bar**. Density does **not** force more groups — a dense
frame is usually ONE group whose template absorbs the density internally (a meta-template like
`poster-tile-mosaic`). **Group count tracks distinct treatments, not beats.**
## Step C — per group, pick a treatment (exactly one of three)
### A. Match a template
Read [`template-catalog.md`](template-catalog.md). Match the group's `feel` + `mood` + `pacing`
to a template's **Reach for it when**; take the closest fit. Then bind it:
- Fill `params` (keys from the catalog entry) — your copy into text slots, palette from the brand spine, `duration` = the group's span length.
- Fill `role_bindings` with this group's **real anchor seconds** read from `audiomap.json` over its span (not example times).
- If the template's natural stop and the group's span end disagree, snap to the nearest anchor.
### B. Free-compose (no template fits)
Write a `free_design` — one visual thesis from [`motion-primitive-catalog.md`](motion-primitive-catalog.md)
(a dominant system + the named L0 primitives + a density topology) + `anchors` (the real
beat / onset seconds the moves ride). Free-compose is a **first-class** choice, written as
carefully as a matched group — never a failure.
### C. Asset treatment (only when the user supplied assets and they fit)
Make it an `asset` group ([`montage.md`](montage.md)). **Obey `pacing`:** on a `beat_cut`
frame use `beat_cut` (one clip per anchor) or `bg_under_text`; on a `phrase_flow` frame use
`ken_burns` or a slow crossfade — **never** per-onset hard cuts. Assets are additive: if none
fits a group, fall back to template / free (typography is the floor — a complete video needs
no assets).
## Copy (you own the words)
- Keep exact user words; else invent with taste, on the brief's mood.
- **Message vs texture:** a readable word holds ≥1 beat (headline 38, sentence 410), stable + focal; a word held <1 beat is texture (strobe / grid / ticks). Never force a message onto a sub-beat — demote it to texture.
- Place copy into the template's text params, onto a free group's anchors, or as an asset group's `overlay_copy`. Declare the anchor + accumulate / stagger intent; leave micro-timing to the worker.
- A closing logo / CTA lands on the final hit / hard stop and holds through trailing silence.
## Transitions (you do not emit them)
Everything is a **0ms hard cut** for now. **frame → frame** is owned by the assembler
(back-to-back files); adjacent `span_sec` already imply the cut. **group → group inside a
frame** is owned by the worker on its frame timeline; you only set each group's `span_sec`.
## Write + validate
Complete `STORYBOARD.md` ([`storyboard-format.md`](storyboard-format.md)), then run
`node scripts/validate-plan.mjs` and fix every `✗`. Show the user a frame-by-frame summary and
iterate until approved.
## Self-check
- `frame.md` is a verbatim copy of one preset; frontmatter `style.font` / `style.palette` are drawn from it (exact values).
- Every frame became ≥1 group; groups tile the frame span in order; no group < ~1 bar; no group boundary inside a `rolls[]` run.
- Each group is exactly one of template / free_design / asset.
- Template `params` keys match the catalog entry; `role_bindings` / `anchors` use real audiomap seconds.
- Asset treatments obey `pacing` (no `beat_cut` on a `phrase_flow` frame).
- Every group's palette draws from the one brand palette.
- `duration_s == audiomap.audio.duration_sec`; `validate-plan.mjs` passes.