mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-13 07:40:06 +00:00
feat(skills): product-launch-video skill + consolidate motion knowledge into hyperframes-animation (#1745)
* feat(skills): product-launch-video + consolidate motion knowledge into hyperframes-animation
- Add the product-launch-video skill: shot-sequence architecture where each
visual frame is a time-coded shot sequence picked from a blueprint menu and
paced to the voiceover (anti-PowerPoint). Includes the frame-worker sub-agent,
story/visual/motion-design references, and audio/captions/transitions/
stage-assets/assemble-index scripts.
- Consolidate motion knowledge in hyperframes-animation as the single source of
truth: promote the updated atomic rules (31 -> 36) and rename product-launch-
video's archetypes into hyperframes-animation blueprints (13 -> 15, replacing
the old set). product-launch-video, faceless-explainer, and pr-to-video now
reference them via ../hyperframes-animation/{rules-index,blueprints-index}.md
and the rules/blueprints dirs. Fixes the discrete-text-sequence broken links;
blueprints no longer ship per-id runnable examples, so example references in
the consumers were dropped.
- Default HeyGen TTS voice to Marcia (deterministic; was the API's first English
voice, which drifts on catalog re-sort). Override with --voice.
- assemble-index pre-assembly frame guards: auto-repair a sub-comp root missing
canvas dims; hard-fail on <video>/<audio> inside a sub-comp; hard-fail on a
timed non-root element missing class="clip" or overlapping same-track clips.
- Lint/CLI: lint media inside sub-compositions as an error; stop false-positive
caption layout/lint findings; contrast/layout-audit skip elements hidden by an
invisible ancestor.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(skills): clear CodeQL alerts in assemble-index.mjs
- script/style blanking regex now matches closing tags with trailing
whitespace (</script >, </style >) — js/bad-tag-filter (high).
- drop the existsSync precheck before reading/repairing a frame file; read
directly and handle ENOENT, removing the check->write TOCTOU window —
js/file-system-race (high).
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
413d8187fd
commit
05af482f22
@@ -1,119 +0,0 @@
|
||||
# Composition — product-launch 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** — only for workspace-mockup frames; otherwise skip.
|
||||
- **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 → the zone is usable, but keep it 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 (now a 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.
|
||||
- **Real 16:9 screenshots don't fit a tall frame** — never letterbox with dead bars, never stretch-distort. Instead: crop to the salient region; seat it as a top/bottom band with kinetic type filling the rest; or scale it inside a device / browser-frame mock.
|
||||
|
||||
## 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. Brand reveal, key metric, CTA, climax.
|
||||
2. **Rule of thirds** — anchor on a thirds intersection; remaining space carries support or negative space. Feature showcase, demo + description.
|
||||
3. **Split screen (comparison / dual focus)** — left/right halves carry separate elements. Before/after, comparison, problem/solution.
|
||||
4. **Layered depth (immersive)** — foreground / midground / background differ in scale + opacity. Opening hooks, atmosphere, workbench beats.
|
||||
5. **Asymmetric (editorial)** — primary content pushed to one side (60/40, 70/30); intentional imbalance → tension + sophistication. Feature focus, dense info, editorial proof.
|
||||
6. **Triptych (three-panel)** — three equal zones for three capabilities / beats at once.
|
||||
7. **Full-width strip** — one horizontal band (ticker, logo chain, marquee), 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%.
|
||||
- **≥ 3 visual layers** — background (gradient / particles / grid) + midground (main content) + foreground (emphasis / decoration).
|
||||
- **Openings and closings** are prone to emptiness — black background + a lonely line of text reads as placeholder. Add environmental layers: dual-radial swell, floating particles, brand-color ambient texture, low-opacity scanlines.
|
||||
- **Text-only frames still need visual elements** — logo, an asset, icon decoration, halftone field, brand-derived geometry.
|
||||
- **Feature the frame's `asset_candidates`** — story already chose the real assets for this frame (they're the highest-value material); a product screenshot at 60% + supporting text + an ambient layer feels full; the text alone feels empty.
|
||||
|
||||
**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 image** › **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, when a UI-demo group is independently actionable (command row, feature card), or when shadow-stacking communicates "lifted." **Don't** card for mere separation (use whitespace) or for a continuous list. **Never nest cards** — claustrophobic, muddy hierarchy. You write "comparison-split: left/right dual cards, three-layer shadow stack"; the worker writes the `box-shadow`.
|
||||
|
||||
## Asset prominence
|
||||
|
||||
The frame's assets (logos, product images, screenshots) are real and strongly brand-related — feature them, don't shrink them into decoration. A focal product screenshot fills **40-60% of the frame**; a logo stays recognizable at playback size; use the highest-quality version. **Never** replace a real asset with a generic decorative graphic when a real one exists.
|
||||
|
||||
## 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 product + foreground CTA 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 replacing real assets, floating bokeh / purple-to-blue AI gradients (the "default AI cliché," banned). **Exception:** an intentional product-interface reconstruction for a UI-demo frame — nav bars, command panels, timeline tracks, CTA buttons give real context, making it read as a real workflow.
|
||||
|
||||
## Composition note example
|
||||
|
||||
> "Composition: asymmetric 60/40 — product screenshot occupies left 60%, copy + CTA right 40%. Generous safe margin; text capped inside the primary content area. 3 depth layers: background swell + midground screenshot + foreground CTA glow. Density: primary visual ~55%, ambient adds 5% scanline + architectural grid."
|
||||
|
||||
One line per frame; never concrete px / scale / shadow recipes (the worker writes those).
|
||||
@@ -0,0 +1,220 @@
|
||||
# Cut catalog — within-frame seams (worker-built)
|
||||
|
||||
> **A worker build-recipe (Step 5) — the sibling of `../hyperframes-animation/rules/`, not a second motion doc.** These are within-frame cuts the **frame worker builds INSIDE its own composition** (Z-scale + blur + opacity tweens, or per-word x-staggers, all on the frame's own paused GSAP timeline). They are **not** the between-frame transition: story owns that via `transition_in`, which the harness's injector stamps from a **separate registry vocabulary** (`crossfade` / `blur-crossfade` / `push-slide` / `zoom-through` / `squeeze`) — the catalog names here (**cut-the-curve / inverse-zoom / waterfall**) are **not** valid `transition_in` values. Use this catalog when a frame's shot sequence has an internal seam — a within-scene text/element swap, a **Scene-to-Scene** cut (a `Scene` is a time window WITHIN one frame, **not** a frame-to-frame boundary), or a text-to-text line change — and you want it to read as one continuous move instead of a hard slideshow cut. (`zoom-through` lives in both worlds: a whole-frame wrapper transition in the registry, an element-level Z-cut here — same idea, different scope.)
|
||||
|
||||
Four techniques that create depth and continuity:
|
||||
|
||||
1. **Zoom-Through** — within-scene text swaps, Z-axis, moving TOWARD the viewer
|
||||
2. **Inverse Zoom-Through** — Z-axis swaps moving AWAY from the viewer
|
||||
3. **Cut the Curve** — between-scene transitions on x/y
|
||||
4. **Waterfall Cut** — word-by-word cut-the-curve with staggered exits and entries
|
||||
|
||||
All four are the same underlying principle: **cut at peak velocity, match direction and
|
||||
speed on both sides of the cut.** The differences are axis, scope, and granularity.
|
||||
|
||||
**Choosing which at a seam:** for an UNFINISHED phrase (building one larger idea across
|
||||
several visually distinct scenes that still approach the same point — multi-line text, a
|
||||
run of consecutive cards) use **cut-the-curve** / **waterfall**. For a STATE CHANGE (turning
|
||||
to a NEW part of the video — most often hook → context, between two distinct chapters) use
|
||||
**zoom-through**, and **inverse zoom-through** for an arrival / payoff beat. Chain these so
|
||||
the frame's internal seams feel like one camera moving through the content.
|
||||
|
||||
---
|
||||
|
||||
## Blur Logic (applies to all Z-axis variants)
|
||||
|
||||
Blur sells the speed at the cut, but it must scale with the SUBJECT SIZE:
|
||||
|
||||
| Subject | Peak blur | Why |
|
||||
| ------------------------------------------------------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Text-scale (headline, line, word group) | **10px** | At 20px text smears into illegibility — the eye loses the word it was tracking and the cut reads as a glitch, not speed. (Learned 2026-06-10: the until-now inverse zooms shipped at 20px and read mushy; 10px keeps letterforms readable mid-cut.) |
|
||||
| Full-frame surface (terminal window, card, screenshot) | **18–20px** | Big surfaces have edges and texture that survive heavy blur; lighter blur on a full-frame move reads as a rendering hiccup instead of motion. |
|
||||
|
||||
Both sides of a cut use the SAME peak blur — the value must match at the swap frame.
|
||||
Apply blur to the WRAPPER, never to individual children.
|
||||
|
||||
---
|
||||
|
||||
## 1. Zoom-Through (forward)
|
||||
|
||||
### The Problem
|
||||
|
||||
Text enters, holds, exits. Then next text enters, holds, exits. Each text block is
|
||||
independent — no depth, no continuity. The video feels like a slideshow.
|
||||
|
||||
### The Principle
|
||||
|
||||
A velocity-matched cut on the Z-axis. You **never see both texts at the same time.** The
|
||||
outgoing text scales toward the viewer (accelerating), blur and opacity peak at the cut
|
||||
point hiding a hard swap, and the incoming text continues scaling up from behind
|
||||
(decelerating into the focal plane). One continuous forward motion, two different texts.
|
||||
|
||||
### The Three Phases
|
||||
|
||||
**Phase 1: Exit** — text accelerates forward (toward viewer)
|
||||
|
||||
- Scale: `1.0 -> 1.2`, Blur: `0px -> 10px` (text-scale; see Blur Logic), Opacity: `1.0 -> 0.15`
|
||||
- Scale/blur easing: `power3.in` (steep acceleration)
|
||||
- Opacity easing: `none` (linear — even dimming, separated from scale)
|
||||
- Duration: 0.2s
|
||||
|
||||
**Phase 2: Hard cut** at peak velocity + peak blur
|
||||
|
||||
- Outgoing: `opacity: 0` (instant via `tl.set`)
|
||||
- Incoming: `opacity: 0.15, scale: 0.75, blur: 10px` (instant via `tl.set`)
|
||||
- All properties match at the cut: blur, opacity, and scale DIRECTION (both scaling up)
|
||||
|
||||
**Phase 3: Entry** — text continues forward (growing into focal plane)
|
||||
|
||||
- Scale: `0.75 -> 1.0`, Blur: `10px -> 0px`, Opacity: `0.15 -> 1.0`
|
||||
- Easing: `expo.out` (steep initial burst matching exit velocity, long settle)
|
||||
- Duration: 0.5s
|
||||
|
||||
### Why Opacity Must Be Separate on Exit
|
||||
|
||||
Scale uses `power3.in` but that keeps opacity near 1.0 for most of the tween. Splitting
|
||||
opacity to its own tween with linear ease makes the dimming even. On entry, all properties
|
||||
can share `expo.out`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Inverse Zoom-Through (backward)
|
||||
|
||||
The mirror: the camera "pulls back" instead of pushing through. The outgoing element
|
||||
RECEDES away from the viewer; the incoming element arrives OVERSIZED (as if it had been
|
||||
just behind the camera) and retracts into the focal plane. Both move in the shrinking
|
||||
direction — same-direction rule preserved, just reversed.
|
||||
|
||||
**When to use over the forward variant:** arrival beats. The incoming element lands with
|
||||
presence because it comes from larger-than-frame — right for a payoff line ("That changes
|
||||
today."), a giant reply, or a held end-state. Forward zoom-through reads as _progressing
|
||||
through_ content; inverse reads as _arriving at_ content.
|
||||
|
||||
### The Three Phases
|
||||
|
||||
**Phase 1: Exit** — element recedes (away from viewer)
|
||||
|
||||
- Scale: `1.0 -> 0.8`, Blur: `0px -> 10px` (text-scale)
|
||||
- Scale/blur easing: `power3.in`; Opacity: `1.0 -> 0.15` on `none` (separate tween)
|
||||
- Duration: 0.2s
|
||||
|
||||
**Phase 2: Hard cut**
|
||||
|
||||
- Outgoing: `opacity: 0` via `tl.set`
|
||||
- Incoming: `opacity: 0.15, scale: 1.25, blur: 10px` via `tl.set`
|
||||
|
||||
**Phase 3: Entry** — incoming retracts into place
|
||||
|
||||
- Scale: `1.25 -> 1.0`, Blur: `10px -> 0px`, Opacity: `0.15 -> 1.0`
|
||||
- Easing: `expo.out`, Duration: 0.5s
|
||||
|
||||
Shipped examples: `boring → until-now` and `B3 → "That changes today."` (sfx-music-launch);
|
||||
seams 3/4 in claude-paper (`follow-up → thinking`, `thinking → compose UI`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Cut the Curve (Scene Transitions)
|
||||
|
||||
### The Principle
|
||||
|
||||
Use cut-the-curve for **all scene-to-scene transitions** on x and y axes. The outgoing
|
||||
scene's hero element accelerates in one direction, the cut lands mid-motion, and the
|
||||
incoming scene's hero element continues moving in the **same direction** and decelerates.
|
||||
Nothing exits fully off-screen and nothing enters from fully off-screen — **speed plus
|
||||
opacity fading trick the eye**; the partial moves are enough.
|
||||
|
||||
### Same Path, Same Direction
|
||||
|
||||
If Scene A's hero slides left, Scene B's hero enters from the right and continues sliding
|
||||
left. Both move leftward. One continuous motion.
|
||||
|
||||
| Direction | Scene A exit | Scene B entry start | Scene B entry end |
|
||||
| --------- | -------------- | ------------------- | ----------------- |
|
||||
| Leftward | `x: 0 -> -230` | `x: +230` | `x: 0` |
|
||||
| Rightward | `x: 0 -> +230` | `x: -230` | `x: 0` |
|
||||
| Upward | `y: 0 -> -230` | `y: +230` | `y: 0` |
|
||||
| Downward | `y: 0 -> +230` | `y: -230` | `y: 0` |
|
||||
|
||||
### Velocity matching via mirrored eases
|
||||
|
||||
The cleanest match: exit `power4.in` and entry `power4.out` with the SAME distance and
|
||||
duration — mathematically the two halves of one `power4.inOut` composite, so the entering
|
||||
element picks up at exactly the 50% point of the notional path at identical velocity
|
||||
(e.g. 230px / 0.3s ≈ 3,070 px/s at the cut on both sides).
|
||||
|
||||
The fade trick: the exit's opacity completes at ~25–30% of its travel (fade duration
|
||||
≈ 0.18–0.3s vs motion 0.3–0.34s) — the element vanishes while still visibly accelerating,
|
||||
and nothing has to reach the frame edge. Entry fades IN fast from ~0.35 under its
|
||||
deceleration. Time the LAST fading element to die right at the hard cut — gaps where
|
||||
nothing is moving read as awkward dead air.
|
||||
|
||||
### Rules
|
||||
|
||||
- Use cut-the-curve for all scene transitions — it's the default, not an accent
|
||||
- Same direction on both sides; mirrored `.in`/`.out` eases, same distance + duration
|
||||
- Exit duration short (0.2–0.4s), entry duration >= exit duration
|
||||
- Partial travel + fade, never full off-screen moves
|
||||
|
||||
---
|
||||
|
||||
## 4. Waterfall Cut (word-by-word cut-the-curve)
|
||||
|
||||
Cut-the-curve at WORD granularity — the strongest version of the leftward cut for
|
||||
text-to-text seams. Each word of the outgoing line ramps out on its own pronounced curve;
|
||||
each word of the incoming line cascades in mid-flight. The stagger turns the cut into a
|
||||
wave the eye rides across the seam.
|
||||
|
||||
### Exit (per word)
|
||||
|
||||
- Motion: `x: 0 -> -230` over 0.34s on **power4.in** — a much more pronounced ramp than
|
||||
the usual power2: the word barely creeps, then RIPS
|
||||
- Fade: `opacity -> 0` over 0.18s (separate tween, `power1.in`) — completes when the word
|
||||
is only ~25–30% into its travel
|
||||
- Stagger: reading order, ~0.022s per word, timed so the LAST word finishes fading right
|
||||
at the hard cut
|
||||
|
||||
### Entry (per word)
|
||||
|
||||
- `fromTo x: +230 -> 0, opacity: 0.35 -> 1` over 0.3s on **power4.out** — the mirrored
|
||||
back half of the composite; every word ignites already moving at matched velocity
|
||||
- Waterfall stagger with SHRINKING gaps (start 0.05s, multiply by ~0.84 per word) so the
|
||||
cascade accelerates across the line — the cascade should speed up word over word, not run
|
||||
at a flat per-word delay
|
||||
- Pre-set all words to `x: +230, opacity: 0` at build time — `immediateRender: false`
|
||||
alone leaves un-started words sitting visible at rest during the stagger window
|
||||
|
||||
### Whole-line variant
|
||||
|
||||
A single-line beat (e.g. a big intro line) exits as one group with the same pronounced
|
||||
ramp, but stretch its fade to ~0.3s ending ~0.02s before the cut — a lone element that
|
||||
fades early leaves dead air that a word cascade would have covered.
|
||||
|
||||
Shipped example: `until-now.html` B1→B2→B3 (sfx-music-launch).
|
||||
|
||||
---
|
||||
|
||||
## Choosing a Variant
|
||||
|
||||
| | Zoom-Through | Inverse Zoom | Cut the Curve | Waterfall Cut |
|
||||
| -------------- | --------------------------- | --------------------------- | ----------------- | ------------------------- |
|
||||
| Scope | Within-scene text swap | Arrival/payoff beat | Between scenes | Text-to-text seam |
|
||||
| Axis | Z, toward viewer | Z, away from viewer | X / Y | X, per-word |
|
||||
| Peak blur | 10px text / 20px full-frame | 10px text / 20px full-frame | none required | none (fade does the work) |
|
||||
| Opacity at cut | 0.15 | 0.15 | exit faded by cut | last word dies at cut |
|
||||
| Feel | progressing through | arriving at | carried sideways | a wave across the seam |
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
| Don't | Why | Instead |
|
||||
| ---------------------------------------- | ------------------------------------------- | ------------------------------------------------------ |
|
||||
| Two texts visible during a zoom-through | Overlapping text breaks the Z-axis illusion | Hard cut at blur peak, one text at a time |
|
||||
| 20px blur on text-scale subjects | Letterforms smear; reads as a glitch | 10px for text, 18–20px only full-frame |
|
||||
| Elements on different paths across a cut | Eye tracks one direction, cut goes another | Same property, same direction |
|
||||
| Mismatched blur/opacity at the swap | Visible flash or brightness jump | Identical values at the cut frame |
|
||||
| Gentle easing on entry (`power2.out`) | Entry velocity feels slower than exit | Mirror the exit: `power4.out` / `expo.out` |
|
||||
| Full off-screen exits / entries | Wastes time and breaks the speed illusion | Partial travel + early fade |
|
||||
| Lone element fading long before its cut | Dead air at the seam | Fade ends ~0.02s before the cut, or use a word cascade |
|
||||
| Zoom-through on body text | Small text at 0.75 scale is unreadable | Only headlines and short phrases |
|
||||
| Scene cuts without cut-the-curve | Static cuts feel like a slideshow | Cut-the-curve is the default |
|
||||
@@ -1,139 +1,156 @@
|
||||
# Motion language — product-launch visual-design judgment
|
||||
# Motion language — the move vocabulary + the motion doctrine + the seek-safe core
|
||||
|
||||
> 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 promo 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.
|
||||
> The motion layer for **Step 4 (Visual design)**. When you write a frame's **time-coded shot sequence**, you name each scene's move **inline from the vocabulary below** — a named palette of the moves the golden corpus actually uses. Each move carries the **backing rule id** in this skill's local `../hyperframes-animation/rules/`; cite that id so the move resolves to a real recipe when a **frame worker** implements it in Step 5 (the worker reads the rule body in `../hyperframes-animation/rules/<id>.md` — it reproduces the move, it does not guess from the name). You name motion by **role / move name**, never by raw GSAP curve, ms, or stagger formula — the worker maps the curve. Between-frame **transitions are not yours**: story names `transition_in`, the harness injects it; that injected transition **is** the frame's exit. For cuts a worker builds INSIDE a frame (within-scene swaps, scene-to-scene seams), see the catalog in `cut-catalog.md`.
|
||||
|
||||
## A frame is a shot, not a slide
|
||||
A good promo feels like one continuous film — one camera, one motion feel, **smooth and timed to the voiceover** — not a pile of slides that animate once and freeze. The doctrine in Part 2 is load-bearing: when in doubt, do what it says.
|
||||
|
||||
The single failure that makes a promo 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**.
|
||||
---
|
||||
|
||||
Three layers fill a shot, each governed by a different rule:
|
||||
# Part 1 — the move vocabulary
|
||||
|
||||
| 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 |
|
||||
Reach into this palette when naming a scene's motion. Pick the move that matches the beat, name it in the shot sequence, and cite the rule id after `→`. The blueprints (`../hyperframes-animation/blueprints/`) name these same moves in their `rule mapping`; you're drawing from one shared palette. Compose 2–4 across a shot's scenes (entrance → sequential reveal → settle), not all at once.
|
||||
|
||||
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 / UI animation_; 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.
|
||||
## Kinetic type
|
||||
|
||||
## Multi-phase choreography — direct the full shot
|
||||
- **hard-cut / flash word-swap** — a word or line replaces the previous one on an instant cut (no fade/roll); the swap itself is the beat. → `discrete-text-sequence`
|
||||
- **in-place token cycle** — a fixed line holds and only its variable slot changes, token → token → token. → `discrete-text-sequence`
|
||||
- **per-word staggered reveal** — a phrase assembles word-by-word (or chunk-by-chunk), each landing on its own beat. → `dynamic-content-sequencing`
|
||||
- **kinetic beat-slam** — short phrases slam in on a shared percussive beat array, each with a distinct entrance, resolving on a locked finale; the recipe for "punchy / rhythmic" taglines. → `kinetic-beat-slam`
|
||||
|
||||
Every non-still frame's timeline is choreographed across its length, not front-loaded into the entrance:
|
||||
## Typewriter
|
||||
|
||||
```
|
||||
entrance → development → settle
|
||||
```
|
||||
- **type-on with caret** — text types in character-by-character behind a blinking caret. → `discrete-text-sequence` (+ `context-sensitive-cursor` for the caret blink / color)
|
||||
- **backspace-and-retype** — the line types, deletes the last word(s), and retypes a new one (typo-correction, reframe). → `discrete-text-sequence` (+ `context-sensitive-cursor`)
|
||||
|
||||
- **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 card morphs to its next state, 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).
|
||||
## Count-up / data
|
||||
|
||||
**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).
|
||||
- **value-scaled counter** — a number counts up and its font size grows with the value, so the climb itself escalates. → `counting-dynamic-scale`
|
||||
- **bars / progress / star wipe** — a number paired with a graphic that fills: bar-height stagger, a progress bar / ring filling, a fractional star-rating wipe. → `stat-bars-and-fills`
|
||||
|
||||
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** (simultaneous entry collapses three phases into one slide).
|
||||
## Reveal / decode
|
||||
|
||||
## Spring intent (by role, not curve)
|
||||
- **3D char flip-decode** — characters flip in 3D and resolve from scrambled glyphs to the real text (decryption feel). → `hacker-flip-3d`
|
||||
- **SVG self-draw** — an outline / icon / ring draws itself stroke-by-stroke. → `svg-path-draw`
|
||||
|
||||
| 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 | UI elements, small icons, buttons |
|
||||
| **heavy** | weighted deceleration | large images, prototype screenshots, hero visuals |
|
||||
| **slam** | bouncy overshoot, intentionally loud | logo / bell / impact moments |
|
||||
## Camera
|
||||
|
||||
**Consistency:** similar elements share one intent (all icons `snappy`, all hero images `heavy`). Don't invent a unique ease + duration per element.
|
||||
- **push / focus / drift** — a sequential camera move on the frame root (pull-back → focus → push) plus continuous micro-drift; the cinematic baseline. → `multi-phase-camera`
|
||||
- **zoom-to-target** — zoom into a non-centered element (scale + counter-translate to keep it framed). → `coordinate-target-zoom`
|
||||
- **pan / focus-lock** — a virtual camera transforming one `.world` wrapper to pan / zoom / lock onto a region. → `viewport-change`
|
||||
- **camera-cursor-tracking** — the viewport locks to a moving focal point (a typing cursor), static framing then focal-locked tracking. → `camera-cursor-tracking`
|
||||
|
||||
**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).
|
||||
## Layout motion
|
||||
|
||||
## Duration intent
|
||||
- **cluster→outward expansion** — elements start clustered at center and expand outward to their final positions in lockstep. → `center-outward-expansion`
|
||||
- **orbit** — elements flip in from 3D space and settle into a continuous elliptical orbit (entry flips in-place at the orbital position). → `orbit-3d-entry`
|
||||
- **split-tilt cards** — two cards side-by-side with opposing rotationY tilts, entering from their respective sides (comparison / before-after). → `split-tilt-cards`
|
||||
- **logo/avatar ring + connectors** — avatars or logos on an elliptical ring with SVG connection lines to a center point, staggered entry. → `avatar-cloud-network`
|
||||
|
||||
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.
|
||||
## Surface / UI
|
||||
|
||||
**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.)
|
||||
- **3D page-scroll reveal** — a full webpage as a tilted 3D card whose internal content scrolls to reveal specific sections. → `3d-page-scroll`
|
||||
- **cursor click + ripple** — a cursor moves to a target, depresses with it on click, and emits an expanding ripple. → `cursor-click-ripple`
|
||||
- **button press** — a tactile press: compression then spring recovery, optional release burst / glow. → `press-release-spring` (or `physics-press-reaction` for a click that compresses cursor + target together)
|
||||
- **keyword glow** — keywords light up with glow + scale + color on an attack-decay-rest envelope, synced to a word rail. → `asr-keyword-glow`
|
||||
|
||||
## Stagger cap
|
||||
## Morph / handoff
|
||||
|
||||
When staggering N elements, **total ≤ 500ms** (longer feels dragged):
|
||||
- **scale-swap** — two elements at the same screen center hand off: the outgoing cluster shrinks + fades as the incoming one arrives. → `scale-swap-transition`
|
||||
- **card morph-anchor** — a container morphs apparent size + corner radius + surface between two shots, then fades to reveal the real target beneath (HyperFrames uses uniform `scale`, not `width`/`height`). → `card-morph-anchor`
|
||||
|
||||
- **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.
|
||||
## Seam cuts (worker-built, inside a frame)
|
||||
|
||||
## Beat structure across frames (the cross-frame rhythm)
|
||||
The velocity-matched cuts a worker authors between a frame's own Scenes. Name the seam in the shot sequence; the recipe is in the catalog, not a single `../hyperframes-animation/rules/` id.
|
||||
|
||||
Rhythmic videos breathe: tension → release → tension → release. A clean reference shape for a ~46s video:
|
||||
- **zoom-through / inverse zoom-through** — a within-scene swap on the Z-axis; forward reads "progressing through", inverse reads "arriving at" (payoff). → `cut-catalog.md`
|
||||
- **cut-the-curve** — a scene-to-scene cut where both sides move the same direction at matched velocity. → `cut-catalog.md`
|
||||
- **waterfall cut** — cut-the-curve at word granularity, a wave across a text-to-text seam. → `cut-catalog.md`
|
||||
|
||||
| Phase | Duration | Rhythm | Frame type |
|
||||
| -------------- | -------- | ------------------ | ---------------------------------- |
|
||||
| Slow setup | 6-10s | slow build | hero establish, VO not yet present |
|
||||
| Fast montage | 6-10s | ~2s each | quick cuts every 1.5-2s |
|
||||
| Process reveal | 12-18s | continuous, no cut | screen recording, real workflow |
|
||||
| Closure | 3-5s | still, breathable | logo, URL, CTA |
|
||||
## Emphasis / marker
|
||||
|
||||
Allocate motion by a frame's energy: **high-energy** (hook, CTA) → faster entry, tighter stagger, `snappy`, busier development; **breathable** (brand reveal, emotional beat) → slower entry, `gentle`, longer hold, minimal development; **data** (stat, feature) → medium rhythm, clean stagger, count-up as the development phase.
|
||||
- **highlight / circle / burst / scribble** — a marker-drawn emphasis on a word or element: yellow highlight sweep, hand-drawn circle, radiating burst, scribble, or rough sketch-outline. → `css-marker-patterns`
|
||||
|
||||
## Hold time — read time, not freeze time
|
||||
## Aliveness during a hold (use sparingly — see Part 2)
|
||||
|
||||
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.
|
||||
- **subtle jitter** — the sanctioned way to keep a settled frame alive: a small, low-amplitude positional/scale jitter on the held element. The motion-graphics trick that reads "alive" without reading "weak." → `sine-wave-loop` (low-amplitude register)
|
||||
- **live SVG internals** — internal SVG parts move so an icon feels alive (rotating hands, oscillating blades, pulsing dots, dash-flow); fine because it's the subject doing something, not a card breathing. → `svg-icon-enrichment`
|
||||
- **finite bounded ambient** — a single bounded breathe/drift on ONE held hero, only when genuinely needed; de-emphasized — prefer sequential reveal or jitter first. → `sine-wave-loop`
|
||||
|
||||
| Content | Minimum hold |
|
||||
| ------------------------------------ | ------------ |
|
||||
| display text (1-3 words) | ~1s |
|
||||
| short sentence | ~1.5s |
|
||||
| data / statistic | ~1.5s |
|
||||
| product screenshot | ~2s |
|
||||
| complex visual (diagram, comparison) | ~2.5s |
|
||||
| hero / climax word | ~1-1.4s |
|
||||
## The added moves — now backed by local rules
|
||||
|
||||
Narration shorter than the needed hold → the frame's `duration` should still give the visual its read time.
|
||||
Five moves the golden corpus needs were added to this skill's `../hyperframes-animation/rules/`, rounding out the vocabulary above:
|
||||
|
||||
## Stillness before climax — the marked exception
|
||||
- **depth-of-field / selective-blur** — blur the off-focus subset to spotlight the focal element → `depth-of-field-blur`
|
||||
- **motion-blur streak** — directional velocity blur on a fast fly-in / camera push-through → `motion-blur-streak`
|
||||
- **3D depth scatter-assemble** — glyphs/elements scatter into a tumbling 3D cloud, then reassemble → `depth-scatter-assemble`
|
||||
- **spring-pop entrance** — the canonical entrance pop; default to a smooth long-tail settle, overshoot only when explicitly playful → `spring-pop-entrance`
|
||||
- **ambient glow / bloom** — un-triggered soft glow blooming behind a static hero → `ambient-glow-bloom`
|
||||
|
||||
Archive signature: a **0.3-0.75s pause** between the major action and its confirmation / result — the silence builds tension before the landing. 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 (if every frame is already frozen, a pause carries nothing). **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
|
||||
# Part 2 — the motion doctrine (load-bearing)
|
||||
|
||||
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:
|
||||
These four rules are the difference between a clip that reads as a serious launch video and one that reads as an agent-made PowerPoint. Follow them as written.
|
||||
|
||||
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, CTA). Everything else holds.
|
||||
3. Prefer **macro move + depth parallax** over many independent floats.
|
||||
## 1. Smooth beats bouncy — `power3` is the default
|
||||
|
||||
Secondary-slot menu (formulas are the worker's): **multiplicative breathing** (hero — small ±2-5% on final scale) · **glow pulse** (CTA / click target) · **sine float** (one decorative cluster at most) · **rotational drift** (3D cards, hero logo) · **orbit** (surrounding icons; counts as the one decorative cluster) · **halftone breathing** (atmospheric frames).
|
||||
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
||||
|
||||
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; the budget caps how many things idle, it does not license invisible motion.
|
||||
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious launch-video shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle.
|
||||
|
||||
## Seek-safe motion — intents that don't survive the renderer
|
||||
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
||||
|
||||
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**:
|
||||
This is the anti-PowerPoint mechanism — sharper than "put development in the middle."
|
||||
|
||||
- **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; the worker writes it, but don't ask for a loop the timeline can't hold.
|
||||
- **Don't dump everything on screen in the first ~25%** of the scene. Rushing all content in up front is exactly what forces the slideshow feel.
|
||||
- **Reveal each piece — a line, a card, even an h1 — when the voiceover mentions it**, sequencing reveals across the **later ~50%** of the scene. Same amount of agent work, but the cut becomes coherent and gains rhythm.
|
||||
- **Less is more.** Fewer things on screen, each arriving on its VO beat, beats a full canvas that animated once and froze.
|
||||
|
||||
## Forbidden — both failure modes
|
||||
Practically: a frame's shot sequence front-loads almost nothing — the entrance carries only what the VO is saying at t=0, and the rest of the elements wait in the timeline for their spoken cue. A reveal maps onto a development-class move from Part 1 (`per-word staggered reveal`, `cluster→outward expansion`, a `count-up`, an `asr-keyword-glow` synced to the word rail).
|
||||
|
||||
**Slideshow (under-motion):**
|
||||
## 3. No lazy breathing, no bad pan/push — "no motion over bad 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.
|
||||
The agent's two reflexive ways to fake "aliveness" both read cheap:
|
||||
|
||||
**Screensaver (over-motion):**
|
||||
- **No lazy breathing.** Scaling cards/text up and down in a circular loop to look "alive" is the cheap tell. Don't reach for it.
|
||||
- **No bad slow pan / push in the back half.** A slow pan or push on elements in the later ~50% of a scene **disrupts the viewer's sightline and causes eye discomfort** — it actively makes the frame worse, not better.
|
||||
|
||||
- **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.
|
||||
The fix for both is the same: **stagger element reveals in time with the script** (rule 2). And the governing principle: **"I'd rather have NO motion than BAD motion."** A held, still frame is better than a frame kept "alive" by breathing or a drifting camera. The **only sanctioned aliveness** during a hold is **subtle jitter** — a small low-amplitude jitter that keeps a frame from feeling dead without looking weak (it's in Claude videos now). Everything else holds.
|
||||
|
||||
**Always:**
|
||||
## 4. Internal seams are velocity-matched cuts
|
||||
|
||||
- `bounce.out` / `elastic.out`; a bespoke ease+duration per element; `repeat` / `yoyo`; all elements entering simultaneously (must stagger or sequence).
|
||||
When a frame has an internal seam — a within-scene swap, a Scene-to-Scene cut, a text-to-text line change — make it a **velocity-matched cut**, not a hard slideshow cut: cut at peak velocity, match direction and speed on both sides. The catalog (the four techniques, the blur logic, and which to use when) is `cut-catalog.md`; the moves are listed under **Seam cuts** in Part 1.
|
||||
|
||||
## Motion note example
|
||||
## One-line summary
|
||||
|
||||
> "Macro: slow dolly-in on the frame root across the whole beat. **Entrance** — hero enters `EASE.entry` (heavy); icons snappy-stagger (5 items, ~400ms). **Development** — icons rearrange into a row, then the result panel reveals beneath them. **Stillness-before-climax 0.6s** (allocated frame; only the dolly continues). **Settle** — result emphasis: text gentle entry + double-layer glow; idle hold with hero breathing ±3% as the one live element."
|
||||
Smooth long-tail (`power3`) over bouncy; reveal sequentially in the back ~50% timed to the VO (not dumped in the first 25%); no lazy breathing and no bad slow pan/push — prefer stillness, with subtle jitter as the only aliveness; cut at peak velocity with matched direction/speed (→ `cut-catalog.md`).
|
||||
|
||||
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.
|
||||
---
|
||||
|
||||
# Part 3 — the seek-safe core (hard rules)
|
||||
|
||||
The frame is a **paused GSAP timeline seeked frame-by-frame**, so some "continuous" intents from a real-time engine can't render — don't name them. These are non-negotiable regardless of doctrine.
|
||||
|
||||
- **No infinite / forever motion** — "particles loop endlessly," "logo rotates forever," "marquee on repeat." Any aliveness (the subtle jitter, a live SVG internal, a needed bounded ambient) is a **finite tween over the hold**, never `repeat` / `yoyo`.
|
||||
- **No randomness or wall-clock** — no `Math.random` particle fields, no `Date.now` drift. Every render must be identical; name deterministic motion only (stagger and any variation derive from the element index).
|
||||
- **Entrances use `fromTo`** — state the from-state explicitly so a seek to `t=0` lands the element correctly; never rely on a CSS-hidden start (it renders visible before the tween claims it, and flickers under seek).
|
||||
- **No CSS `transition` / `@keyframes` for motion** — CSS animation runs on the browser clock, independent of the HF seek clock; it desyncs and flickers. Drive all motion inside the paused GSAP timeline.
|
||||
- **Entrance + sequential reveal only — no mid-video exit.** The frame unmounts via the harness transition; that injected `transition_in` **is** the exit. Exit motion belongs only to the final frame. (Worker-built seam cuts in `cut-catalog.md` are within-frame, not the frame's exit.)
|
||||
|
||||
## Forbidden — the failure modes
|
||||
|
||||
**Slideshow (the primary failure):** everything dumped on screen in the first ~25%; content enters then freezes; nothing revealed on its VO cue. Fix with rule 2 (sequential reveal timed to the VO).
|
||||
|
||||
**Cheap aliveness:** circular breathing as "life"; a slow pan/push in the back half disrupting the eye; many elements floating independently as "motion." Fix with rule 3 (stillness + subtle jitter only).
|
||||
|
||||
**Bouncy:** `back.out` / `bounce.out` / `elastic.out` as the default entrance; hand-keyed overshoot. Fix with rule 1 (`power3` long-tail; overshoot only when explicitly playful).
|
||||
|
||||
**Always:** no `repeat` / `yoyo`; no `Math.random` / `Date.now`; no all-elements-entering-simultaneously (sequence or stagger).
|
||||
|
||||
## Naming motion in a shot — example
|
||||
|
||||
> Scene 1 (0.0–1.0s): solid field; hero headline enters via **per-word staggered reveal** (`dynamic-content-sequencing`) on a smooth long-tail settle (`power3`); slow **push** on the root (`multi-phase-camera`) holds steady — no back-half re-push.
|
||||
> Scene 2 (1.0–3.0s): as the VO names each capability, five feature icons reveal **sequentially** via **cluster→outward expansion** (`center-outward-expansion`), then a **value-scaled counter** (`counting-dynamic-scale`) ticks up beneath them — the back-half reveal, timed to the script, not dumped at t=0.
|
||||
> Scene 3 (3.0–4.2s): hold on the result; **keyword glow** (`asr-keyword-glow`) lands on the payoff word as the VO says it; settles and holds still — at most **subtle jitter** (`sine-wave-loop`, low amplitude) keeps it alive; no breathing, no drift.
|
||||
|
||||
Name the move + its rule id (or `cut-catalog.md` for a seam cut) per scene; let the worker pick curves, ms, and stagger — defaulting to `power3`.
|
||||
|
||||
@@ -1,267 +1,373 @@
|
||||
# Story design — product launch video
|
||||
|
||||
Use this reference in Step 3 to write `STORYBOARD.md` and `SCRIPT.md` for a product launch, promo, feature reveal, or marketing video.
|
||||
Step 3 of the product-launch flow. Output: `STORYBOARD.md` (the narrative plan, one frame per beat) and `SCRIPT.md` (the locked spoken narration).
|
||||
|
||||
This file defines the story: what the video says, in what order, and why each frame exists. It does not define layout, visual effects, animation, or final markdown schemas. For exact file syntax, follow `../hyperframes-core/references/storyboard-format.md` and `../hyperframes-core/references/script-format.md`.
|
||||
This step decides **what the video says, in what order, and how each beat is said** — and it says each beat in the SHAPE of a proven script. It does not design layout, composition, or motion (that is Step 4). For exact file syntax follow `../hyperframes-core/references/storyboard-format.md` and `../hyperframes-core/references/script-format.md`.
|
||||
|
||||
## What story design produces
|
||||
|
||||
For every beat, four things:
|
||||
|
||||
1. **Position in the SEQUENCE** — the shot order. Story truth decides which beats exist and in what order (the arc).
|
||||
2. **Voiceover written in a blueprint's script shape** — the spoken line, drafted to sound like the proven script for the shape this beat is reaching toward (see the script bank below).
|
||||
3. **A candidate `blueprint:` id** — the proven shot SHAPE this beat leans toward (a tag, not a commitment; Step 4 confirms or overrides).
|
||||
4. **`transition_in`** — how this beat enters from the one before it.
|
||||
|
||||
The big idea: **the blueprint is applied from the very first step.** The blueprints were reverse-engineered from 50 golden clips; each one implies a proven script. So we write the VO in that script's shape from the start — the voiceover is blueprint-shaped before Step 4 ever runs, which makes the blueprint's hit-rate downstream high.
|
||||
|
||||
This is still a SOFT discipline. Story truth comes first: **never invent, bend, drop, or reorder a beat to fit a blueprint.** The script patterns only shape HOW a beat is said and which proven shape it leans toward — they never decide which beats exist.
|
||||
|
||||
## Read first
|
||||
|
||||
Read these inputs before writing:
|
||||
|
||||
1. `hyperframes.json` — locked brief: angle, length, aspect ratio, language.
|
||||
2. `frame.md` — tone, mood, design system, and brand register.
|
||||
2. `frame.md` — tone, mood, design system, brand register.
|
||||
3. `capture/extracted/visible-text.txt` — product facts, page copy, positioning, proof, CTA.
|
||||
4. `capture/extracted/asset-descriptions.md` — the only source for captured asset inventory.
|
||||
4. `capture/extracted/asset-descriptions.md` — the ONLY source for the captured asset inventory.
|
||||
5. `user_script.txt` and `VO_MODE`, when present.
|
||||
|
||||
Do not inspect `capture/assets/`, contact sheets, screenshots, or raw captured files during Step 3. Treat `asset-descriptions.md` as the canonical asset list. Do not invent asset filenames.
|
||||
Do not inspect `capture/assets/`, contact sheets, screenshots, or raw files in Step 3. Treat `asset-descriptions.md` as the canonical asset list. Never invent asset filenames.
|
||||
|
||||
## Output
|
||||
|
||||
Create two files:
|
||||
|
||||
- `STORYBOARD.md` — the narrative plan, one frame per beat.
|
||||
- `SCRIPT.md` — the locked narration, only for spoken frames.
|
||||
|
||||
Every storyboard frame must include the required fields from the storyboard format reference, plus the narrative metadata below.
|
||||
|
||||
## Core rule
|
||||
|
||||
A website is an information layout. A video is an emotional sequence.
|
||||
|
||||
Do not follow page order. Reorder, merge, omit, and reshape captured content into a clear launch story.
|
||||
|
||||
## Step 3 method
|
||||
## Method
|
||||
|
||||
### 1. Extract the product truth
|
||||
|
||||
From the brief and captured text, identify:
|
||||
From the brief and captured text, name:
|
||||
|
||||
- Audience — who the video is speaking to.
|
||||
- Pain or desire — what the viewer already wants fixed or achieved.
|
||||
- Promise — the one-line thesis of the video.
|
||||
- Product role — what the product does in the story.
|
||||
- Proof — features, UI moments, metrics, logos, examples, or demos.
|
||||
- CTA — what the viewer should do next.
|
||||
- **Audience** — who the video speaks to.
|
||||
- **Pain / desire** — what they already want fixed or achieved.
|
||||
- **Promise** — the one-line thesis of the whole video.
|
||||
- **Product role** — what the product does in the story.
|
||||
- **Proof** — features, UI moments, metrics, logos, demos.
|
||||
- **CTA** — what the viewer should do next.
|
||||
|
||||
Write the storyboard around the promise, not around a list of features.
|
||||
Build the sequence around the **promise**, not a feature list. A website is an information layout; a video is an emotional sequence. Reorder, merge, and omit captured content freely — do not follow page order.
|
||||
|
||||
### 2. Match the register to `frame.md`
|
||||
### 2. Choose the arc (the sequence backbone)
|
||||
|
||||
Use `frame.md` as a soft guide:
|
||||
Pick ONE arc — it fixes the beat order. Compound only when useful (e.g. `PAS with feature-benefit progression`).
|
||||
|
||||
| `frame.md` signal | Story effect |
|
||||
| ----------------------------- | ----------------------------------------- |
|
||||
| restrained, editorial, B2B | plain, confident, low-hype script |
|
||||
| bold, kinetic, launch-like | short hooks, punchier beats |
|
||||
| warm, human, playful | friendly direct address, lighter phrasing |
|
||||
| premium, cinematic, spectacle | aspirational framing, fewer words |
|
||||
| Arc | Use when | Beat order |
|
||||
| ------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------- |
|
||||
| `PAS` | Pain is known and urgent (broken B2B workflows). | hook → pain → agitation → solution tease → product intro → proof/demo → CTA |
|
||||
| `Future Pacing` | Sells a new future / category / paradigm. | imagine → name product → remove pain → mechanism → outcome → CTA |
|
||||
| `Demo Loop` | UI is self-explanatory; best shown working. | question → product intro → demo cycle 1 → demo cycle 2 → trust → CTA |
|
||||
| `BAB` | Bridges an old workflow to a better one. | before → after tease → bridge/product → step 1 → step 2 → wow → CTA |
|
||||
| `Feature-Benefit Cascade` | Feature-rich or desire/status-driven. | category hook → feature → benefit → feature → benefit → climax → CTA |
|
||||
|
||||
The product truth decides the arc. The visual system tunes the voice.
|
||||
Use feature→benefit rhythm inside any arc when there are many capabilities — always translate a feature into viewer value, never stack raw features.
|
||||
|
||||
### 3. Choose one outer arc
|
||||
`frame.md` tunes the VOICE, not the arc: restrained/B2B → plain, low-hype; bold/launch → short, punchy; warm/human → friendly direct address; premium/cinematic → aspirational, fewer words.
|
||||
|
||||
Pick one primary arc. Use a compound only when useful, e.g. `PAS with feature-benefit progression`.
|
||||
### 3. Lay out the beats, each with a role
|
||||
|
||||
| Arc | Use when | Beat order | Reveal timing |
|
||||
| ------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------- |
|
||||
| `PAS` | The pain is known and urgent. Best for broken B2B workflows. | hook → pain → agitation → solution tease → product intro → proof/demo → CTA | late |
|
||||
| `Future Pacing` | The product sells a new future, category, or paradigm. | imagine → name product → remove pain → show mechanism → show outcome → CTA | early |
|
||||
| `Demo Loop` | The UI is self-explanatory and the product is best shown working. | question → product intro → demo cycle 1 → demo cycle 2 → trust/benefit → CTA | early |
|
||||
| `BAB` | The product bridges an old workflow to a better one. | before → after tease → bridge/product → step 1 → step 2 → step 3/wow → CTA | early-mid |
|
||||
| `Feature-Benefit Cascade` | The product is feature-rich or desire/status-driven. | product/category hook → feature → benefit → feature → benefit → climax → CTA | frame 1 |
|
||||
|
||||
Use feature-benefit rhythm inside any arc when the video has many capabilities. Do not stack several features without translating them into viewer value.
|
||||
|
||||
### 4. Build the frame sequence
|
||||
|
||||
Each frame needs one clear job. Avoid frames that only say “more benefits” or “another feature.”
|
||||
|
||||
Use these frame types:
|
||||
One clear job per beat — never "more benefits" or "another feature." Beat `type` (= blueprint **role**):
|
||||
|
||||
`hook | pain_point | product_intro | feature_showcase | benefit_highlight | social_proof | branding | cta`
|
||||
|
||||
For every frame, define:
|
||||
The opening 3–5s needs ONE hook that creates tension, curiosity, or desire — a shocking stat, pain validation, a rhetorical question, direct address, an imagine/future-pace, a category announcement, or visual spectacle. Never open with generic company description.
|
||||
|
||||
- `type` — one of the allowed frame types.
|
||||
- `persuasion` — the specific persuasion move.
|
||||
- `beat` — the viewer emotion.
|
||||
- `scene` — a one-line visual idea, not detailed composition.
|
||||
- `voiceover` — spoken guide text, or empty for silent frames.
|
||||
- `asset_candidates` — real captured assets that could support the frame.
|
||||
A UI demo is usually a SEQUENCE of 3+ consecutive `feature_showcase` / `benefit_highlight` beats on the same surface (input → response → result → benefit), not one isolated frame.
|
||||
|
||||
The prose under each frame should state:
|
||||
### 4. Write each beat's VO in its blueprint's script shape
|
||||
|
||||
- `narrativeRole` — why this frame exists in the story.
|
||||
- `keyMessage` — the one idea the viewer should remember.
|
||||
For each beat, look up its **role** in the script bank below, find the blueprint whose SHAPE fits the beat you already chose, and **draft the voiceover to sound like that blueprint's pattern.** Tag the candidate `blueprint:` id on the frame.
|
||||
|
||||
## Hook strategy
|
||||
- The bank is the heart of this step: proven product-launch clips reversed into the one VO line each implies, grouped by role → blueprint, each with a **pattern** to imitate.
|
||||
- If two blueprints fit the beat, prefer the one whose script shape matches the line you'd naturally write.
|
||||
- If NO shape fits the beat, omit `blueprint:` and write the VO plainly — Step 4 composes that frame freely. Do not force a wrong shape.
|
||||
- **Vary the shapes across the video.** Reaching for the same blueprint every beat re-creates the sameness this exists to avoid. `kinetic-type-beats` is the workhorse (6 roles) — lean on it, but not everywhere.
|
||||
- **Write each VO as discrete cues, not one run-on breath.** Step 5 reveals each on-screen piece _when the voiceover names it_ (the anti-PowerPoint mechanism — `motion-language.md` Part 2). A line with clear phrase boundaries — "Content, sentiment, engagement — in one place" — hands the shot its reveal cadence for free; a single long clause leaves the frame nothing to pace to. The bank patterns are already cue-segmented — keep that rhythm.
|
||||
|
||||
Pick one opening strategy for the first 3-5 seconds:
|
||||
Step 3 only TAGS the candidate id and writes the shaped VO. Step 4 (visual design) picks and instantiates the blueprint into a time-coded shot; it may override or drop a Step 3 candidate. The full menu with picking guidance lives in `../hyperframes-animation/blueprints-index.md`.
|
||||
|
||||
| Strategy | Use when |
|
||||
| ----------------------- | ----------------------------------------------- |
|
||||
| Shocking statistic | A credible number proves the pain. |
|
||||
| Pain validation | The audience already knows the problem. |
|
||||
| Rhetorical question | You need curiosity and speed. |
|
||||
| Direct address | The audience is clear and specific. |
|
||||
| Imagine / future pacing | The product introduces a new future. |
|
||||
| Category announcement | The product is the category or launch headline. |
|
||||
| Visual spectacle | The aesthetic is part of the pitch. |
|
||||
| Trend positioning | The product rides a timely market shift. |
|
||||
---
|
||||
|
||||
The hook must create tension, curiosity, or desire. Do not open with generic company description.
|
||||
## The script bank — what each beat's VO sounds like
|
||||
|
||||
## Persuasion labels
|
||||
> Proven product-launch clips, each reversed into the one spoken line it implies. Grouped by **role → blueprint**. Real product names kept (swap in your own). Draft your beat's VO in the SHAPE of the matching pattern.
|
||||
|
||||
Use concrete labels. Do not write generic labels like “show benefit.”
|
||||
### HOOK
|
||||
|
||||
Good labels include:
|
||||
**kinetic-type-beats** — the words ARE the motion
|
||||
|
||||
- Pain agitation
|
||||
- Cognitive overload
|
||||
- Negative contrast
|
||||
- Friction reduction
|
||||
- Simplification
|
||||
- Show-don’t-tell proof
|
||||
- Demonstration of capability
|
||||
- Feature-to-benefit translation
|
||||
- Statistical proof
|
||||
- Authority by association
|
||||
- Social proof
|
||||
- Risk reversal
|
||||
- Future pacing
|
||||
- Value stacking
|
||||
- Empowerment and control
|
||||
- Rule of three
|
||||
- Scarcity / urgency
|
||||
- Status seeking
|
||||
- Mailoji — "Still using a @gmail address? Or @outlook, or @hotmail, or @yahoo?"
|
||||
- Outrank — "Getting traffic is hard. Insanely hard."
|
||||
- AiAgent — "An AI agent that's easy to use — and optimised for you."
|
||||
- Uizard — "Transform your sketches into prototypes — automatically."
|
||||
- _Pattern:_ a punchy claim or rhetorical jab whose KEY WORD swaps in place (or escalates beat by beat) — the swap/escalation is the joke.
|
||||
|
||||
When no label fits, create one and explain the mechanism in the frame prose.
|
||||
**typewriter-reveal** — someone is typing this
|
||||
|
||||
## Emotional beats
|
||||
- "Need answers about your audience — right now?"
|
||||
- Contra — "You are more than your job title. You are more than your resume."
|
||||
- _Pattern:_ a relatable line typed live and edited mid-stream (a word backspaces and retypes) — the everyday thought, in your own words.
|
||||
|
||||
Use specific emotions:
|
||||
**spatial-pan-stations** — a panned timeline
|
||||
|
||||
- Negative: `anxiety`, `frustration`, `overwhelm`, `tension`, `urgency`, `skepticism`, `FOMO`
|
||||
- Pivot: `relief`, `curiosity`, `clarity`, `intrigue`, `aspiration`
|
||||
- Build: `trust`, `confidence`, `control`, `ease`, `power`, `awe`, `excitement`, `belonging`, `reassurance`
|
||||
- Close: `triumph`, `motivation`, `urgency-to-act`, `peace of mind`, `inevitability`
|
||||
- Rows — "From VisiCalc to Excel to Google Sheets — the spreadsheet has barely changed since 1979."
|
||||
- _Pattern:_ a march of named milestones across time, landing on "...until now / ...up to us."
|
||||
|
||||
Compound beats are allowed, e.g. `relief + control`.
|
||||
**constellation-hub** — nodes ring a center, camera pushes in
|
||||
|
||||
- "Content, sentiment, engagement, analysis — every platform you're on, in one place."
|
||||
- _Pattern:_ a spread of tools/channels collapsing onto one center — "it connects everything."
|
||||
|
||||
**ticker-takeover** — options cycle, then a hero crashes in
|
||||
|
||||
- Notion — "A doc? A database? A wiki? — no, it's all of them, in one place."
|
||||
- _Pattern:_ a "could be X, or Y, or Z?" cycle on one swapping word, then a hero claim crashes in and replaces it — "actually, this is what it is."
|
||||
|
||||
### PROBLEM
|
||||
|
||||
**kinetic-type-beats** — pain lands alone on a bare canvas
|
||||
|
||||
- Butter — "What if your sessions didn't have to be boring and unstructured — or buried under a dozen tabs?"
|
||||
- SmartCue — "You asked for better leads. We were the cure — MQLs that actually convert, a sales team that becomes your ally."
|
||||
- _Pattern:_ 3–5 short pain statements (or a "what if?" framing), each landing solo before the next — no product yet.
|
||||
|
||||
**spatial-pan-stations** — a panned web of pain
|
||||
|
||||
- Vauban — "Coordinating legal documents, signatures, and cross-border transactions — it's a tangled mess."
|
||||
- _Pattern:_ pain "stations" traversed one by one, ending on a knot — "too many disconnected steps."
|
||||
|
||||
**dataviz-countup** — the data IS the argument
|
||||
|
||||
- "67% of professionals say leadership is disconnected — and it's costing them a 65% boost in profitability."
|
||||
- _Pattern:_ a count-up / chart / stat the camera pushes through to dramatize a worsening or large-scale problem.
|
||||
|
||||
**overwhelm-surround** — buried by your own tools
|
||||
|
||||
- "Slack, email, docs, tickets, three more tabs — and somehow it all lands on you."
|
||||
- _Pattern:_ recognizable tools pile in until they surround and bury the viewer — the pain is being swamped, not one bad number.
|
||||
|
||||
### PRODUCT_INTRO
|
||||
|
||||
**kinetic-type-beats** — "Introducing…" name-drop
|
||||
|
||||
- "Elevating experiences, removing manual touchpoints, automating processes — so you can focus on the customer."
|
||||
- Uizard — "Introducing Uizard — the design tool for everyone."
|
||||
- _Pattern:_ hard-cut through "Introducing…" / tagline / value beats and resolve on the brand name or logo.
|
||||
|
||||
**logo-assemble-lockup** — wordless premium sting
|
||||
|
||||
- Manifold — "Manifold." _(wordless mark assembles; VO optional — just the name)_
|
||||
- _Pattern:_ an abstract system assembles around a fixed mark — no copy, or just the product name landing.
|
||||
|
||||
**cursor-ui-demo** — first cursor-led look
|
||||
|
||||
- ClickUp — "This is ClickUp — click through and watch your whole workspace change."
|
||||
- "Pull up any contact, find the right advisor, and you're matched in seconds."
|
||||
- PaLM 2 — "Meet PaLM 2 — what is it, what can it do, and how was it built?"
|
||||
- _Pattern:_ a cursor sweeps in to introduce the surface — a light first look landing on a hovered hero element or fresh result.
|
||||
|
||||
**dataviz-countup** — open on the result
|
||||
|
||||
- SuperX — "X growth — discover what really works: 19.6 million impressions."
|
||||
- _Pattern:_ a confident "look at the data / the result" open — scroll a tilted card grid to one glowing hero metric, tagline assembling word by word.
|
||||
|
||||
**video-text-pivot** — show it work, then the number
|
||||
|
||||
- "Watch it run — then look at what it saved: 14 hours, every week."
|
||||
- _Pattern:_ the product video plays, then slides aside to hand the frame to one impact stat — "see it work, now see what it's worth."
|
||||
|
||||
### KEY_FEATURE
|
||||
|
||||
**grid-card-assemble** — enumerate breadth at once
|
||||
|
||||
- Postcards — "Want more? Unlimited exports, 1,400 fonts, an AI assistant, version history — and it's free to try."
|
||||
- ClearVPN — "ClearVPN is built to help you: streaming access, secure browsing, location changing — only the essentials."
|
||||
- Copilot — "Command bar, Zapier, white-labeling, API, SOC2 — and a whole lot more."
|
||||
- _Pattern:_ a tile/pill/card grid self-assembles to show many capabilities at once — "look how much it does."
|
||||
|
||||
**cursor-ui-demo** — one workflow, end to end
|
||||
|
||||
- "Scroll your feed, then jump straight to your notifications — it's all one click away."
|
||||
- Flowrite — "Pick your recipient, set your intention, choose a tone — and Flowrite writes it for you."
|
||||
- Descript — "Tune your edits, add a crossfade, automate the volume, normalize loudness — then export."
|
||||
- _Pattern:_ one specific multi-step workflow shown end-to-end across 2–4 real edits, landing on the action button or result.
|
||||
|
||||
**device-surface-showcase** — experienced inside its real interface
|
||||
|
||||
- HRS — "Your flight's cancelled — so book a hotel, a taxi, and get reimbursed, all in one digital journey."
|
||||
- HelpKit — "A dynamic table of contents that follows your readers as they scroll."
|
||||
- Graphite — "Use unique themes, recolor one element or several, and configure it all in a handy window."
|
||||
- Contra — "Pick a template, make it yours, and launch a portfolio that's unmistakably you."
|
||||
- _Pattern:_ a feature shown being USED inside its real surface — the device/window is the hero and its screens advance through a flow.
|
||||
|
||||
**comparison-split** — two paired capabilities, side by side
|
||||
|
||||
- "Design on the left, code on the right — always one source of truth."
|
||||
- _Pattern:_ two complementary capabilities of equal weight shown together — "X and Y, in lockstep."
|
||||
|
||||
**video-text-pivot** — the feature, then its result
|
||||
|
||||
- "Here's the editor in action — and the result: a publish-ready cut in minutes."
|
||||
- _Pattern:_ a feature clip runs, then yields the frame to a metric / impact line — the clip proves it, the number lands it.
|
||||
|
||||
### BENEFITS
|
||||
|
||||
**kinetic-type-beats** — rapid-fire value montage
|
||||
|
||||
- AiAgent — "No API keys, GPT-4 access, simple UX, clean UI — moving fast."
|
||||
- Uizard — "Export to Sketch, create style guides, share, collaborate — and code less."
|
||||
- _Pattern:_ a staccato montage of 8–12 short value phrases, each flashing and clearing at high tempo.
|
||||
|
||||
**grid-card-assemble** — an accumulating value list
|
||||
|
||||
- Lineicons — "Consistent and clean, tons of free icons, a Figma plugin, a powerful editor, every format you need."
|
||||
- Plutio — "Manage projects, track time, send invoices, write proposals — all deeply customisable."
|
||||
- _Pattern:_ short value phrases populate a vertical list ~1/sec, co-resident and accumulating, each popping into its slot.
|
||||
|
||||
**titlecard-reveal** — the calm value beat
|
||||
|
||||
- CSS Scan Pro — "A smart color picker — with instant tints and shades."
|
||||
- _Pattern:_ one clean two-line value title, one slide-up crossfade, then held still. Low motion is the point.
|
||||
|
||||
### SOCIAL_PROOF
|
||||
|
||||
**constellation-hub** — the hub at the center of your stack
|
||||
|
||||
- kyvos — "On any BI tool — Tableau, Looker, Power BI — Kyvos sits at the center of your stack."
|
||||
- _Pattern:_ the product mark is the hub and partner logos orbit it — "sits at the center of everything you use."
|
||||
|
||||
**grid-card-assemble** — a logo wall pulling back to a vast ecosystem
|
||||
|
||||
- Lineicons — "Used by more than 100,000 designers, developers, and companies — including these."
|
||||
- ClickUp — "Connect Google Drive, Slack, GitHub, Stripe — your whole ecosystem in one place."
|
||||
- Copilot — "With thousands of partner apps — Airtable, Calendly, Jira, Asana — you can embed anything."
|
||||
- _Pattern:_ a wall of partner/app logos builds, then a camera zoom-out reveals a vast ecosystem.
|
||||
|
||||
**titlecard-reveal** — busy → clean proof card
|
||||
|
||||
- Trumpet — "We supply the trumpet, you bring the band — loved by 1,000+ sales, success, and marketing teams."
|
||||
- _Pattern:_ wipe a busy open away to a clean lockup plus a "loved by N+ teams" line that settles and holds.
|
||||
|
||||
### CTA
|
||||
|
||||
**kinetic-type-beats** — punchy closing line beat-by-beat
|
||||
|
||||
- Stylebit — "Go pro, connect up to five Figma accounts — more features coming. Join now."
|
||||
- revid.ai — "Boost your engagement and turbocharge your social media."
|
||||
- _Pattern:_ a closing line (or short value stack) that snaps in beat by beat and lands on the logo or URL.
|
||||
|
||||
**logo-assemble-lockup** — logo build → push-through into the URL
|
||||
|
||||
- Strapi Cloud — "Deploy on Strapi Cloud — no server hassle, same flexibility. Try it now at strapi.io/cloud."
|
||||
- Highlander — "Highlander is ready for the future you're building. Let's raise — at highlander.ai."
|
||||
- STUDIO AI — "Get early access to STUDIO."
|
||||
- Glorify — "Get started for free now — no credit card required."
|
||||
- _Pattern:_ the logo builds, a fast camera push-through streaks giant CTA letters past the lens, resolving on the URL or action verb.
|
||||
|
||||
**cta-morph-press** — identity condenses into one click
|
||||
|
||||
- Linear — "This is Linear. Start building — it's free."
|
||||
- _Pattern:_ the brand mark condenses straight into the single thing you click — "here's us → click here," no spatial set.
|
||||
|
||||
### BRAND_OUTRO
|
||||
|
||||
**kinetic-type-beats** — a verb barrage resolving on one word
|
||||
|
||||
- Phantom — "Buy, store, stake, swap, send, connect, explore — multichain."
|
||||
- _Pattern:_ a rapid center-channel barrage of single-word verbs asserting breadth, resolving on the brand's one defining word. No logo lockup needed.
|
||||
|
||||
**typewriter-reveal** — persistent mark + typed CTA rail
|
||||
|
||||
- Collato — "Next time, just Collato it — sign up for free today."
|
||||
- _Pattern:_ the mark holds dead-center the whole time while a sub-line types or swaps into the final CTA.
|
||||
|
||||
**logo-assemble-lockup** — elements clear, the lockup draws itself in
|
||||
|
||||
- Copilot — "Copilot." _(pills disperse off-frame, the mark draws on; VO optional — just the name)_
|
||||
- Dora AI — "Dora AI — join the waitlist."
|
||||
- _Pattern:_ feature/UI elements clear the stage off all four edges, then the logo mark draws itself on and the wordmark completes the lockup.
|
||||
|
||||
**ticker-takeover** — use-cases cycle, the brand takes the frame
|
||||
|
||||
- "For notes, for tasks, for plans, for teams — [brand] holds it all."
|
||||
- _Pattern:_ closing use-cases/verbs cycle through one slot, then the brand mark crashes in and owns the final frame.
|
||||
|
||||
---
|
||||
|
||||
## VO_MODE handling
|
||||
|
||||
**No pasted script** — write the VO yourself, in the matching blueprint's script shape:
|
||||
|
||||
- 1–2 sentences per spoken beat, usually 6–20 words.
|
||||
- Concrete and human; active verbs; say what the product does for a person.
|
||||
- Avoid: "seamless experience," "unlock the power of," "streamline your workflow," long noun-phrase lists, a whole beat that is just "Or…".
|
||||
- Silent beats are allowed when the visual proves the point — leave them out of `SCRIPT.md`.
|
||||
|
||||
**`VO_MODE = restructure`** — treat `user_script.txt` as source material. Rewrite, reorder, merge, or omit to fit the arc and target length. You may still shape each segment toward its beat's blueprint pattern.
|
||||
|
||||
**`VO_MODE = verbatim`** — do NOT change the user's words. Segment the script into beat-sized chunks at sentence/paragraph boundaries (split a long sentence only at a natural clause boundary). Final duration follows the provided script. Blueprint shaping does not apply to wording — only to which shape each verbatim chunk is paired with.
|
||||
|
||||
## Asset candidates
|
||||
|
||||
`asset_candidates` is the handoff from Step 3 to visual design and frame building.
|
||||
`asset_candidates` is the Step-3 → Step-4 handoff. Rules:
|
||||
|
||||
Rules:
|
||||
|
||||
1. Read only `capture/extracted/asset-descriptions.md` to know what assets exist.
|
||||
2. Use only filenames listed there.
|
||||
3. Write candidates as `assets/<basename>`, where `<basename>` is the captured file basename.
|
||||
4. Put all candidates on one line.
|
||||
5. Separate candidates with semicolons.
|
||||
6. Add a short description after `—`.
|
||||
7. Prefer `[video]` assets when motion proves the product better than a still.
|
||||
8. Use content assets: UI, screenshots, product photos, charts, diagrams, demos.
|
||||
9. Skip tiny icons, favicons, badges, decorative chrome, and repeated logo variants unless the frame needs them.
|
||||
10. Pure typography frames may use an empty asset list.
|
||||
1. Read only `capture/extracted/asset-descriptions.md` to know what exists.
|
||||
2. Use only filenames listed there; write as `assets/<basename>`.
|
||||
3. One line, candidates separated by semicolons, a short description after `—`.
|
||||
4. Prefer `[video]` assets when motion proves the product better than a still.
|
||||
5. Use content assets (UI, screenshots, product photos, charts, demos). Skip tiny icons, favicons, badges, decorative chrome, repeated logo variants — unless the beat needs them.
|
||||
6. Pure-typography beats may use an empty asset list. Do not use nested lists.
|
||||
|
||||
Example:
|
||||
|
||||
```md
|
||||
- asset_candidates: assets/dashboard-hero.png — main analytics UI, dark dashboard, wide screenshot; assets/demo-loop.mp4 — product interaction clip, query to result flow
|
||||
- asset_candidates: assets/dashboard-hero.png — dark analytics dashboard, wide screenshot; assets/demo-loop.mp4 — query-to-result interaction clip
|
||||
```
|
||||
|
||||
Do not use nested lists for assets. The parser expects a single metadata line.
|
||||
## transition_in
|
||||
|
||||
## UI demos
|
||||
Between-frame transition — how each frame ENTERS from the one before it. The harness's injector stamps it onto the two whole-frame clips (opacity / transform / filter on the frame wrappers). Name a **registry type** directly; optionally add a direction and/or a duration (`push-slide LEFT`, `crossfade 0.4s`). `cut` / `none` / empty = a hard cut.
|
||||
|
||||
A UI demo should usually be a sequence, not one isolated frame.
|
||||
The five registry types:
|
||||
|
||||
Use 3 or more consecutive `feature_showcase` / `benefit_highlight` frames on the same product surface when the product value depends on workflow or interaction.
|
||||
- **`crossfade`** — a plain opacity dissolve; the neutral choice when two frames sit in the same visual world.
|
||||
- **`blur-crossfade`** — dissolve through a soft blur + slight scale; use when the two frames' backgrounds differ a lot, so the blur masks the color clash a plain crossfade would expose.
|
||||
- **`push-slide`** `[LEFT|RIGHT|UP|DOWN]` — outgoing slides off, incoming pushes in from the opposite edge; a lateral "next beat" feel for a run of consecutive cards / feature beats.
|
||||
- **`zoom-through`** — outgoing scales up + blurs out, incoming scales up from small into focus; for a STATE CHANGE / turning to a new section (hook → context).
|
||||
- **`squeeze`** — outgoing compresses to a line on one edge as incoming expands from the other; a snappy, mechanical beat change.
|
||||
|
||||
Good demo rhythm:
|
||||
|
||||
1. Input or user action.
|
||||
2. Product response.
|
||||
3. Result, insight, automation, or saved effort.
|
||||
4. Benefit or trust proof.
|
||||
|
||||
Use consistent transitions across the sequence so it feels like one flow.
|
||||
|
||||
## Script rules
|
||||
|
||||
### If there is no pasted script
|
||||
|
||||
Write tight per-frame narration:
|
||||
|
||||
- 1-2 sentences per spoken frame.
|
||||
- Usually 6-20 words per frame.
|
||||
- Concrete and human.
|
||||
- Say what the product does for a person.
|
||||
- Prefer active verbs.
|
||||
|
||||
Avoid:
|
||||
|
||||
- “Seamless experience.”
|
||||
- “Unlock the power of...”
|
||||
- “Streamline your workflow.”
|
||||
- Long noun-phrase lists.
|
||||
- A whole frame with only “Or...” or another filler bridge.
|
||||
|
||||
Silent frames are allowed when the visual proves the point. Leave them out of `SCRIPT.md`.
|
||||
|
||||
### If `VO_MODE = restructure`
|
||||
|
||||
Treat `user_script.txt` as source material. Rewrite, reorder, merge, or omit to fit the chosen arc and target length.
|
||||
|
||||
### If `VO_MODE = verbatim`
|
||||
|
||||
Do not rewrite the user’s words. Segment the script into frame-sized chunks at sentence or paragraph boundaries. You may split a long sentence at a natural clause boundary, but do not change words. The final duration follows the provided script.
|
||||
|
||||
## Transitions
|
||||
|
||||
Use only registry transition names:
|
||||
|
||||
`cut | crossfade | blur-crossfade | push-slide LEFT | push-slide RIGHT | push-slide UP | push-slide DOWN | zoom-through | squeeze`
|
||||
|
||||
Pick 2-3 transition types for the whole video and repeat them. Frame 1 can use `cut` as a placeholder.
|
||||
Pick a small set and repeat them: default to `crossfade` (or `blur-crossfade` when the backgrounds clash), and reach for `zoom-through` at section boundaries. Frame 1's `transition_in` is a placeholder.
|
||||
|
||||
## Frame template
|
||||
|
||||
Use the exact fields required by the core storyboard format. This is the narrative shape each frame should satisfy:
|
||||
Use the exact fields required by the core storyboard format. The narrative shape each frame satisfies:
|
||||
|
||||
```md
|
||||
## Frame N — Short name
|
||||
|
||||
- scene: one clear visual idea
|
||||
- voiceover: "spoken guide text, or empty"
|
||||
- voiceover: "spoken line, written in the candidate blueprint's script shape, or empty"
|
||||
- duration: rough estimate in seconds
|
||||
- transition_in: cut
|
||||
- transition_in: crossfade
|
||||
- status: outline
|
||||
- src: compositions/frames/NN-short-name.html
|
||||
- type: hook
|
||||
- persuasion: Pain validation
|
||||
- beat: urgency
|
||||
- blueprint: kinetic-type-beats — candidate shape from the role→blueprint menu; omit when none fits
|
||||
- asset_candidates: assets/example.png — short asset description
|
||||
|
||||
narrativeRole: What this frame does in the viewer journey.
|
||||
keyMessage: The one idea the viewer should remember.
|
||||
narrativeRole: what this beat does in the viewer journey.
|
||||
keyMessage: the one idea the viewer should remember.
|
||||
```
|
||||
|
||||
- `persuasion` — a concrete move (Pain agitation, Negative contrast, Friction reduction, Show-don't-tell proof, Feature-to-benefit translation, Statistical proof, Authority by association, Social proof, Risk reversal, Future pacing, Value stacking, Rule of three, Scarcity/urgency, Status seeking…). Never "show benefit." Invent one if none fits and explain it in the prose.
|
||||
- `beat` — a specific emotion (anxiety, frustration, overwhelm, tension, urgency, skepticism, FOMO → relief, curiosity, clarity, intrigue, aspiration → trust, confidence, control, ease, power, awe, excitement, belonging → triumph, motivation, urgency-to-act, peace of mind, inevitability). Compound allowed (e.g. `relief + control`).
|
||||
|
||||
## Final checklist
|
||||
|
||||
Before asking for user approval, verify:
|
||||
|
||||
- The arc is named and consistent.
|
||||
- The sequence is narrative-driven, not page-order-driven.
|
||||
- The opening uses a clear hook strategy.
|
||||
- Each frame has one job.
|
||||
- Every frame has `type`, `persuasion`, and `beat`.
|
||||
- Every visual frame has suitable `asset_candidates`, unless intentionally typography-only.
|
||||
- Asset filenames come only from `capture/extracted/asset-descriptions.md`.
|
||||
- UI/product demos use a multi-frame sequence when needed.
|
||||
- Transitions use only registry names and repeat 2-3 types.
|
||||
- `SCRIPT.md` contains only locked spoken narration.
|
||||
- Silent frames are intentional and omitted from `SCRIPT.md`.
|
||||
- The arc is named; the sequence is narrative-driven, not page-order-driven.
|
||||
- The opening uses one clear hook strategy that creates tension/curiosity/desire.
|
||||
- Each beat has one job; every beat has `type`, `persuasion`, `beat`.
|
||||
- Each beat's `voiceover` is written in its candidate blueprint's script shape (from the bank), with the candidate `blueprint:` tagged wherever a shape fits — and omitted where none does.
|
||||
- Each `voiceover` is phrase-segmented into cues (each cue a piece Step 5 can reveal on) — not one long run-on clause.
|
||||
- Shapes vary across the video; no single blueprint on every beat.
|
||||
- Story truth was never bent to fit a blueprint — no beat invented/dropped/reordered for a shape.
|
||||
- Every visual beat has suitable `asset_candidates` (filenames only from `asset-descriptions.md`), unless intentionally typography-only.
|
||||
- UI/product demos use a multi-beat sequence when the value depends on workflow.
|
||||
- `transition_in` is a registry type (`crossfade` / `blur-crossfade` / `push-slide` / `zoom-through` / `squeeze`) — default `crossfade` (`blur-crossfade` on a background clash), `zoom-through` at section boundaries, repeated across the video.
|
||||
- `SCRIPT.md` contains only locked spoken narration; silent beats are intentional and omitted.
|
||||
|
||||
@@ -1,55 +1,94 @@
|
||||
# Visual design — product-launch per-frame enrichment method
|
||||
# Visual design — product-launch per-frame shot 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`, the five narrative fields, and its `asset_candidates`); 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, not just its entrance. You write **no HTML** (that's the frame workers), you **never read `capture/`** (story already chose the assets), and you do **not** select assets or name transitions (story owns both). `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`.
|
||||
> 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`, the narrative fields, its `asset_candidates`, and optionally a candidate blueprint id); you add how each frame **looks and moves**. The unit you write per frame is a **time-coded shot sequence** — a shot directed across its whole duration, not a static slide. You write **no HTML** (that's the frame workers), you **never read `capture/`** (story already chose the assets), and you do **not** select assets or name transitions (story owns both). `frame.md` is your palette/type truth by role. Layout is a compact vocabulary in this file (the **Layout** section below), stated inline per Scene; motion vocabulary + the motion doctrine + the seek-safe core → `motion-language.md`; the proven shapes → `../hyperframes-animation/blueprints-index.md` + `blueprints/<id>.md`; concrete rules resolve in Step 5 from this skill's local `../hyperframes-animation/rules/`. Adding palette theory or a generic font rule here? Wrong home — `frame.md` + `hyperframes-creative`.
|
||||
|
||||
## Every frame is a directed shot
|
||||
## The unit is a time-coded shot sequence
|
||||
|
||||
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**.
|
||||
A frame's visual layer is **a sequence of time windows paced to the voiceover**, not a bag of effect tags. The failure that reads as PowerPoint is **front-loading**: the agent rushes the whole canvas on screen in the first ~25%, and then it just sits (the old representation — a flat set of effect names + a prose note — fired everything at entrance and left the rest empty). A time-coded shot sequence written **against the VO** makes that impossible: each window states what is on screen and what is moving, and **nothing appears before the voiceover reaches it.**
|
||||
|
||||
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.
|
||||
Write each frame as a handful of windows cued by the spoken line:
|
||||
|
||||
```
|
||||
Scene 1 (0.0–Xs): only what the VO is saying at t=0 enters — never the whole canvas
|
||||
Scene 2 (Xs–Ys): the next piece reveals as the VO names it (a line / card / stat / icon)
|
||||
… one window per spoken cue — as many or as few as the line calls for
|
||||
Scene N (…–end): content has resolved; hold the read (stillness; subtle jitter at most)
|
||||
```
|
||||
|
||||
- Each `Scene` line names **what's on screen**, **what moves in this window**, and **where it sits** (layout, inline). Times are real seconds across the frame's `duration`.
|
||||
- **Pace reveals to the voiceover; never front-load.** This is the core anti-PowerPoint mechanism (→ `motion-language.md` Part 2 Rule 2). At t=0 show only what the VO is saying then; reveal each further piece — a line, a card, even an h1 — **when the VO names it**, spreading reveals across the shot and especially the **back ~50%**. **The window count = the number of spoken cues the line calls for** — a two-beat line is two windows, a five-feature list is five or six. There is **no fixed count and no mandatory "middle" act**; the only sin is dumping everything up front.
|
||||
- **End on a held read.** Once the content has resolved it holds and reads — **prefer stillness to bad motion**: no forced camera drift, no lazy breathing, no back-half pan/push; at most a subtle jitter keeps it alive (→ `motion-language.md`). On a short shot the final reveal and the hold are the **same window** — the hold is not a separate mandatory act. Only the final frame has a real exit; every other frame's exit is the harness transition (story's `transition_in`).
|
||||
- A **deliberately held** frame — content already revealed, now reading still — is legitimate and often right (a climax, a breather). The failure is never "too still"; it is **front-loaded-then-frozen** (everything dumped by ~25%, nothing cued to the VO). Place held beats deliberately for rhythm so the video isn't uniformly busy (allocate them in `## Video direction`). Reveal pacing + holds + the idle budget → `motion-language.md`.
|
||||
|
||||
## Pick the shape — instantiate a blueprint
|
||||
|
||||
Don't invent each shot from scratch. The frame's **role** (its `type` / `beat`) points to a proven shape:
|
||||
|
||||
1. **Match the role to a blueprint.** Open `../hyperframes-animation/blueprints-index.md`, find the frame's role in the **role→blueprint menu**, and pick the blueprint whose intent fits this beat (story may already have named a candidate id — confirm or override it). Read that `blueprints/<id>.md`: it is a short, product-agnostic, **time-coded shot template with `[slots]`** and a named **signature move** (the thing that makes the shape itself — the SVG ring, the push-THROUGH, the in-place token swap).
|
||||
|
||||
2. **Instantiate its `[slots]` with THIS product's content** — three postures:
|
||||
- **Reproduce** — the blueprint fits the beat and your content maps onto its slots cleanly. Fill every `[slot]` with this product's word / asset / stat and follow its Scene timing. Write the resulting Scene lines.
|
||||
- **Adapt** — the _structure_ fits but the content / asset-count / surface doesn't (or you want a fresher surface to avoid templating). State **what you keep / what you change** in one line, then write the adapted Scene lines. You may extend or vary; you may **never** drop the **signature move** (drop it and you picked the wrong blueprint), and you keep the reveals **paced to the VO** — never collapse the shape to a single front-loaded dump.
|
||||
- **Compose** — no blueprint fits the beat. Build the shot from the **motion vocabulary** in `motion-language.md`: still pace the reveals to the VO across the shot, never fire everything at t=0. Mark it `blueprint: compose`.
|
||||
|
||||
3. **Keep the signature move.** Whichever posture, the blueprint's signature move (named in its file) is the spine of the shot — it usually lands on the shot's key reveal. Carry it through.
|
||||
|
||||
The blueprint's own Scene lines, motion vocabulary, and `rule mapping` are your raw material; you are choosing a shape and casting this product into it, not copying an engineering spec.
|
||||
|
||||
## 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):
|
||||
Story-design's `## Frame N` block already carries the narrative + `asset_candidates`. You append the shot. Story's `scene` / `voiceover` / `transition_in` / role fields stay untouched.
|
||||
|
||||
```
|
||||
## Frame 3 — The problem
|
||||
- scene: a 20-minute timer spins on a stack of rejected takes ← refine only if it could read sharper
|
||||
- scene: a 20-minute timer over a stack of rejected takes ← refine only if it could read sharper
|
||||
- voiceover: "…" ← story's; leave it
|
||||
- transition_in: crossfade ← story's; leave it
|
||||
- type: pain_point ← story's
|
||||
- persuasion: Pain agitation
|
||||
- beat: frustration
|
||||
- effects: slow-push, count-up, vignette-pulse ← you add: cite effect ids (≥3, sequenced into the phases below)
|
||||
- blueprint: messaging-multi-phase ← you add (optional): one multi-phase blueprint id
|
||||
- focal: assets/timer-stack.png ← you add: which existing candidate is the hero
|
||||
- roles: timer-stack = background (dim ~40%) ← you add: cutout / background / supporting per candidate
|
||||
- sfx: impact-soft, riser ← you add: the sound the beat wants (fetched + mounted at root; never yours to embed)
|
||||
- blueprint: dataviz-countup (Adapt) ← you add: the id you instantiated (or "compose")
|
||||
- focal: assets/reject-stat.png ← you add: the hero asset for this beat
|
||||
- roles: reject-stat = cutout · timer = supporting · backdrop = background (dim ~40%) ← you add: role per candidate
|
||||
- sfx: impact-soft, riser ← you add: the sound the beat wants (fetched + mounted at root; never yours to embed)
|
||||
|
||||
Entrance: timer drops in upper-left (heavy), rejected-takes stack seated low. Development: the stack grows beat-by-beat toward the band as the reject count ticks up (count-up). Settle: vignette pulses in and holds; only the slow-push continues. A dense, edge-anchored frame.
|
||||
Adapt: keep the count-up-ring signature; one stat not three, and the trend chart becomes the rejected-takes count climbing.
|
||||
Scene 1 (0.0–1.2s): solid backdrop (dim ~40%); a circular progress ring + bold center number seat dead-center, ring sweeps and number counts 0→20 on one heavy ease — Centered template, ~50% of frame. Slow push-in runs underneath.
|
||||
Scene 2 (1.2–3.4s): as the VO names the count, the camera pushes THROUGH the ring into the rejected-takes stack lower-left; the stack grows beat-by-beat as a reject counter ticks up beside it (the count-up reveals on its spoken cue, not at t=0). Asymmetric 60/40, 3 depth layers.
|
||||
Scene 3 (3.4–5.0s): land the hero stat card dead-center, accent glow blooms behind it and holds; the stat reads clean and STILL — no continuing push, no breathing (a held beat beats bad motion). The stillness reads against the prior motion.
|
||||
```
|
||||
|
||||
- **`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 (that collapses three phases into one slide). The names are a shared vocabulary; the recipe lives there — you cite, the worker **reads the 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 (multi-phase reveal, orbit-collapse, …). Two postures — **both require the worker to read the recipe body (and run its `examples/<id>.html` to see the signature move) first**; deviating from a name-guess instead of from understanding is the one banned failure:
|
||||
- **Reproduce** — the blueprint fits the beat cleanly and the frame's content maps onto its slots; the worker reproduces its phases faithfully. Write the composition note shot-by-shot to match.
|
||||
- **Adapt** — the blueprint is the right _structure_ but the content / beat / asset-count doesn't fit its exact form, or you want the proven skeleton with a fresher surface (anti-templating), or you're grafting a second blueprint's phase. Lead the note with a **`Base / Keep / Depart`** line — `Base:` the blueprint id · `Keep:` its **signature** (the move that makes it itself — the SVG ring, the orbit→collapse; never drop this, or you named the wrong blueprint) · `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. E.g. `Base: avatar-cloud-network · Keep: the SVG-connected elliptical ring · Depart: 7 logos not 12, + a hub count-up as the development beat`.
|
||||
The lightweight tags:
|
||||
|
||||
Choose **Reproduce** when the shape fits as-is, **Adapt** when the structure fits but the form doesn't (or to avoid templating); **omit** `blueprint` entirely when no blueprint's structure fits — then the cited `effects` (≥3) carry the phases (**Compose**).
|
||||
- **`blueprint:`** — the id you instantiated (with `(Reproduce)` / `(Adapt)`), or `compose`. One id per frame.
|
||||
- **`focal:`** — which existing candidate is the hero of this beat.
|
||||
- **`roles:`** — each candidate's role: `cutout` (foreground subject, lay text around it) · `background` (full-bleed, dim 30–50%) · `supporting` (secondary). You **consume** the candidates story chose — never add, swap, or drop one (coverage is story's call; if a frame truly has the wrong candidates, flag it back, don't reach into `capture/`).
|
||||
- **`sfx:`** — name the sound the beat wants (an impact for a slam, a whoosh for a push, a riser into a reveal). 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.
|
||||
|
||||
- **`focal` / `roles`** — story listed `asset_candidates`; you pick the **focal** hero and each candidate's role (`cutout` = foreground subject, lay text around it; `background` = full-bleed, dim 30-50%; supporting = secondary). You **consume** the candidates — never add, swap, or drop one (coverage is story's call; if a frame truly has the wrong candidates, flag it back, don't reach into `capture/`).
|
||||
- **`sfx`** — name the sound the beat wants (an impact for a slam, a whoosh for a push). The audio script's `fetch-sfx` pass retrieves it from HeyGen 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: …` (shot-by-shot; mandatory when you named a `blueprint`) — naming what's on screen and what moves in each phase, so the worker builds the development instead of freezing after entry. 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).
|
||||
**Layout is stated INLINE in each Scene line** — name the template, density, depth, and hierarchy as part of "where it sits" (`Centered, ~50% of frame`, `asymmetric 60/40, 3 depth layers`), drawing on the **Layout** vocabulary below; never write px / scale / shadow recipes (the worker writes those).
|
||||
|
||||
## Video direction — write the invariants ONCE
|
||||
**Motion is named INLINE in each Scene line** — name the move from `motion-language.md`'s vocabulary (`ring sweeps`, `pushes THROUGH`, `count-up`, `glow blooms`) and let it settle on a long-tail curve (`power3` default — smooth beats bouncy; see `motion-language.md`). Never write ease curves / ms / stagger (those resolve in Step 5 from this skill's local `../hyperframes-animation/rules/`).
|
||||
|
||||
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**:
|
||||
## Layout — named inline per Scene
|
||||
|
||||
State each Scene's layout as part of "where it sits." **If the blueprint already implies a composition** (a ring around a center, stations on a wide canvas, two cards from opposite wings), that wins — describe it directly; the vocabulary below is for **composing freely** or a generic beat, not a menu you must pick from. Never write px / scale / shadow (the worker does). One frame's layout can EVOLVE across its Scenes (Scene 1 centered hero → Scene 2 rearranges to a grid).
|
||||
|
||||
- **Framing vocabulary** — centered (hero / climax) · rule-of-thirds · split-screen (comparison) · layered-depth (immersive) · asymmetric 60/40 or 70/30 (editorial) · triptych (three panels) · full-width strip. Vary the framing across the video so it doesn't read as one repeated template — let the beat decide, not a quota.
|
||||
- **Density** — primary visual ≥ 40% of canvas; ≥ 3 depth layers (background + midground + foreground); never a lone small cluster floating in empty space. Squint test: after blur you can still pick out the #1 element.
|
||||
- **Hierarchy** — combine ≥ 2 of size (3:1) / weight (800 vs 400) / contrast / position (upper-third is golden) / motion, so one element clearly dominates.
|
||||
- **Depth** — layer 2–3 of: size, blur, opacity gradient, overlap, shadow-stack.
|
||||
- **Don't show**: nav bars, footers, scrollbars, real cursors / browser chrome, generic decorative shapes standing in for a real asset, floating bokeh / purple-blue "AI" gradients — unless it's an intentional UI-demo reconstruction.
|
||||
|
||||
## `## Video direction` — write the invariants ONCE
|
||||
|
||||
The whole video shares one look and one motion grammar. Write a **`## Video direction`** block ONCE at the top of `STORYBOARD.md` so every frame inherits it and per-frame Scene lines carry only the **delta**. This block is load-bearing — it is what binds many independent shots into one film. **Keep it.**
|
||||
|
||||
- **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 and effects 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 (the anti-repetition discipline; → `motion-language.md`).
|
||||
- **motion grammar + reveal model** — long-tail eases (`power3` default, smooth over bouncy) + the **VO-paced reveal** model every frame follows (reveal each piece on its spoken cue; never front-load) + what may stay alive during a hold (subtle jitter at most; no lazy breathing) (→ `motion-language.md`).
|
||||
- **rhythm / held-frame allocation** — name the **held / breather frames** (often before a climax) so the video varies its energy: most frames reveal to the VO, a few hold still (a held read beats bad motion; the anti-monotony discipline; → `motion-language.md`).
|
||||
- **negative list** — what never appears: off-brand textures / effects the pack forbids, **plus both motion failure modes** — slideshow (front-load then freeze) and screensaver (everything floating independently) (→ `motion-language.md`).
|
||||
|
||||
Do **not** repeat these in every frame — restating video-level rules per frame is exactly the bloat this layer prevents. Each frame's metadata is the delta on top of Video direction.
|
||||
Do **not** repeat these per frame — restating video-level rules in every frame is exactly the bloat this layer prevents.
|
||||
|
||||
## Palette & type — from `frame.md`, never invented
|
||||
|
||||
@@ -58,26 +97,30 @@ Do **not** repeat these in every frame — restating video-level rules per frame
|
||||
|
||||
## 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`.
|
||||
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.
|
||||
|
||||
## Where the detail lives
|
||||
|
||||
| For… | Read |
|
||||
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| composition — zones, density, templates, asset 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` |
|
||||
| "produced, not generated" foreground density | `hyperframes-creative/references/video-composition.md` |
|
||||
| transitions | story-design owns `transition_in`; you don't touch it |
|
||||
| For… | Read |
|
||||
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| the proven shapes + role→blueprint menu + how to pick | `../hyperframes-animation/blueprints-index.md` → `blueprints/<id>.md` (local) |
|
||||
| motion — shot model, vocabulary, holds, idle budget, stillness, seek-safe | `motion-language.md` (local) |
|
||||
| layout — templates, density, depth, hierarchy, caption band | the **Layout** vocabulary in this file |
|
||||
| concrete eases / ms / stagger + rule recipe bodies (Step 5) | local `../hyperframes-animation/rules/` (the frame worker reads it; you don't) |
|
||||
| palette + type tokens | the project's `frame.md`; basics → `hyperframes-creative` `house-style.md` / `typography.md` |
|
||||
| "produced, not generated" foreground density | `hyperframes-creative/references/video-composition.md` |
|
||||
| within-frame cuts / seams (zoom-through · cut-the-curve · waterfall) | `cut-catalog.md` (the worker builds them inside the composition) |
|
||||
| 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 / shot-by-shot) — 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 visual frame's `asset_candidates` have a `focal` + per-candidate `roles`; none added or dropped.
|
||||
- **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, not restatements.
|
||||
- **`## Video direction`** written once at the top (palette · motion grammar + shot model + idle budget · stillness allocation · negative list incl. both failure modes); per-frame entries are deltas, not restatements.
|
||||
- Every frame is a **time-coded shot sequence** with real second windows across its `duration` — not a tag bag.
|
||||
- **No frame front-loads** — at t=0 only what the VO is saying enters; each further piece reveals on its spoken cue, across the back ~50%. Window count follows the VO, not a fixed number.
|
||||
- Every frame names an **`blueprint:`** id (Reproduce / Adapt) or `compose`; an Adapt states keep/change and **keeps the signature move**; nothing collapses to a single front-loaded dump — reveals stay paced to the VO.
|
||||
- **Held frames are deliberate** — allocated in Video direction for rhythm; a held read is fine (prefer stillness to bad motion), but no frame may be front-loaded-then-frozen.
|
||||
- Each frame's `asset_candidates` have a `focal` + per-candidate `roles`; none added, swapped, or dropped.
|
||||
- Layout named **inline** per Scene (template / density / depth / hierarchy — the **Layout** vocabulary here); motion named **inline** per Scene from the vocabulary (`motion-language.md`). No px / ease curves / ms / JS.
|
||||
- Content planned into the top ~83% (caption band clear).
|
||||
- Palette / type pulled from `frame.md` by role — nothing invented.
|
||||
- You wrote no HTML and never read `capture/`.
|
||||
|
||||
Reference in New Issue
Block a user