Skill Tracer
Skills › HyperFrames › hyperframes › storyboard-format.md

storyboard-format.md

107 lines · skills/hyperframes/references/storyboard-format.md at a595755

Open on GitHub
1# Storyboard format — `STORYBOARD.md` + parsed manifest
2
3Defines the storyboard's **base data format** only: the `STORYBOARD.md` file shape and the `StoryboardManifest` it parses into. Planning the film itself is in [story.md](story.md); the optional narration/TTS file (`SCRIPT.md`) is a separate concern, not here.
4
5A storyboard is the **plan layer** for a video — an ordered set of **frames** (key moments) in one markdown file. Parser: `@hyperframes/core/storyboard` → `StoryboardManifest`.
6

Storyboard format — STORYBOARD.md + parsed manifest

Defines the storyboard's base data format only: the STORYBOARD.md file shape and the StoryboardManifest it parses into. Planning the film itself is in story.md; the optional narration/TTS file (SCRIPT.md) is a separate concern, not here.

A storyboard is the plan layer for a video — an ordered set of frames (key moments) in one markdown file. Parser: @hyperframes/core/storyboard → StoryboardManifest.

Raw lines 1 to 6
7## Frontmatter (global direction)
8
9YAML block at the top. Unknown keys are kept under `globals.extra`.
11| Key | Meaning | Example |
12| ---------- | ------------------------------------------------------------ | ----------------------------------------- |
13| `format` | Canvas size | `1920x1080` |
14| `duration` | The length the person asked for (advisory, not a hard limit) | `22s` |
15| `message` | One-line thesis | `Ship a launch video in an afternoon` |
16| `arc` | Narrative arc | `Hook → Problem → Solution → Proof → CTA` |
17| `audience` | Who it's for | `indie devs on X` |
18| `mode` | Interaction mode (default collaborative) | `autonomous` |
20Set `duration` when the storyboard is first written. It is an expectation, not a gate: compare where the cut actually lands against it — judge whether the drift serves the piece, and update the value when the intended length genuinely changes.

Frontmatter (global direction)

YAML block at the top. Unknown keys are kept under globals.extra.

KeyMeaningExample
formatCanvas size1920x1080
durationThe length the person asked for (advisory, not a hard limit)22s
messageOne-line thesisShip a launch video in an afternoon
arcNarrative arcHook → Problem → Solution → Proof → CTA
audienceWho it's forindie devs on X
modeInteraction mode (default collaborative)autonomous

Set duration when the storyboard is first written. It is an expectation, not a gate: compare where the cut actually lands against it — judge whether the drift serves the piece, and update the value when the intended length genuinely changes.

Raw lines 7 to 21
22## Per-frame sections
24One `## Frame N — Title` heading per frame (`Frame` / `Beat` / `Scene` accepted at H2/H3). Metadata as `- key: value` bullets; everything below them until the next heading is the free-form **narrative**.
26| Key | Meaning |
27| --------------- | ------------------------------------------------------------------------------------------------------------------- |
28| `status` | `outline` → `built` → `animated` (defaults `outline`) |
29| `src` | project-relative path to the frame's HTML sub-composition (the tile poster renders from it) |
30| `duration` | e.g. `4s` |
31| `transition_in` | `crossfade` / `cut` / `wipe` … (alias `transition`); a note only, build it yourself (overlap clips for a crossfade) |
32| `scene` | one-line contact-sheet caption (aliases `description` / `summary` / `caption`) |
33| `voiceover` | the frame's narration _guide_ (aliases `vo` / `voice_over` / `narration`) |
34| `poster` | seconds to seek for the tile poster (past the intro animation) |
35| _any other key_ | kept verbatim under the frame's `extra` — carry your own per-frame data (effects, assets, …) here |
37Two `extra` keys every film plan carries, so the build and the review check the same thing:
39| Key | Meaning |
40| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41| `reads` | what the viewer must understand in this frame, in order, each with its window: `the cursor finds the button (0.4-1.2s); "Export" lands (1.2-2.6s)`. Windows never overlap, and each is long enough for its words (`story.md` §6) |
42| `sound` | the bed, the effects on visible actions, or silence: `bed enters strong; click on Export; whoosh on the cut` |

Per-frame sections

One ## Frame N — Title heading per frame (Frame / Beat / Scene accepted at H2/H3). Metadata as - key: value bullets; everything below them until the next heading is the free-form narrative.

KeyMeaning
statusoutline → built → animated (defaults outline)
srcproject-relative path to the frame's HTML sub-composition (the tile poster renders from it)
duratione.g. 4s
transition_incrossfade / cut / wipe … (alias transition); a note only, build it yourself (overlap clips for a crossfade)
sceneone-line contact-sheet caption (aliases description / summary / caption)
voiceoverthe frame's narration guide (aliases vo / voice_over / narration)
posterseconds to seek for the tile poster (past the intro animation)
any other keykept verbatim under the frame's extra — carry your own per-frame data (effects, assets, …) here

Two extra keys every film plan carries, so the build and the review check the same thing:

KeyMeaning
readswhat the viewer must understand in this frame, in order, each with its window: the cursor finds the button (0.4-1.2s); "Export" lands (1.2-2.6s). Windows never overlap, and each is long enough for its words (story.md §6)
soundthe bed, the effects on visible actions, or silence: bed enters strong; click on Export; whoosh on the cut
Raw lines 22 to 43
44## Parsed manifest
46The parser is **lenient**: it never throws and records anything surprising as a `warning`.
48```
49StoryboardManifest {
50 globals: { format?, message?, arc?, audience?, extra: {…} }
51 frames: Array<{
52 index, number?, title?,
53 status, // "outline" | "built" | "animated"
54 src?, duration? / durationSeconds?, transitionIn?,
55 scene?, voiceover?, poster?,
56 narrative, // markdown below the metadata
57 extra: {…} // unknown keys, preserved
58 }>
59 warnings: Array<{ message, line?, frameIndex? }>
61```

Parsed manifest

The parser is lenient: it never throws and records anything surprising as a warning.

StoryboardManifest {
  globals: { format?, message?, arc?, audience?, extra: {…} }
  frames: Array<{
    index, number?, title?,
    status,                       // "outline" | "built" | "animated"
    src?, duration? / durationSeconds?, transitionIn?,
    scene?, voiceover?, poster?,
    narrative,                    // markdown below the metadata
    extra: {…}                    // unknown keys, preserved
  }>
  warnings: Array<{ message, line?, frameIndex? }>
}
Raw lines 44 to 62
63## `SCRIPT.md` (out of scope here)
65Optional, free-form, **not parsed into the manifest** — the locked-narration file that drives TTS, absent for videos with no narration/TTS. The per-frame `voiceover` above is the storyboard's own narration guide.

SCRIPT.md (out of scope here)

Optional, free-form, not parsed into the manifest — the locked-narration file that drives TTS, absent for videos with no narration/TTS. The per-frame voiceover above is the storyboard's own narration guide.

Raw lines 63 to 66
67## Example
69```markdown
70---
71format: 1920x1080
72message: "Ship a launch video in an afternoon"
73arc: Hook → Problem → Solution → Proof → CTA
74audience: indie devs on X
75---
77## Frame 1 — Hook
79- scene: Big type punches in on the beat
80- duration: 3s
81- poster: 2s
82- transition_in: cut
83- status: animated
84- voiceover: "Ship a launch video in an afternoon."
85- reads: "Ship a launch video" lands (0.3-1.6s); "in an afternoon" (1.6-3.0s)
86- sound: bed enters on its strongest bar; impact on "afternoon"
87- src: compositions/frames/01-hook.html
89Open cold on the promise. This is the thesis — everything after pays it off.
91## Frame 2 — The problem
93- scene: A 20-minute timer spins on a stack of rejected takes
94- duration: 4s
95- transition_in: crossfade
96- status: built
97- voiceover: "The old way? Prompt, wait twenty minutes, get something that misses."
98- src: compositions/frames/02-problem.html
100The old way: prompt, wait, get something that misses. Establish the pain we remove.
101```

Example

---
format: 1920x1080
message: "Ship a launch video in an afternoon"
arc: Hook → Problem → Solution → Proof → CTA
audience: indie devs on X
---

## Frame 1 — Hook

- scene: Big type punches in on the beat
- duration: 3s
- poster: 2s
- transition_in: cut
- status: animated
- voiceover: "Ship a launch video in an afternoon."
- reads: "Ship a launch video" lands (0.3-1.6s); "in an afternoon" (1.6-3.0s)
- sound: bed enters on its strongest bar; impact on "afternoon"
- src: compositions/frames/01-hook.html

Open cold on the promise. This is the thesis — everything after pays it off.

## Frame 2 — The problem

- scene: A 20-minute timer spins on a stack of rejected takes
- duration: 4s
- transition_in: crossfade
- status: built
- voiceover: "The old way? Prompt, wait twenty minutes, get something that misses."
- src: compositions/frames/02-problem.html

The old way: prompt, wait, get something that misses. Establish the pain we remove.
Raw lines 67 to 102
103## Notes
105- A frame with `status: outline` and no built `src` renders as an outline placeholder.
106- `built` is the middle rung: the frame's HTML exists and its **layout is confirmed** (a wireframe sketch or better) — motion not yet added. Nothing is drawn yet beyond the approved layout.
107- Multi-line `voiceover` values collapse to one line on save.

Notes

  • A frame with status: outline and no built src renders as an outline placeholder.
  • built is the middle rung: the frame's HTML exists and its layout is confirmed (a wireframe sketch or better) — motion not yet added. Nothing is drawn yet beyond the approved layout.
  • Multi-line voiceover values collapse to one line on save.
Raw lines 103 to 107