mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-13 15:49:53 +00:00
refactor(skills): move product-launch / pr-to-video / faceless-explainer onto the script-driven architecture (#1635)
* refactor(product-launch-video): restructure onto script-driven architecture Move product-launch-video onto the shared script-driven authoring flow: build-frame remixes a hyperframes-creative preset onto brand tokens, audio routes through the shared hyperframes-media engine, per-preset caption skins, and every frame is authored as a directed shot. Removes the old bespoke scripts (captions/validate/prep/hoist/…) in favour of the shared lib. assemble-index.mjs keeps upstream #1629's blank/partial scene-file guard (reject an empty or markup-less scene file at assembly, before emitting data-composition-src, and re-dispatch) carried onto the restructured reader. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(pr-to-video): restructure onto script-driven architecture Move pr-to-video onto the shared script-driven authoring flow: ingest.mjs folds the gh PR artifacts into the synthetic capture package the shared backend (build-frame / captions / assemble-index) reads, add the mechanism beat, route audio through hyperframes-media, and remix a hyperframes-creative preset onto brand tokens via the shared lib. - Fix skill name: pr-to-video-refactor -> pr-to-video (match directory). - Drop a stale faceless-explainer-refactor reference in an ingest.mjs comment. - assemble-index.mjs keeps upstream #1629's blank/partial scene-file guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(faceless-explainer): restructure onto script-driven architecture Move faceless-explainer onto the shared script-driven authoring flow: every visual is invented (typography / abstract graphics / diagram / data-viz) and authored through the shared backend (build-frame remixes a hyperframes-creative preset onto tokens, audio via hyperframes-media, assemble-index builds the standalone index.html) using the shared lib. - Fix skill name: faceless-explainer-refactor -> faceless-explainer (match directory). - assemble-index.mjs keeps upstream #1629's blank/partial scene-file guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(skills): refresh test-skills-fresh.sh workflow roster Update the install-and-verify harness to the current surface: 10 workflows (adds website-to-video, embedded-captions, graphic-overlays, slideshow; drops the removed footage-recut) and refreshed example prompts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(product-launch-video): oxfmt storyboard.mjs Run oxfmt over lib/storyboard.mjs — formatting only, no logic change. Fixes the Format / Preflight CI check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(studio): import commitGsapPositionFromDrag from its actual module The function was split out into gsapDragPositionCommit.ts in #1605, but the test kept importing it from ./gsapDragCommit, which no longer exports it — yielding 'is not a function' at runtime. Import from the correct module. Inherited main breakage (same fix as #1631); fixes the Test CI check on this branch independently of merge order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(hyperframes): refine router skill metadata tags Update the entry router's metadata tags (video / animation / router focus); oxfmt collapses the now-shorter metadata to a single line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): tighten caption comment-strip + document audio --only merge Review follow-ups (#1635): - captions.mjs (x3): the HTML-comment strip used a single global replace, which CodeQL flags as incomplete multi-character sanitization (a nested/partial pair can re-form a marker the single pass misses). Strip in a fixpoint loop instead. Input is preset-library content, not user-controlled, so this is lint- cleanliness, not XSS defense. - audio.mjs (x3): document that fetch-sfx (--only sfx) MERGES into the neutral audio_engine_meta.json sidecar — the engine reads prev and recomputes only the sfx section, so voices/bgm from the generate pass are preserved (review Q). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): remove existsSync->write TOCTOU in workflow scripts Clears the 9 js/file-system-race CodeQL alerts (captions/audio/transitions x3). Each was an existsSync precheck followed by a later write of the same path: - captions.mjs: caption-overrides shim -> atomic writeFileSync({ flag: 'wx' }). - audio.mjs (sync-durations) + transitions.mjs (inject): drop the existsSync precheck and read directly, surfacing the same friendly error from a try/catch on readFileSync — no check->write gap. Behavior is unchanged (same error messages); these are local single-process deterministic scripts so the race was never a real risk, but this clears the gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(skills): paint root composition ground color in assemble-index Per-frame roots carry data-start/data-duration and get clip-gated against the global timeline at render, so only the first frame's window overlaps global 0 — a frame's own full-bleed background can't serve as the video ground, and every frame after the first renders on the bare body color (black). Paint the ground on the always-present root composition using the project's frame.md canvas color (the same role the caption skin maps to --cap-canvas); fall back to the body letterbox color when frame.md is absent or has no resolvable ground. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(hyperframes): drop router-tag edit (moved to the foundation PR) The entry SKILL.md is rewritten wholesale by the frame-presets/media foundation PR (#1632); editing it here too guaranteed a merge conflict. Restore this file to main and let the router-tag tweak live with the rewrite in #1632, so the two PRs no longer both touch it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d0f0ec29e7
commit
1967901b57
@@ -0,0 +1,111 @@
|
||||
# Code vocabulary — the `code-*` animation blocks
|
||||
|
||||
PR videos run on two kinds of moving picture: **code** (the lines that changed) and **behavior** (what the change _does_ at runtime). This file is the vocabulary for both — the `code-*` blocks for code beats, and the **mechanism beat** (an invented animated diagram, or a `flowchart` / `data-chart`) for behavior beats. A video that is _all_ code reads flat; **alternate the two** (story-design plans the rhythm; see "Showing behavior" below).
|
||||
|
||||
For code beats the registry ships purpose-built **code animation blocks** that render a diff, a typed-on snippet, a morph, a highlight, a scroll, or a 3D/particle/dissolve reveal — far better than hand-built motion. **Reach for one of these first** for any code beat; fall back to hand-authored composition only when none fits.
|
||||
|
||||
- **Step 4 (visual design):** for each `diff` / `before_after` / code beat, name the block in the frame's `scene` (e.g. "the `request()` retry block, ~6 lines, `code-diff`"). One judgment call: which block.
|
||||
- **Step 5 (frame worker):** install the named block and fill it with the real diff/snippet (below). The block is the frame's centerpiece, composited onto claude's navy **Code Surface**.
|
||||
|
||||
## Install + use
|
||||
|
||||
Every block installs the same way (confirmed `packages/cli/src/commands/add.ts`):
|
||||
|
||||
```bash
|
||||
npx hyperframes add <block-name> # writes compositions/<block-name>.html
|
||||
```
|
||||
|
||||
It is a self-contained sub-composition (inlined engine; a paused GSAP timeline the engine seeks per frame). Mount it in the frame as a sub-composition clip:
|
||||
|
||||
```html
|
||||
<div
|
||||
data-composition-id="code-diff"
|
||||
data-composition-src="compositions/code-diff.html"
|
||||
data-start="0"
|
||||
data-duration="6"
|
||||
data-track-index="1"
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
></div>
|
||||
```
|
||||
|
||||
**Customize by editing two globals** in the installed HTML's inline `<script>`:
|
||||
|
||||
- `window.__TOKENS` — the code content, baked as Shiki tokens: `{ <seq>: { lang, theme, bg, fg, states: [ { code, tokens:[ {key, content, color, fontStyle} ] } ] } }`. Replace `code`/`tokens` with the PR's real snippet(s). `fontStyle` is a bitmask (`&1` italic, `&2` bold). The blocks bake `theme: "github-dark"` independently of the `code-snippet-*` themes below.
|
||||
- `window.__BLOCK` — selects the effect + timing: 2D `{ id, effect, seq, line?, duration }`; WebGL `{ id, effect, seq, duration, seed }`.
|
||||
|
||||
The timeline registers synchronously at `window.__timelines[id]`. All blocks are **1920×1080** and **deterministic / seek-safe** (no CSS transitions, no rAF, seeded randomness — never `Math.random` / `Date.now`).
|
||||
|
||||
## The animation blocks
|
||||
|
||||
| Block | What it does | Inputs of note | PR beat |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`code-diff`** | Unified diff inside an editor window: removed lines collapse in red, added lines expand in green, staggered. (6s) | `__TOKENS.diff.states` needs **exactly 2 states** (before, after) — the engine LCS-diffs them. | The diff hunk (before→after); literal add/remove semantics. **The default PR block.** |
|
||||
| **`code-morph`** | One snippet transforms into another — shared tokens glide (FLIP), leavers fade out, enterers fade in. (7s) | `__TOKENS.morph.states` (2+); reuse the same token `key` across states for a token that should glide. | A refactor / rename / signature change where continuity matters (not add/remove framing). |
|
||||
| **`code-typing`** | Per-character typewriter reveal with a gliding caret. (5s) | single state in `__TOKENS.feature.states[0]`. | A new function / file **written on screen** ("here's what we added"). |
|
||||
| **`code-highlight`** | A blue band sweeps one line; the rest dim. (5s) | `__BLOCK.line` = target line, **0-based here**. single state. | "This one line is the change" — spotlight a changed/important line. Quick callout. |
|
||||
| **`code-scroll`** | "Camera" scrolls a long file to center a target line, dims the rest. (6s) | `__BLOCK.line` = target, **1-based here**. one long state. | Locating the change in a large file. The only block built for long files. |
|
||||
| **`code-3d-extrude`** | Code on a lit, beveled 3D slab that rotates and settles. (8s, WebGL) | single state; `__BLOCK.seed`. `<canvas id="gl">`. | A hero / title code moment ("the feature"). Style over density — not for reading a diff. |
|
||||
| **`code-particle-assemble`** | GPU particles scatter, then fly to the exact glyph pixels and resolve to syntax color. (8s, WebGL) | single state; `__BLOCK.seed`. | A dramatic climax reveal of a key snippet. Flashiest; not for line-by-line reading. |
|
||||
| **`code-shader-dissolve`** | Code "compiles into existence" out of seeded noise with a moving dissolve front + edge glow. (7s, WebGL) | single state; `__BLOCK.seed`. | A "compiles / builds / works now" beat, or a polished snippet reveal. |
|
||||
| **`code-snippet-flight`** | Discrete snippets fly in from the side and assemble into a stacked program (block-level FLIP). (6s) | `__TOKENS.flight.states`. | "The pieces assemble" — several functions/modules coming together. (An animation block despite the `code-snippet-` prefix.) |
|
||||
|
||||
**Gotchas (call out so the worker doesn't trip):**
|
||||
|
||||
- **Fit the cadence to the frame's `data-duration`.** Each block carries its own internal timing — `code-typing` types at a fixed per-character speed, so a snippet that's long relative to a short frame **overruns**: the code never finishes typing within `data-duration`, and the chrome beats around it (an underline, a `+N/−M` count-up) never play. Check **char-count × per-char cadence** (plus the block's settle) against `data-duration`, and tune the timing so the **full block lands inside the frame**. This is the one code-motion knob you MUST set to the frame — you're fitting the _timing_, not redesigning the effect (the typewriter / diff / morph stays the block's).
|
||||
- `code-diff` and `code-morph` need **≥2 baked states**; every other animation block uses a single state.
|
||||
- **Line indexing differs:** `code-highlight` is **0-based** (`line: 1` = the 2nd line); `code-scroll` is **1-based**. Don't off-by-one.
|
||||
- **No caption-safe band.** These are full-bleed 1920×1080 code surfaces with no reserved caption area. When captions are enabled, the frame must keep the code panel clear of the bottom caption keep-out band (composite the block in the top ~83%, or scale/inset it) — the worker owns that, not the block.
|
||||
|
||||
## The `code-snippet-*` theme family (standalone, not palettes)
|
||||
|
||||
These are **NOT palettes you attach to the animation blocks** — each is its own ready-made ~11–12s composition rendering a full developer UI with baked typing and its own timeline. Use one when you want **ambient realistic context** (a real IDE or terminal on screen), not a focused diff. Install the specific one: `npx hyperframes add code-snippet-<name>`.
|
||||
|
||||
- **VS Code workbench (12):** full VS Code window (activity bar, file-tree, tabs, editor with per-char typing, integrated terminal running `pytest`, status bar) in each theme. `dark-plus`, `light-plus`, `dark-modern`, `light-modern`, `dark-2026`, `light-2026`, `monokai`, `solarized-light`, `visual-studio-dark`, `visual-studio-light`, `high-contrast`, `high-contrast-light`. (Each pulls a `background.jpeg` into `assets/`.)
|
||||
- **Apple Terminal (12):** macOS Terminal.app window typing a shell command per profile. `apple-terminal-` + `basic`, `clear-dark`, `clear-light`, `grass`, `homebrew`, `man-page`, `novel`, `ocean`, `pro`, `red-sands`, `silver-aerogel`, `solid-colors`.
|
||||
|
||||
The theme is baked into each block (not chosen at runtime); to use a given look, install that block and edit its `codeLines`. For claude's editorial register, prefer the focused animation blocks on the navy Code Surface; reach for a `code-snippet-*` UI only when "show it in a real editor/terminal" is the point.
|
||||
|
||||
## Showing behavior — the mechanism beat (not a `code-*` block)
|
||||
|
||||
A `code-*` block shows **the code**. It does not show **what the code does**. The single biggest cause of a flat PR video is a body that is all code surfaces — so for any change with a visible runtime behavior, plan a **`mechanism` beat** that _animates the behavior_ (story-design owns the rhythm; this is the vocabulary).
|
||||
|
||||
A mechanism beat is **not** a registry `code-*` block. It is one of:
|
||||
|
||||
- an **invented animated diagram** — SVG / HTML / GSAP the frame worker builds from claude's atoms (hairline-ink nodes / edges / lanes on cream, one coral marker on the active element), the build playing out the behavior across the shot; **or**
|
||||
- a **`flowchart` / `flowchart-vertical`** registry block — a process / pipeline / state flow; **or**
|
||||
- a **`data-chart`** registry block — a perf / metric comparison (two bars or timelines racing).
|
||||
|
||||
`flowchart`, `flowchart-vertical`, and `data-chart` install exactly like a code block (`npx hyperframes add <name>`) and mount as a sub-composition — so when a `mechanism` frame names one in its `scene`, Step 5 pre-installs it alongside the `code-*` blocks. An invented SVG/GSAP diagram needs no install (the worker hand-builds it).
|
||||
|
||||
**What to animate, by what the change touches** (the menu story-design plans from):
|
||||
|
||||
| The change touches… | Animate (the behavior) | Use |
|
||||
| ------------------------------- | ----------------------------------------------------------------------- | ---------------------- |
|
||||
| Retry / backoff / resilience | request lifecycle: fire → 500 → wait (delay growing) → retry → 200 | invented SVG/GSAP |
|
||||
| Caching / memoization | two lanes racing: cold (hits DB) vs cached (hits cache) | invented SVG/GSAP |
|
||||
| Concurrency / parallelism | a serial lane reshaping into parallel lanes | invented / `flowchart` |
|
||||
| Race / ordering bug | the broken flow (dropped items, colliding writers), then the fixed flow | invented SVG/GSAP |
|
||||
| Performance | two timelines / bars racing, the new one finishing first | `data-chart` |
|
||||
| Refactor / migration | a tangled call-graph untangling; same inputs → same outputs | `flowchart` / invented |
|
||||
| New endpoint / pipeline / state | data flowing the new path; a state machine lighting up step by step | `flowchart-vertical` |
|
||||
|
||||
Unlike a `code-*` block (which owns its own animation), the diagram's motion is **yours** — sequence ≥3 effects into entrance (draw the nodes / lanes) → development (run the flow) → settle (the resolved state + one coral emphasis). Never let it enter then freeze.
|
||||
|
||||
## PR beat → block cheat-sheet
|
||||
|
||||
| PR moment | Block(s) |
|
||||
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Diff hunk (before → after) | `code-diff` |
|
||||
| Refactor / rename / signature change (continuity) | `code-morph` |
|
||||
| Failing → passing test (red → green) | `code-morph` or `code-diff` + `code-highlight` on the green line; a `code-snippet-*` VS Code/terminal block for a literal test-runner UI |
|
||||
| New function / file typed on | `code-typing` |
|
||||
| Spotlight one changed line | `code-highlight` |
|
||||
| Walk / scroll a long changed file | `code-scroll` |
|
||||
| Pieces / modules assembling into a feature | `code-snippet-flight` |
|
||||
| Hero / title code moment ("the feature") | `code-3d-extrude` |
|
||||
| "Compiles / builds / works now" reveal | `code-shader-dissolve` |
|
||||
| Big dramatic snippet reveal / climax | `code-particle-assemble` |
|
||||
| A benchmark / metric / count-up | **Not a `code-*` block** — use claude's `number-lockup` (Number/Impact treatment) or the `data-chart` registry block |
|
||||
| **What the change DOES at runtime** (behavior, not code) | **Not a `code-*` block** — a `mechanism` beat: an invented SVG/GSAP diagram, or `flowchart` / `flowchart-vertical` / `data-chart`. See "Showing behavior" above. |
|
||||
| Show the change in a realistic IDE / terminal (ambient) | a `code-snippet-*` VS Code theme (editor) or Apple Terminal profile (CLI run) |
|
||||
@@ -0,0 +1,123 @@
|
||||
# Composition — PR-to-video visual-design judgment
|
||||
|
||||
> The composition-judgment layer for **Step 4 (Visual design)**. You read it while enriching `STORYBOARD.md` frames: which layout, how much frame the hero fills, how many depth layers — **director decisions**. Concrete px (safe margins 96-150), scale (1.05 / 0.92), three-layer `box-shadow`, `perspective` values are the **frame worker's** job; you name the intent in the frame's composition note. Video composition is closer to film / poster design than webpage layout — no scrolling, no reflow; every frame is a fixed canvas, every pixel matters. Default canvas **1920×1080**; portrait `1080×1920` / square `1080×1080` per the storyboard `format`.
|
||||
|
||||
## Squint test
|
||||
|
||||
Squint (or blur the frame). Can you still pick out the most important element, the second, and clear spatial groups? If everything has equal weight after blur, hierarchy is broken — redesign before writing the note. The strongest frames pass this: one dominant block + one supporting structural element, everything else demoted.
|
||||
|
||||
## Canvas zones (conceptual)
|
||||
|
||||
```
|
||||
+--------------------------------------------------+
|
||||
| Optional top chrome |
|
||||
| +----------------------------------------------+ |
|
||||
| | Safe margin | |
|
||||
| | +----------------------------------------+ | |
|
||||
| | | Primary content area | | |
|
||||
| | | (center 65-75% of frame) | | |
|
||||
| | +----------------------------------------+ | |
|
||||
| | | Caption band (bottom ~17%, HARD w/ captions) | |
|
||||
| | +----------------------------------------+ | |
|
||||
| +----------------------------------------------+ |
|
||||
+--------------------------------------------------+
|
||||
```
|
||||
|
||||
- **Top chrome** — rarely needed in a faceless explainer; skip unless a frame intentionally mocks an interface.
|
||||
- **Safe margin** — key content stays off the edges; hero / editorial frames need more air.
|
||||
- **Primary content area** — the center 65-75% is where the eye rests; body text never presses the edge.
|
||||
- **Caption band (bottom ~17%, HARD-reserved when captions are on)** — when the film has captions enabled (the frame's `Captions:` flag), the bottom ~17% of **canvas height** is reserved (landscape 1080h → bottom 180px, y 900-1080; portrait 1920h → bottom 320px, y 1600-1920): primary content and key visuals **cap at the band top**, and a centered hero anchors at **y ≈ 0.42 × height** (landscape ≈454, portrait ≈806), not the canvas midpoint. Background / ambient / surface layers are exempt and may stay full-bleed. Captions disabled → keep the zone clear anyway for bottom-edge consistency across frames.
|
||||
|
||||
You write "hero word centered with generous safe margins"; you do not write `padding: 150px 120px 92px`.
|
||||
|
||||
## Portrait & square (non-16:9 canvases)
|
||||
|
||||
The zones, density, hierarchy, and depth principles all still apply; the **aspect ratio** changes, and a wide-frame layout does not transplant into a tall one. Design for the storyboard's `format` from the start — never plan landscape and "crop."
|
||||
|
||||
- **Stack vertically, not side-by-side.** Portrait has little horizontal room: split-screen / triptych / 60-40 asymmetry become **top/bottom stacks**, vertical step lists, stacked bands. Square tolerates side-by-side only for two compact items.
|
||||
- **Vertical center moves with the canvas** — anchor a centered hero around **y ≈ 0.42 × height** (portrait ≈806, square ≈454), not a fixed 540.
|
||||
- **Type runs larger, fewer words per line** — narrow frames wrap long headlines badly; prefer short kinetic lines, bigger type, more vertical rhythm.
|
||||
- **Travels well to portrait:** Centered, Layered Depth, Full-Width Strip (stacked band), vertical Rule-of-Thirds. **Avoid** wide Split Screen and Triptych — use stacked equivalents.
|
||||
- **Density still rules** — primary visual ≥ 40% of canvas, ≥ 3 depth layers, measured against the tall frame; an empty top or bottom third reads as placeholder.
|
||||
|
||||
## 7 composition templates
|
||||
|
||||
Use ≥3 different templates per video (5 frames → 3+, 9 frames → 4+). **Don't default every frame to centered**; never use the same layout class twice in a row.
|
||||
|
||||
1. **Centered (hero / climax)** — one dominant element, generous breathing room. Concept name, key takeaway, the hero word, the closing principle.
|
||||
2. **Rule of thirds** — anchor on a thirds intersection; remaining space carries support or negative space. A mechanism step + its label.
|
||||
3. **Split screen (comparison / dual focus)** — left/right halves carry separate elements. Before/after, common-belief vs reality, two options.
|
||||
4. **Layered depth (immersive)** — foreground / midground / background differ in scale + opacity. Opening hooks, atmosphere, the "imagine…" scenario.
|
||||
5. **Asymmetric (editorial)** — primary content pushed to one side (60/40, 70/30); intentional imbalance → tension + sophistication. A dense diagram with a caption rail.
|
||||
6. **Triptych (three-panel)** — three equal zones for three items / beats at once. The rule-of-three landing.
|
||||
7. **Full-width strip** — one horizontal band (a number line, a timeline, an enumeration), usually ~20% of canvas height.
|
||||
|
||||
## Frame density — avoid empty frames
|
||||
|
||||
Common failure: small elements floating in the center with empty space around them. Every frame must feel **intentionally filled**.
|
||||
|
||||
- **Primary visual occupies ≥ 40% of canvas** — hero text 50-75% height × 60-80% width; a centered card 30-50% × 50-70%; a diagram big enough to read its labels.
|
||||
- **≥ 3 visual layers** — background (gradient / particles / grid) + midground (main content) + foreground (emphasis / decoration).
|
||||
- **Openings and closings** are prone to emptiness — a bare background + a lonely line of text reads as placeholder. Add environmental layers: dual-radial swell, floating particles, brand-color ambient texture, low-opacity scanlines or a hairline grid.
|
||||
- **Text-only frames still need visual elements** — a coined-term card, an icon, a halftone field, brand-derived geometry, an underline that draws on.
|
||||
|
||||
**Fullness test:** could this frame stand as a poster or social graphic? If it looks like a sparse slide → add layers.
|
||||
|
||||
## Negative space
|
||||
|
||||
Whitespace directs attention, it isn't waste. Tight grouping (icon + label) → small spacing; unrelated groups → large separation; asymmetric outer margins feel more designed than equal padding; a hero word keeps large side whitespace so one word carries the weight. **Failure modes:** everything equidistant (no grouping); unintended overlap; text tight against an edge; captions colliding with bottom visuals; the framework's default padding everywhere.
|
||||
|
||||
## In-frame visual hierarchy
|
||||
|
||||
Visual weight, strong → weak: **large element** › **motion** (moving beats static) › **high contrast** › **type scale** › **position** (center + upper third are golden). Combine **at least two** — an element that is large, moving, and upper-third is unquestionably primary.
|
||||
|
||||
A title that is only _larger_ (sharing weight/color/spacing with body) reads weak. Stack dimensions:
|
||||
|
||||
| Dimension | Strong contrast |
|
||||
| --------- | ------------------------------------------- |
|
||||
| Size | 3:1 ratio or larger |
|
||||
| Weight | 800-900 vs 400 |
|
||||
| Color | high contrast against background |
|
||||
| Motion | one element moving vs all else static |
|
||||
| Position | top / left = primary |
|
||||
| Space | large surrounding whitespace vs equidistant |
|
||||
|
||||
## Cards and grouping
|
||||
|
||||
Spacing + alignment can group without a card container. **Use cards** when content is genuinely distinct (a list item, a definition, a stat callout) or when shadow-stacking communicates "lifted." **Don't** card for mere separation (use whitespace) or for a continuous diagram. **Never nest cards** — claustrophobic, muddy hierarchy.
|
||||
|
||||
## Inventing the visual — diagrams, type, data-viz
|
||||
|
||||
This is a **faceless** explainer: the frame's hero is something you design, not a screenshot. The three first-class treatments:
|
||||
|
||||
- **Typographic / kinetic type** — the hero word, the coined term, a number, a short enumeration. Treat type as the subject: full-bleed scale, weight contrast, one emphasized term. Strongest for hooks, concept names, takeaways.
|
||||
- **Abstract graphics** — shapes, fields, paths, geometry that _embody_ the idea (the snowball, the spotlight, the staircase-not-cliff). Build the metaphor the script names; don't decorate with generic bokeh.
|
||||
- **Diagram / data-viz** — nodes + edges, a chart, a number line, a formula, a process flow. The build (each part appearing on beat) is the teaching — design it to assemble, not appear whole.
|
||||
|
||||
Make the invented hero **fill 40-60% of the frame** — a diagram big enough to read, a hero word near full-bleed. Don't shrink the one designed element into decoration around empty space.
|
||||
|
||||
## Depth on a 2D canvas
|
||||
|
||||
Layer **2-3 depth techniques** per frame to avoid a flat poster (concrete perspective / rotate / scale values are the worker's):
|
||||
|
||||
| Technique | Effect |
|
||||
| ---------------- | ------------------------------------------------------------------------------------------ |
|
||||
| Size difference | larger = nearer, smaller = farther |
|
||||
| Blur | blurred = background, sharp = foreground |
|
||||
| Opacity gradient | low = receding, full = primary |
|
||||
| Overlap | foreground partially covers background |
|
||||
| Shadow stacking | three-layer shadow = lift + brand feel |
|
||||
| Motion speed | faster parallax = closer |
|
||||
| Counter-scale | camera pushes toward focus → background appears larger, focal CSS scale <1 but fills frame |
|
||||
|
||||
You write "3 depth layers: background swell + midground diagram + foreground label glow; background counter-scales for the push"; the worker writes the scale values.
|
||||
|
||||
## What should not appear
|
||||
|
||||
Nav bars, footers, cookie banners, scrollbars, cursor arrows, browser chrome, unclickable buttons, generic decorative shapes standing in for a designed metaphor, floating bokeh / purple-to-blue AI gradients (the "default AI cliché," banned). Faceless explainers have no real interface to show — an interface mock is correct **only** when the topic itself is about that interface and the frame intentionally reconstructs it.
|
||||
|
||||
## Composition note example
|
||||
|
||||
> "Composition: asymmetric 60/40 — the node-graph diagram occupies left 60%, the layer label + caption right 40%. Generous safe margin; text capped inside the primary content area. 3 depth layers: background hairline grid + midground graph + foreground active-node glow. Density: primary visual ~55%, ambient adds a 5% scanline."
|
||||
|
||||
One line per frame; never concrete px / scale / shadow recipes (the worker writes those).
|
||||
@@ -0,0 +1,141 @@
|
||||
# Motion language — PR-to-video visual-design judgment
|
||||
|
||||
> The motion-judgment layer for **Step 4 (Visual design)**. You name **each shot's choreography, spring intent, beat rhythm, holds, stillness, and the idle-motion budget** while enriching `STORYBOARD.md` frames; the **frame worker** maps intent to concrete GSAP eases / ms / stagger / code (via `hyperframes-animation`). A good explainer feels like one continuous whole — one camera, one spring feel, **every shot directed across its full length** — not a pile of slides that animate once and freeze. You reference motion by **role**, never by curve: eases / durations resolve from `frame.md`'s motion tokens, named `entry` / `emphasis` / `exit` / `drift` (the pack's exact keys may differ); the worker maps the curve. Between-frame **transitions are not yours** — story names `transition_in`, the harness injects it.
|
||||
|
||||
## A frame is a shot, not a slide
|
||||
|
||||
The single failure that makes an explainer read as PowerPoint: a frame whose content **animates in over the first ~0.8s, then freezes** for the rest of its duration while a slow drift plays underneath. The entrance is not the shot — it's the **first beat** of it. You direct the **whole duration**.
|
||||
|
||||
In explainers especially, the development beat _is_ the teaching: the formula assembling term by term, the diagram gaining a layer, the count-up landing. Don't waste it on a frozen hold.
|
||||
|
||||
Three layers fill a shot, each governed by a different rule:
|
||||
|
||||
| Layer | What | Rule |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
|
||||
| **Camera** (macro) | ONE correlated move on the frame root — slow drift / dolly / push / parallax pan | **always on, the whole shot** — this is the "someone is filming this" layer |
|
||||
| **Choreography** (action) | the beat develops: entrance → mid-shot move (reveal / rearrange / morph / emphasis hit) → settle | **fill the duration** — a shot animated only at entry is a slide |
|
||||
| **Idle life** (texture) | ambient continuation on the 1-2 elements that hold a live slot — breathing, glow, float | **budgeted** — this is where screensaver lives; cap it |
|
||||
|
||||
The reconciliation that matters: **mandate choreography, budget idle life.** Purposeful, sequential motion that carries information should fill the shot; ambient, simultaneous motion that carries none should be capped. Many elements each floating independently reads as _screensaver_; a shot that only enters then freezes reads as _slideshow_. Avoid both — **one camera move + a directed multi-phase action + 1-2 living elements**, nothing scattered.
|
||||
|
||||
## Multi-phase choreography — direct the full shot
|
||||
|
||||
Every non-still frame's timeline is choreographed across its length, not front-loaded into the entrance:
|
||||
|
||||
```
|
||||
entrance → development → settle
|
||||
```
|
||||
|
||||
- **entrance** — the beat's primary content arrives (hero `entry` / `heavy`; groups staggered).
|
||||
- **development (the phase that's usually missing → PPT)** — mid-shot, the content _does something_: a second element reveals, elements rearrange to a new layout, a diagram gains a layer, a count-up runs, an emphasis hit lands on the keyword. This is the motion that separates video from slides.
|
||||
- **settle** — the shot resolves and holds for its read; the camera + idle life continue underneath (never a hard freeze).
|
||||
|
||||
**Architecture:** in hyperframes only the **exit** is forbidden mid-video (the frame unmounts; the harness transition _is_ the exit). Everything _before_ the settle — including rich mid-shot development — is free and seek-safe. Build the development phase; skip only the exit (unless you are the final frame).
|
||||
|
||||
When you name a **`blueprint`**, the development phases come from its recipe — write the composition note **shot-by-shot** to match. When you name **no blueprint**, the **≥3 cited effects ARE the phases** — sequence them (one enters, one develops, one emphasizes); **don't fire them all at t=0**.
|
||||
|
||||
## Spring intent (by role, not curve)
|
||||
|
||||
| Intent | Feel | Use |
|
||||
| ---------- | ------------------------------------------- | --------------------------------------- |
|
||||
| **entry** | confident slight overshoot, settles quickly | primary element entry (default) |
|
||||
| **gentle** | soft slide-in, no overshoot | background elements, subtle motion |
|
||||
| **snappy** | tight overshoot, nearly instant | small icons, labels, list items |
|
||||
| **heavy** | weighted deceleration | large diagrams, hero visuals |
|
||||
| **slam** | bouncy overshoot, intentionally loud | a coined term landing, an impact moment |
|
||||
|
||||
**Consistency:** similar elements share one intent (all labels `snappy`, all hero visuals `heavy`). Don't invent a unique ease + duration per element.
|
||||
|
||||
**Forbidden:** `bounce.out` / `elastic.out` (dated; real objects decelerate, they don't bounce — low overshoot for `entry` is fine, high overshoot only for clearly playful moments); a unique ease+duration per element (visual noise).
|
||||
|
||||
## Duration intent
|
||||
|
||||
Reference by **tier** ("instant feedback" / "state change" / "layout change" / "entry animation"); the worker maps concrete ms / frames at 30fps. **A single entry should not exceed ~800ms** — for a longer buildup, use multi-element stagger or a development phase, **not** one long tween.
|
||||
|
||||
**Phase-to-phase within a shot is swift** — when one element makes way for the next (development), the outgoing move runs ~75% of an entry; arrival is deliberate, hand-off is quick. (The between-frame **exit** is the harness's transition, never your within-shot motion.)
|
||||
|
||||
## Stagger cap
|
||||
|
||||
When staggering N elements, **total ≤ 500ms** (longer feels dragged):
|
||||
|
||||
- **3-7 elements** — normal stagger, total 300-700ms.
|
||||
- **8+ elements** — tighten per-item delay, or stagger only the first few and enter the rest with the last.
|
||||
- Never let stagger run past 500ms.
|
||||
|
||||
## Beat structure across frames (the cross-frame rhythm)
|
||||
|
||||
Rhythmic videos breathe: tension → release → tension → release. A clean reference shape for a ~46s explainer:
|
||||
|
||||
| Phase | Duration | Rhythm | Frame type |
|
||||
| ------------ | -------- | ------------------- | ----------------------------------------- |
|
||||
| Hook + gap | 4-8s | slow build | open the curiosity gap; land the hook |
|
||||
| Concept name | 3-6s | deliberate | name the idea, one breathable beat |
|
||||
| Body build | 12-20s | continuous, layered | the mechanism / steps / items, on a stage |
|
||||
| Landing | 3-5s | still, breathable | the takeaway / principle / CTA |
|
||||
|
||||
Allocate motion by a frame's energy: **high-energy** (hook, a surprising stat) → faster entry, tighter stagger, `snappy`, busier development; **breathable** (concept name, the turn in a story, the landing) → slower entry, `gentle`, longer hold, minimal development; **data / mechanism** (a step, a statistic) → medium rhythm, clean stagger, a count-up or layer-reveal as the development phase.
|
||||
|
||||
## Hold time — read time, not freeze time
|
||||
|
||||
After an element enters it must stay long enough to read (the worker maps concrete frames). "Hold" means **don't cut early** — the camera + idle life keep playing underneath; it is never a hard freeze.
|
||||
|
||||
| Content | Minimum hold |
|
||||
| ----------------------------------- | ------------ |
|
||||
| display text (1-3 words) | ~1s |
|
||||
| short sentence | ~1.5s |
|
||||
| data / statistic | ~1.5s |
|
||||
| diagram / formula | ~2s |
|
||||
| complex visual (multi-part diagram) | ~2.5s |
|
||||
| hero / climax word | ~1-1.4s |
|
||||
|
||||
Narration shorter than the needed hold → the frame's `duration` should still give the visual its read time.
|
||||
|
||||
## Stillness before climax — the marked exception
|
||||
|
||||
A **0.3-0.75s pause** between the major action and its confirmation / result — the silence builds tension before the landing (the turn in a story, the "aha" after a build). It lands **because the rest of the video is choreographed** — stillness is a contrast against motion, so it only reads when motion is the baseline. **Allocate it to only 2-3 frames per video, named in the `## Video direction` block**, where the narration lands a payoff. Stamped on every frame it becomes a tic and flattens the rhythm. Name `stillness-before-climax` in that frame's motion note; even then the camera move continues (still ≠ frozen).
|
||||
|
||||
## The idle-life budget — what may move during the hold
|
||||
|
||||
The 1-2 elements that keep moving _after_ the development settles. This is the layer that, overdone, becomes screensaver — so it is **capped**, not mandated:
|
||||
|
||||
1. **Camera move** — always present (the macro layer above); it alone keeps everything coherently alive.
|
||||
2. **At most 1-2 secondary live elements** — the ones carrying the beat (hero, the active node). Everything else holds.
|
||||
3. Prefer **macro move + depth parallax** over many independent floats.
|
||||
|
||||
Secondary-slot menu (formulas are the worker's): **multiplicative breathing** (hero — small ±2-5% on final scale) · **glow pulse** (the active element) · **sine float** (one decorative cluster at most) · **rotational drift** (3D cards, hero mark) · **orbit** (surrounding icons; counts as the one decorative cluster) · **halftone breathing** (atmospheric frames).
|
||||
|
||||
Multiplicative breathing is the signature for a hero **that holds a live slot** — not stamped on every hero. **Minimum amplitude ±6px or ±2-5% scale** — a 3px micro-float doesn't count.
|
||||
|
||||
## Seek-safe motion — intents that don't survive the renderer
|
||||
|
||||
The frame is a **paused GSAP timeline seeked frame-by-frame**, so some "continuous" intents from a real-time engine cannot render — **don't name them**:
|
||||
|
||||
- **No infinite / forever motion** — "particles loop endlessly," "logo rotates forever," "marquee scrolls on repeat." Idle life is a **finite tween over the hold** (breathe up then back), never `repeat`/`yoyo`.
|
||||
- **No randomness or wall-clock** — `Math.random` particle fields, `Date.now` drift. Every motion is the same on every render; name deterministic motion only.
|
||||
- **Entrance + development only** (exit = final frame only) — the cross-frame exit is the harness's transition.
|
||||
- Express oscillation/breathing as a **bounded finite move**, not a loop.
|
||||
|
||||
## Forbidden — both failure modes
|
||||
|
||||
**Slideshow (under-motion):**
|
||||
|
||||
- Content animates in, then **freezes** for the rest of the shot (the PPT tell).
|
||||
- Only the entrance is animated; the remaining duration is a frozen hold under a drift.
|
||||
- The ≥3 cited effects **all fire at t=0** instead of sequencing into entrance / development / emphasis.
|
||||
- No mid-shot development on a non-still frame.
|
||||
|
||||
**Screensaver (over-motion):**
|
||||
|
||||
- **Every element** floating independently; idle motion with no information.
|
||||
- More than 1-2 elements idling at once; scattered sine floats as the "aliveness."
|
||||
- A 3px micro-float standing in for real motion.
|
||||
|
||||
**Always:**
|
||||
|
||||
- `bounce.out` / `elastic.out`; a bespoke ease+duration per element; `repeat` / `yoyo`; all elements entering simultaneously (must stagger or sequence).
|
||||
|
||||
## Motion note example
|
||||
|
||||
> "Macro: slow dolly-in on the frame root across the whole beat. **Entrance** — the concept word enters `EASE.entry` (heavy); supporting labels snappy-stagger (4 items, ~400ms). **Development** — the diagram gains its second layer, then a count-up runs beneath it. **Stillness-before-climax 0.6s** (allocated frame; only the dolly continues). **Settle** — the takeaway emphasis: text gentle entry + glow; idle hold with the hero word breathing ±3% as the one live element."
|
||||
|
||||
One line for a single-shot frame; **shot-by-shot when the beat is multi-phase** (always, when you named a `blueprint`). Never concrete ease curves / ms / stagger formulas / JS — the worker writes those.
|
||||
@@ -0,0 +1,207 @@
|
||||
# Story design — PR → narrative
|
||||
|
||||
Use this reference in Step 3 to write `STORYBOARD.md` and `SCRIPT.md` for a **PR-to-video** — a code change (the diff, commits, files, +/− stats, and the people behind it) turned into an explainer. There is **no website and no captured assets**; the PR was ingested into `capture/extracted/` in Step 1.
|
||||
|
||||
This file defines the story: what the video explains, in what order, and why each frame exists. It does not define layout, effects, animation, or file syntax. For exact storyboard syntax follow `../hyperframes-core/references/storyboard-format.md` and `../hyperframes-core/references/script-format.md`.
|
||||
|
||||
## Read first
|
||||
|
||||
1. `hyperframes.json` — locked brief: angle (archetype), audience, length, aspect, language.
|
||||
2. `frame.md` — tone, type, design system (the shipped preset is **claude**: warm editorial, a serif that thinks, scarce coral, a navy code surface).
|
||||
3. `capture/extracted/visible-text.txt` — the assembled PR brief: title, meta (`base ← head · +N/−M across F files`), people, body, commits, changed files, and a budget-bounded set of **representative diff hunks**. This is your source of **information**.
|
||||
4. `capture/diff.patch` — the full unified diff, for deeper hunk selection than the brief's excerpt.
|
||||
5. `capture/extracted/people.json` — contributors (author / committers / reviewers / commenters), bot-filtered, each with an avatar in `assets/<login>.png` (for an optional credits close).
|
||||
|
||||
## Output
|
||||
|
||||
- `STORYBOARD.md` — the explanation plan, one frame per beat.
|
||||
- `SCRIPT.md` — the locked narration, only for spoken frames.
|
||||
|
||||
Every frame includes the required storyboard-format fields plus the narrative metadata below.
|
||||
|
||||
## Core rule
|
||||
|
||||
A diff is a list of edits. A video is a guided act of understanding.
|
||||
|
||||
Do **not** narrate the diff file-by-file or read the PR description aloud — that is the single most common failure. **Explain the change** — and where the change has a runtime behavior, **show that behavior in motion** (a `mechanism` beat — see "Show the behavior" below), don't just display the lines that changed. Reorder, merge, omit, compress: surface the one change that matters and drop the incidental churn (lockfile bumps, formatting, generated files) unless it _is_ the story. Scene order comes from narrative design, not from the diff's file order or the commit list.
|
||||
|
||||
Default to a **plain, technical, unhurried developer voice** — accurate, specific, no hype, no marketing gloss. You are explaining a real change to engineers; respect their time and intelligence. `frame.md` (claude) tunes the voice toward considered and literary; it does not change the structure.
|
||||
|
||||
## PR archetypes
|
||||
|
||||
Choose **one** archetype (or name a compound). Each is a complete path through understanding a change — do not splice phases from different archetypes.
|
||||
|
||||
- **Changelog** — "here's what shipped." Hook naming the headline → **2–4 roughly co-equal change items** → ship/wrap. Best for release PRs, multi-change PRs, "what's new in vN." Items are parallel → `cut` / `push-slide` between them. Rule-of-three is strongest when changes compress. An item with a visible behavior can be a `mechanism` mini-demo instead of a bare `diff`.
|
||||
- **Feature-reveal** — "we built X; here's what it does." Hook (the new capability) → name it (`change`) → the new code typing on (`diff`) → **animate what it does (`mechanism`)** → why it matters (`impact`) → close. Best for a PR that adds **one notable feature**. The new code is the protagonist, but the `mechanism` beat is where the viewer _sees_ the feature work — not just reads its diff.
|
||||
- **Fix-explainer** — "this was broken; here's the fix." Symptom/bug (`problem`) → **animate the broken behavior (`mechanism`)** → the fix as a before→after (`diff`) → **the behavior now working (`mechanism`)** or the result (`impact`). Best for bugfix PRs. Seeing the bug _happen_ and then _not_ happen is the turn — a stronger shape (tension → turn → relief) than the diff alone.
|
||||
- **Refactor-walkthrough** — "same behavior, better shape." Hook (the smell / the why) → old shape vs new shape (`before_after`) → **the structure untangling, same inputs → same outputs (`mechanism`)** → payoff (`evidence` — lines removed, perf delta, files touched). Best for refactors, perf, cleanups, migrations. A `mechanism` animation _proves_ "same behavior, better shape" far better than asserting it.
|
||||
|
||||
**Choosing:** one notable new capability → feature-reveal; a bug fix → fix-explainer; a behavior-preserving cleanup/perf/migration → refactor-walkthrough; many co-equal changes / a release → changelog. Tie-breakers: a feature that also fixes a bug → feature-reveal with the fix as one body beat; a fix that needed a small refactor → fix-explainer (the fix is the headline). **Compound:** write `arc` as `"<outer> with <inner>"`, e.g. `"feature-reveal with changelog"`. Outer = the macro arc the viewer rides; inner = the body rhythm.
|
||||
|
||||
## PR-native frame types
|
||||
|
||||
Set each frame's `type` to one of these PR-native values. (The storyboard parser keeps `type` verbatim; it is a narrative + pacing label, not a hard enum.) Each maps to a claude frame treatment and a typical visual — so the type, the design, and the visual stay aligned end to end. Note `mechanism` is the **show-the-behavior** beat (an invented animated diagram), distinct from `diff` (show the code).
|
||||
|
||||
| `type` | The frame's job | claude treatment (frame.md) | typical visual (see code-vocabulary.md) |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
||||
| `hook` | The high-leverage opening 3–5s | Cover | — (or `code-3d-extrude` for a hero code moment) |
|
||||
| `problem` | The bug / smell / pain / why-care the PR resolves | Statement or Pull-quote | `code-highlight` (spotlight the offending line) |
|
||||
| `change` | Name the change / the feature / the PR itself | Statement or Cover | — |
|
||||
| `diff` | The change body — a before→after, a hunk, new code typed on | **Code Surface** (navy) | `code-diff` / `code-morph` / `code-typing` |
|
||||
| `before_after` | Explicit old-shape vs new-shape comparison (refactor/fix) | Code Surface (split / morph) | `code-morph` / `code-diff` |
|
||||
| `mechanism` | **Show what the change DOES at runtime** — the request retrying, the cache filling, serial→parallel, the race resolved | invented diagram on cream (hairline ink + one coral active marker) | **invented SVG/GSAP**; `flowchart` / `flowchart-vertical` / `data-chart` where they fit |
|
||||
| `impact` | The payoff — what now works, what's now possible | Number / Impact | `number-lockup` (no code block needed) |
|
||||
| `evidence` | Concrete grounding — `+N/−M`, a passing test, a benchmark | Number / Impact | `code-diff` red→green / `number-lockup` |
|
||||
| `credits` | Shipped-by close — the humans behind the change | Closing | — (avatar row from `assets/<login>.png`) |
|
||||
| `cta` | The closing ask — pull it, upgrade, read the PR | Closing | — (coral-callout) |
|
||||
|
||||
The body of a PR video **alternates `diff` (show the code that changed) with `mechanism` (show what it does at runtime)**, landing on `impact` / `evidence` (the result). A body that is all `diff` reads as code show-and-tell — the `mechanism` beat is what makes the change _legible_ and is the usual cure for a video that feels flat. Every PR has a change, so at least one `diff` (or `change`) frame always exists; most PRs also have a behavior worth animating.
|
||||
|
||||
## Hook strategy
|
||||
|
||||
The hook is the highest-leverage 3–5 seconds. Pick one:
|
||||
|
||||
| Strategy | When | Example |
|
||||
| ---------------------- | ----------------------------------- | ---------------------------------------------------------- |
|
||||
| Shocking statistic | The change quantifies the stakes | "This PR deletes 1,200 lines." / "40% faster cold starts." |
|
||||
| Counterintuitive claim | The change contradicts intuition | "We made the client slower — and that fixed it." |
|
||||
| Pain validation | The audience already feels the bug | "Every deploy, the same flaky timeout." |
|
||||
| Concept announcement | The change has a name worth landing | "Meet retry-with-backoff." |
|
||||
| Before/after teaser | The diff is the whole story | "One line threw. Now it recovers." |
|
||||
| Stakes / consequence | The "why care now" is a real cost | "This crash hit every user on a flaky network." |
|
||||
| Direct address | The audience is clearly defined | "If you've ever waited on a 5-minute CI run…" |
|
||||
|
||||
Do not open with a generic repo/company description.
|
||||
|
||||
## Clarity / rhetoric technique catalog
|
||||
|
||||
Each frame's `persuasion` is a **named** technique, not "explain the change." Combine when several are active:
|
||||
|
||||
- **Make-concrete** — Worked example (one real request/input) · Analogy (backoff as "knock, wait longer, knock again") · Concretization (abstract change → one tangible code line)
|
||||
- **Reveal-in-order** — Progressive disclosure (the diff one line at a time) · Build-up (the simple call, then the edge case) · Signposting ("before… after…")
|
||||
- **Contrast** — Before/after diff · Old shape vs new shape · The bug vs the fix · Two approaches compared
|
||||
- **Structure** — Rule of three (three changes) · Numbered enumeration · Question→answer · Frame-then-fill (state the shape, then the code)
|
||||
- **Evidence** — `+N/−M` stat · Passing test / green check · Benchmark / perf delta · Causal chain (request → 5xx → retry → success)
|
||||
- **Memory & landing** — Callback (return to the hook's bug) · Distillation (the change in one line) · Generalization (this fix → the principle)
|
||||
|
||||
## Emotional beats
|
||||
|
||||
`beat` is one word or a short compound (e.g. "Recognition and relief"). Avoid generic "positive". A PR video rides a comprehension arc:
|
||||
|
||||
- **Negative valley** — _open the gap_ (`hook`/`problem`): curiosity · frustration · recognition · concern · "ugh, that bug"
|
||||
- **Pivot** — _orient_ (`change`): clarity · orientation · anticipation · focus
|
||||
- **Build** — _build understanding_ (`diff`/`before_after`/`impact`/`evidence`): comprehension · "aha" · confidence · momentum · conviction · relief (for a fix)
|
||||
- **Resolution** — _land_ (`credits`/`cta`): satisfaction · resolve · "ship it" · inevitability
|
||||
|
||||
Compound beats are often strongest: "Recognition _and_ relief" (a fix), "Curiosity _and_ confidence" (a feature).
|
||||
|
||||
## The body is a sequence
|
||||
|
||||
A PR video's core is **2–5 body frames**, each advancing one change / one before→after / one item, building cumulatively. **Alternate `diff` (the code) with `mechanism` (the behavior)** — don't stack code surfaces:
|
||||
|
||||
- **changelog:** a `diff` (or a `mechanism` mini-demo) per change item; parallel → default `cut` / `push-slide`.
|
||||
- **feature-reveal:** `change` (name it) → `diff` (the code, often typing/morphing on) → `mechanism` (animate it working) → `impact`.
|
||||
- **fix-explainer:** `problem` (symptom) → `mechanism` (the bug happening) → `diff` (cause + fix, before→after) → `impact` (result, or a `mechanism` of it working).
|
||||
- **refactor-walkthrough:** `before_after` structure → `mechanism` (the structure untangling, behavior preserved) → an `evidence` numbers beat.
|
||||
|
||||
## Continuity across frames
|
||||
|
||||
This framework builds **one frame per worker** — there is no multi-frame "continue run." A sequence reads as one continuous shot through two storyboard-level levers, both yours:
|
||||
|
||||
1. **A consistent stage** — consecutive body frames share one composition idea (the same navy code window filling in, the same before|after split, the same counter advancing), stated in each frame's `scene` so Step 4 and the workers keep the stage stable.
|
||||
2. **A consistent transition** — pick one seam type for a run (`crossfade` for a soft code reveal, `push-slide` for the next change item) and repeat it.
|
||||
|
||||
When a single element genuinely _transforms_ between two ideas (the failing test flips green, the old function becomes the new one), keep it **within one frame** as a development beat (entrance → transform → settle) — the worker owns that motion (a `code-diff` or `code-morph` block). Note the intent in `scene` / narrative; Step 4 turns it into the block + `effects`.
|
||||
|
||||
## Transitions
|
||||
|
||||
Use only registry transition names in `transition_in`:
|
||||
|
||||
`cut | crossfade | blur-crossfade | push-slide LEFT | push-slide RIGHT | push-slide UP | push-slide DOWN | zoom-through | squeeze`
|
||||
|
||||
Pick 2–3 for the whole video and repeat. Frame 1 is `cut` (no previous frame). Match the seam to the narrative: ordered change items → a consistent `push-slide`; a soft reveal / into-the-cause → `crossfade` / `blur-crossfade`; zooming into a code line or pulling back to the file tree → `zoom-through`; a clean new change item → `cut`.
|
||||
|
||||
## The diff is the centerpiece
|
||||
|
||||
Code beats live on the **navy code surface** (claude's Code Surface treatment) — but the body is **not** all code (pair them with `mechanism` beats, next section). Plan the code beats deliberately:
|
||||
|
||||
- **Feature 2–4 real diff hunks**, named in each frame's `scene` — each a small, legible snippet (~4–12 lines), **never a whole file**. Pull them from `capture/diff.patch` / the brief's "Representative diff."
|
||||
- Name **which code animation block** the frame wants in `scene` (the Step-4 visual phase and the worker read it). See `code-vocabulary.md` for the full map; the short version: before→after = `code-diff`; refactor/rename continuity = `code-morph`; new code written on = `code-typing`; spotlight one line = `code-highlight`; walk a long file = `code-scroll`; a hero reveal = `code-3d-extrude` / `code-particle-assemble`.
|
||||
- Numbers (`+1,204 / −318`, files touched, perf delta) belong on an `impact` / `evidence` frame as a `number-lockup`, **not** read aloud in narration.
|
||||
|
||||
## Show the behavior — the mechanism beat (not just the diff)
|
||||
|
||||
A diff shows **what changed in the code**. It does **not** show **what the change does** — and "what it does" is usually the more memorable, more explanatory beat. The single biggest reason a PR video feels flat is that every body frame is a code surface or a number: it _tells_ (here are the lines, here is the stat) but never _shows_ (here is the request actually recovering).
|
||||
|
||||
A **`mechanism` frame animates the runtime behavior** the PR changes — built as an **invented animated diagram** (SVG / HTML / GSAP on claude's cream ground: hairline-ink nodes / edges / lanes, one coral marker on the active or changed element), where **the build _is_ the teaching** — each part appears on beat, the flow plays out across the shot. It is **not** a code block and **not** a headline. Reach for the `flowchart` / `flowchart-vertical` / `data-chart` registry blocks where they fit; otherwise invent it (composition.md's diagram / abstract-graphics register).
|
||||
|
||||
Plan **at least one `mechanism` beat** for any PR with a visible runtime behavior (most feature and fix PRs have one). What to animate, by what the change touches:
|
||||
|
||||
| The change touches… | Animate (the behavior, not the code) |
|
||||
| ------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| Retry / backoff / resilience | a request lifecycle: fire → 500 → wait (delay growing) → retry → 200 |
|
||||
| Caching / memoization | two lanes racing: cold (slow, hits the DB) vs cached (fast, hits the cache) |
|
||||
| Concurrency / parallelism | a serial single lane reshaping into parallel lanes |
|
||||
| Race / ordering bug | the broken behavior first (items dropped, two writers colliding), then the fixed flow |
|
||||
| Performance | two timelines / bars racing, the new one finishing first (a `data-chart` fits) |
|
||||
| Refactor / migration | a tangled call-graph untangling into a clean one; same inputs → same outputs |
|
||||
| New endpoint / pipeline / state | data flowing through the new path; a state machine lighting up step by step (`flowchart-vertical`) |
|
||||
|
||||
Name the mechanism in the frame's `scene` ("animate the request retrying: fire → 500 → backoff → 200, invented SVG flow") so Step 4 and the worker build it. The `diff` frame and the `mechanism` frame are **complementary** — the diff is the proof in code, the mechanism is the proof in motion; alternate them rather than stacking code surfaces.
|
||||
|
||||
## Optional close: a credits / shipped-by scene
|
||||
|
||||
A PR is shipped by people. `capture/extracted/people.json` lists real contributors (bot-filtered), and Step 1 downloaded each avatar to `assets/<login>.png` (the `avatarFetched: true` entries — confirm with `ls assets/`). `reviewDecision` (e.g. `APPROVED`) is honest grounding.
|
||||
|
||||
> **The PR `author` only opened the PR — not necessarily who wrote the code.** A teammate often authors most commits. Lead the credits with `committer`s by `commitCount`, not the opener.
|
||||
|
||||
You **may** add one closing `credits` frame naming the humans — an avatar row with names + roles + an "approved" check. On that frame only, set `asset_candidates` to 2–6 entries of `assets/<login>.png — <login>, <role>` (commit authors by `commitCount` first, then reviewers; only `avatarFetched: true` logins). The body stays code-only — avatars appear **only** on this close, never decorating a diff frame. This is **optional and tasteful**: a one-line hotfix or a solo PR with no reviews doesn't need a credits roll; a feature or release the team rallied around earns one.
|
||||
|
||||
Every other frame has **no** `asset_candidates` (the visuals are invented downstream from `scene` + the diff).
|
||||
|
||||
## Per-frame length budget — ≤ 9 s, word count is the real measurement
|
||||
|
||||
The largest quality bug in PR videos is **scripts that talk too long**. TTS runs at **~2.2 words/second**, so a 45-word "7-second" script is really 20 seconds, and the visual phase has to pad the tail with idle drift (the video reads as "shimmering"). Budget by word count:
|
||||
|
||||
| Bound | Words (@2.2 wps) | Duration | When |
|
||||
| -------------------------- | ---------------- | ------------ | ----------------------------------------------------------------------------- |
|
||||
| **Soft target — default** | **≤ 19** | **≤ 9 s** | Every frame aims here; the cut stays alive. |
|
||||
| **Exception — ≤ 2 frames** | ≤ 26 | ≤ 12 s | The main `diff` (the one change you must explain) or a causal-chain `change`. |
|
||||
| **Hard cap** | > 26 | > 12 s | Trim or split. |
|
||||
| **Whole-film target** | ≤ ~400 | up to ~3 min | Sweet spot ~30–90 s (≤ ~155 words); the body carries the load. |
|
||||
|
||||
Estimate while writing: `duration ≈ ceil(word_count / 2.2)`. 29 words → 13s (trim); 17 words → 8s; 12 words → 6s. Trim techniques: cut the lead-in clause ("Until now, the agent shipped…" → "The agent shipped…"); move numbers off-script onto a counter; split only when the halves carry distinct beats (cause then effect). **Silent frames are allowed and common** — a diff typing on, a before→after morph, a counter running. Set `voiceover` empty, omit from `SCRIPT.md`, and make `narrativeRole` carry it. A complex change does not need a long script; it needs a careful one — if you can't headline the change in 19 words, the headline isn't sharp yet.
|
||||
|
||||
## Frame template
|
||||
|
||||
```md
|
||||
## Frame N — Short name
|
||||
|
||||
- scene: one clear visual idea — name the hunk/file + the code-\* block ("the request() retry block, ~6 lines, code-diff")
|
||||
- voiceover: "spoken guide text, or empty"
|
||||
- duration: ceil(word_count / 2.2) seconds
|
||||
- transition_in: crossfade
|
||||
- status: outline
|
||||
- src: compositions/frames/NN-short-name.html
|
||||
- type: diff
|
||||
- persuasion: Before/after contrast
|
||||
- beat: comprehension
|
||||
|
||||
narrativeRole: What this frame does in the viewer's understanding (its job, not what's on screen).
|
||||
keyMessage: The one thing the viewer should understand after this frame (one sentence).
|
||||
```
|
||||
|
||||
The `credits` frame additionally carries an `asset_candidates:` line (see the credits section); no other frame does.
|
||||
|
||||
## Final checklist
|
||||
|
||||
- One archetype is named (compound only when explicit); the sequence is narrative-driven, not diff-order-driven.
|
||||
- The opening uses a named hook strategy; you do not read the PR description aloud.
|
||||
- Each frame has one job; the body builds cumulatively, **alternating `diff` (the code) with `mechanism` (the behavior)** + `impact` / `evidence` — not a single isolated body frame, and not an unbroken stack of code surfaces.
|
||||
- Every frame has `type` (PR-native), `persuasion` (a named technique), and `beat` (specific). The emotional arc matches the archetype (fix = frustration → relief; feature = curiosity → confidence).
|
||||
- **2–4 real diff hunks** featured, each a small legible snippet (not a whole file), each naming its `code-*` block in `scene`.
|
||||
- **At least one `mechanism` beat** animates what the change _does_ at runtime (an invented diagram, or a `flowchart` / `data-chart`), named in its `scene` — unless the PR genuinely has no visible behavior (a pure docs / config bump). The body is not an unbroken run of code surfaces.
|
||||
- Transitions use only registry names and repeat 2–3 types; frame 1 is `cut`.
|
||||
- `asset_candidates` is absent on every frame except an optional `credits` close (2–6 `assets/<login>.png` entries, `avatarFetched: true` only).
|
||||
- Each `script` fits the budget — ≤ 19 words / ≤ 9 s default, ≤ 2 frames at the ≤ 26 / ≤ 12 s exception; `duration = ceil(word_count / 2.2)`, not a guess.
|
||||
- `SCRIPT.md` contains only locked spoken narration; silent frames are intentional and omitted from it.
|
||||
@@ -0,0 +1,106 @@
|
||||
# Visual design — PR-to-video per-frame enrichment method
|
||||
|
||||
> The method behind **Step 4 (Frame visual design)**. You (the orchestrator) read it to **enrich `STORYBOARD.md` frames in place** — story-design wrote the skeleton (each frame's `scene`, `voiceover`, `transition_in`, and the narrative fields); you add how each frame **looks and moves**. Each frame is a **directed shot, not a static slide** — you choreograph it across its whole duration. Because a PR video is **mostly faceless, most visuals are invented** — typography, number-lockups, diagrams — so you describe visual elements rather than place captured assets; the exceptions are **code beats** (a ready-made `code-*` block) and the **credits close** (real contributor avatars), both covered below. You write **no HTML** (that's the frame workers). `frame.md` is your palette/type truth. Composition / motion detail lives in `composition.md` + `motion-language.md`; effect & blueprint **bodies** live in `hyperframes-animation`. Adding palette theory or a generic font rule here? Wrong home — `frame.md` + `hyperframes-creative`.
|
||||
|
||||
## Every frame is a directed shot
|
||||
|
||||
A frame's visual layer is choreographed across its **full duration**, not front-loaded into an entrance. The failure that reads as PowerPoint: content animates in over the first ~0.8s, then **freezes** while a slow drift plays under it. So every frame's metadata + note describe a **shot with phases** — `entrance → development → settle` — where _development_ (a reveal, a rearrange, a morph, an emphasis hit, a count-up) is the mid-shot motion that separates video from slides. The shot model and the choreography-vs-idle budget live in `motion-language.md`; here you **encode it into the frame**: the `effects` / `blueprint` ids are the motion vocabulary, and the **composition note sequences them into phases**.
|
||||
|
||||
In explainers, _development_ is often the teaching itself — the formula assembling term by term, the diagram gaining a layer, the count-up landing the statistic. Let the build _be_ the message.
|
||||
|
||||
Deliberate **stillness** is the marked exception — the 2-3 climax/breather frames you allocate in `## Video direction`. Every other frame develops; a held frame outside that allocation is just a slide.
|
||||
|
||||
## What you add to each frame
|
||||
|
||||
Story-design's `## Frame N` block already carries the narrative. You append the visual layer as frame metadata + one composition note (story's role/message prose stays):
|
||||
|
||||
```
|
||||
## Frame 3 — How interest compounds
|
||||
- scene: a snowball rolls downhill, gaining a labeled ring each turn ← refine only if it could read sharper
|
||||
- voiceover: "…" ← story's; leave it
|
||||
- transition_in: crossfade ← story's; leave it
|
||||
- type: feature_showcase ← story's
|
||||
- persuasion: Concretization + progressive disclosure
|
||||
- beat: comprehension
|
||||
- effects: scale-in, layer-reveal, count-up ← you add: cite effect ids (≥3, sequenced into the phases below)
|
||||
- blueprint: messaging-multi-phase ← you add (optional): one multi-phase blueprint id
|
||||
- focal: the snowball ← you add: which INVENTED element is the hero
|
||||
- roles: snowball = foreground subject; hill = background gradient; ring labels = supporting ← you add: each invented element's role
|
||||
- sfx: whoosh-soft, tick ← you add: the sound the beat wants (fetched + mounted at root; never yours to embed)
|
||||
|
||||
Entrance: the snowball seats upper-left on a dim hill gradient. Development: it rolls down across the beat, gaining one labeled ring per turn (layer-reveal) while a small total ticks up (count-up). Settle: the final ring emphasis holds; only the slow camera drift continues. A dense, left-anchored frame.
|
||||
```
|
||||
|
||||
- **`effects`** — name atomic effect **ids** from `hyperframes-animation`'s rules index. **Cite ≥3 when you name no `blueprint`** (the worker composes them into the beat; fewer than 3 reads as generic motion); 1+ as accents when a blueprint already carries the choreography. With no blueprint, those **≥3 effects are the shot's phases** — your note must **sequence them** (one enters, one develops, one emphasizes), not list them as a flat set that all fires at entry. You cite; the worker **reads the recipe body and reproduces it** (not a name-guess).
|
||||
- **`blueprint`** — name **one** multi-phase blueprint id from `hyperframes-animation/blueprints-index.md` when a frame's beat wants a proven multi-phase shape. Two postures — both require the worker to read the recipe body (and run its `examples/<id>.html`) first:
|
||||
- **Reproduce** — the blueprint fits the beat cleanly and the frame's content maps onto its slots; write the composition note shot-by-shot to match.
|
||||
- **Adapt** — the blueprint is the right _structure_ but the content / beat doesn't fit its exact form (or you want a fresher surface). Lead the note with a **`Base / Keep / Depart`** line — `Base:` the blueprint id · `Keep:` its **signature** move (never drop this) · `Depart:` what you change and why. Adapt may **extend or vary, never reduce below the shot model** — never flatten a multi-phase blueprint into a single entrance.
|
||||
|
||||
Choose **Reproduce** when the shape fits as-is, **Adapt** when the structure fits but the form doesn't; **omit** `blueprint` entirely when none fits — then the cited `effects` (≥3) carry the phases (**Compose**).
|
||||
|
||||
- **`focal` / `roles`** — name the **invented** visual elements and their roles. `focal` is the hero element (a hero word, a diagram node, a chart series, a coined-term card). `roles` assigns each element a role: `foreground subject` (the thing the eye lands on, text laid around it), `background` (full-bleed field/gradient/grid, dim 30-50%), `supporting` (labels, secondary shapes, ambient layers). Since there are no captured assets, you are _designing_ these elements, not selecting them — keep them few and load-bearing. A user-supplied `public/<basename>` image, if any, is named in story's `asset_candidates`; treat it as the `focal` cutout or a `background`.
|
||||
- **`sfx`** — name the sound the beat wants (an impact for a slam, a whoosh for a push, a tick for a count). The audio script's `fetch-sfx` pass retrieves it and the assembler mounts it at the root — you only **name** it, never embed an `<audio>` element.
|
||||
- **composition note** — the frame's visual brief: layout, hero, depth layers, the macro move, **and the shot's phases**. **Default to a phased note** — `entrance: … → development: … → settle: …` (mandatory when you named a `blueprint`). A **single still line** is correct only for a deliberately held climax or an allocated stillness frame. Full method → `composition.md` (layout) + `motion-language.md` (phases).
|
||||
|
||||
## PR code beats — name a `code-*` block (the one place you don't invent)
|
||||
|
||||
(Frame `type` values are PR-native — `diff` / `before_after` / `mechanism` / `impact` / `credits` / … from story-design; the enrichment method below is the same regardless of type.)
|
||||
|
||||
For a `diff` / `before_after` / code beat, the frame's centerpiece is a **ready-made `code-*` registry block**, not an invented HTML visual — the one exception to "invent every visual." In that frame:
|
||||
|
||||
- **Name the block in `scene` + `focal`.** Pick the one that fits the beat (before→after = `code-diff`; refactor/rename = `code-morph`; new code written on = `code-typing`; spotlight a line = `code-highlight`; walk a long file = `code-scroll`; a hero reveal = `code-3d-extrude` / `code-particle-assemble`). Full map → `code-vocabulary.md`. Name the hunk too ("the `request()` retry block, ~6 lines"). The block is the `focal`; the Step-5 worker installs + fills it with the real diff.
|
||||
- **`effects` choreograph the surrounding chrome, not the code motion.** The block owns the diff/typewriter/morph animation (it _is_ the development beat). Your `effects` / `blueprint` move the claude **Code Surface** around it — the navy window seating in, a `+N/−M` `count-up`, a coral underline drawing on. Cite 1–3 for that chrome; do not re-specify the code animation itself — the worker only fits the block's cadence to the frame's `data-duration` (a long snippet overruns a short frame otherwise).
|
||||
|
||||
Numbers (`+1,204 / −318`, files touched, perf delta) go on an `impact` / `evidence` frame as a `number-lockup` (claude's Number/Impact treatment) — name it the `focal`, with a `count-up`. The **`credits`** close uses the real `assets/<login>.png` avatars (named in story's `asset_candidates`) as the `focal` — an avatar row; the visual phase features non-empty `asset_candidates` like real assets. A **`mechanism`** frame is also invented — but an **animated diagram of the behavior**, not typography (see the next section). Every other frame (`hook` / `change` / `cta`) is invented typography/graphics per the method above.
|
||||
|
||||
## PR mechanism beats — invent an animated diagram of the behavior
|
||||
|
||||
A **`mechanism`** frame is the **show-the-behavior** beat — the antidote to a video that only shows code + text. Its `focal` is an **invented animated diagram** that plays out what the change _does_ at runtime (the request retrying, the cache filling, serial→parallel, the race resolved), **not** a `code-*` block and **not** a headline.
|
||||
|
||||
- **Name the behavior + the diagram in `scene` + `focal`.** e.g. `scene: "animate the request lifecycle — fire → 500 → backoff (delay growing) → retry → 200, invented SVG flow"`; `focal: the request-lifecycle flow`. story-design's "what to animate, by what the change touches" table is the menu. Reach for the `flowchart` / `flowchart-vertical` / `data-chart` registry blocks where they fit (name them in `scene` like a `code-*` block so Step 5 pre-installs them); otherwise the worker builds it in SVG / HTML / GSAP from claude's atoms.
|
||||
- **The build _is_ the development beat.** Unlike a code block (which owns its own animation), the diagram is yours to choreograph: cite **≥3 `effects`** (or a `blueprint`) and **sequence them into the phases** — the lanes / nodes draw on (entrance), the flow runs / the lane splits / the front advances (development), the resolved state + one coral emphasis lands (settle). This is exactly `composition.md`'s "diagram / data-viz where the build is the teaching" register — here the mechanism _is_ the teaching, so never let it enter then freeze.
|
||||
- **Stay on claude's cream ground, hairline-ink.** Nodes / edges / lanes in hairline ink on cream; **one coral marker** on the active or changed element (the retry hop, the cache hit, the new lane); mono labels. Not the navy code surface (that's for code), not heavy shapes / bokeh. Plan it into the top ~83% (caption keep-out).
|
||||
|
||||
`focal` / `roles` name the invented diagram and its parts (the lanes = `foreground subject`; a timeline axis = `supporting`; a dim grid = `background`). A `mechanism` frame carries **no** `asset_candidates` (it's invented, like every non-credits frame).
|
||||
|
||||
## Video direction — write the invariants ONCE
|
||||
|
||||
The whole video shares one look and one motion grammar. State it **once**, at the top of `STORYBOARD.md` (a `## Video direction` block), so every frame inherits it and per-frame metadata carries only the **delta**:
|
||||
|
||||
- **palette system** — from `frame.md`: which roles map to which hues. Never invent.
|
||||
- **motion defaults + shot model** — default eases + the **choreography baseline** (every frame a directed shot: entrance → development → settle) + the **idle-life budget** (what may keep moving during the hold) (→ `motion-language.md`).
|
||||
- **negative list** — what never appears: off-brand textures the pack forbids, **plus both motion failure modes** — slideshow (enter-then-freeze) and screensaver (everything floating independently) (→ `motion-language.md`).
|
||||
- **stillness allocation** — name the 2-3 frames that hold still before a climax; every other frame develops.
|
||||
|
||||
Do **not** repeat these in every frame — each frame's metadata is the delta on top of Video direction.
|
||||
|
||||
## Palette & type — from `frame.md`, never invented
|
||||
|
||||
- **Palette** — `frame.md` (the adopted pack) is the color truth; apply its roles per frame. Generic basics (one accent, tint neutrals, avoid pure `#000`/`#fff`) → `hyperframes-creative/references/house-style.md`.
|
||||
- **Type** — fonts resolve via `frame.md`'s type tokens; reference them **by role** (display / body / mono / the pack's ramp), never by raw family or px. Typography craft (embedded fonts, dark-bg optical compensation, `tabular-nums`) → `hyperframes-creative/references/typography.md`. In a faceless explainer, **type is often the primary visual** — the hero word, the coined term, the kinetic enumeration — so lean on the type ramp hard.
|
||||
|
||||
## Caption-band keep-out (plan side)
|
||||
|
||||
The bottom ~17% of the canvas is reserved for the caption pill. Plan every frame's content into the **top ~83%** so nothing important lands in the band (the worker enforces the pixel cutoff; you plan the layout). Holds even when captions are disabled — bottom-edge consistency. Geometry detail → `composition.md`.
|
||||
|
||||
## Where the detail lives
|
||||
|
||||
| For… | Read |
|
||||
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| composition — zones, density, templates, invented-visual prominence, caption geometry | `composition.md` (local) |
|
||||
| motion — the shot model, phases, idle budget, beat structure, stillness | `motion-language.md` (local) |
|
||||
| effect ids + blueprint ids (vocabulary + recipes) | `../hyperframes-animation/blueprints-index.md` + `../hyperframes-animation/rules-index.md` |
|
||||
| palette + type tokens | the project's `frame.md`; basics → `hyperframes-creative` `house-style.md` / `typography.md` |
|
||||
| transitions | story-design owns `transition_in`; you don't touch it |
|
||||
|
||||
## Before you finish — checklist
|
||||
|
||||
- Every frame has `effects` (≥1 cited id; **≥3 when no `blueprint`** is named); a `blueprint` where the frame matches one, with a shot-by-shot composition note.
|
||||
- **Every frame's composition note is phased** (entrance → development → settle) — not a single entry that then freezes; the ≥3 effects are **sequenced across phases**, not all fired at t=0.
|
||||
- **Stillness is only the 2-3 frames allocated in Video direction**; every other frame develops mid-shot.
|
||||
- Each frame names its **invented** `focal` + per-element `roles` (foreground / background / supporting), kept few and load-bearing.
|
||||
- A `mechanism` frame's `focal` is an **invented animated diagram of the behavior** (or a `flowchart` / `data-chart`), choreographed across its phases — not a code block, not typography; the body is not an unbroken run of code surfaces.
|
||||
- **Video direction** stated once at the top (palette · shot model + idle budget · negative list incl. both failure modes · stillness allocation); per-frame entries are deltas.
|
||||
- Content planned into the top ~83% (caption band clear).
|
||||
- Palette / type pulled from `frame.md` by role — nothing invented.
|
||||
- You wrote no HTML.
|
||||
Reference in New Issue
Block a user