Hyperframes Animated Reel
Build a 9:16 reel where the visuals are HTML + GSAP cards rendered by
hyperframes, composited with talking-head footage. This is the pipeline that
produced merged-v6 through merged-v10 and it beats PIL/ffmpeg frame-painting
for anything with motion, type, or product UI.
Trigger vocabulary
These phrasings load this skill (and its siblings) reliably. The word reel is the routing signal - say it in the first sentence.
| Say this | Loads |
|---|---|
| "build the reel" / "animate the reel" / "add visuals to the reel" | this skill |
| "/reel" followed by what you want | this skill |
| "analyse this reel" (+ video) | reel-subtitle-analysis |
| "add this reel to the reference library" | reel-subtitle-analysis |
| "make a B-roll clip for the reel" | this skill + references/generated-broll-prompt.md |
| "reverse-engineer this video into a prompt" | references/generated-broll-prompt.md |
Avoid "make me a video" alone - it routes to generic video tooling. Say reel.
THE PIPELINE (your standard reel setup)
Five stages. Money is spent only at stage 3, and only on assets already approved.
1. STILLS design/generate every hero visual as a static image (free / cheap)
2. APPROVE the creator signs off the stills in a contact sheet (free)
3. ANIMATE Kling image-to-video on APPROVED stills only ($0.35 / 5s)
4. COMPOSITE hyperframes lays captions + UI panels over the clips (free)
5. VERIFY labelled frame grid -> vision check -> deliver (free)
Why this order is the whole trick. Text-to-video pays the model to guess composition, palette and subject, which is where the ~3x retry waste comes from. An approved still LOCKS all three; Kling only adds motion. Retry rate falls to near 1, so a generated-primary reel costs ~$1.40-1.75 instead of ~$10.50. Generate nothing before the still is approved.
Stage 1: where each still comes from
| Still type | Build it with | Why |
|---|---|---|
| Product UI, dashboards, terminals, data panels | HTML/CSS in this repo | pixel-exact, real fonts, free, editable forever |
| Illustrated scenes, mascots, objects, atmosphere | ChatGPT / GPT Image | better at painterly and 3D-ish subjects |
| Anything quoting real data | real capture | see honesty rules |
UI mocks are HTML, not generated images: a generated dashboard has warped type
and invented controls. your cream palette and Instrument Serif / Inter /
JetBrains Mono stack already exist in index.html - reuse them.
Stage 3: animating a still
fal-ai/kling-video/v2.5-turbo/pro/image-to-video, $0.35 for 5s, $0.07/s
after. 5s is the billing floor - a 2s insert still costs $0.35, so generate 5s
and trim in ffmpeg.
Keep the motion prompt SMALL. The still already carries the design; ask only for camera and light ("slow push in, haze drifting left to right, light blooming from the upper left"). Do not re-describe what is in the image - that invites the model to redraw it.
Stage 4: captions go on LAST, always
Never let a video model render text. Composite generated clips UNDER the hyperframes caption layer so type stays crisp and word-accurate.
Budget
$10 = 28 clips at 5s. A reel using 3-4 animated hero shots = $1.05-1.40.
Two lanes: rendered vs generated
Lane 1 - hyperframes (default). Anything readable: captions, counters, dashboards, terminals, data panels, product UI. Crisp text, frame-accurate sync.
Lane 2 - generated video (texture only). Atmospheric inserts behind abstract
lines. Haze, flare, depth-of-field, abstract motion. 2-6s, silent, composited
UNDER the hyperframes caption layer. See
references/generated-broll-prompt.md for the house reverse-engineering prompt
and verified provider rates.
Never let lane 2 render text.
When to Use
Load
prompt-motion-reel-grammartoo: measured timing constants, seam catalog, caption systems,gsap-kit.jshelpers, and the verified HyperFrames -> ProRes 4444 alpha -> DaVinci Resolve route.
- A transcript needs animated proof visuals (dashboards, terminals, data panels).
- An existing reel project needs more visual density or a beat rebuilt.
- NOT for pure cuts-and-subtitles editing of existing footage — see
transcript-driven-video-editing.
BEFORE YOU BUILD: does it already exist?
Search renders and frame-match the take before creating anything. A finished a fresh, worse reimplementation was built from scratch.
# frame-match a candidate against the user's clip:
ffmpeg -v error -ss 1 -i USERCLIP.mp4 -frames:v 1 /tmp/a.png -y
ffmpeg -v error -ss 1 -i CANDIDATE.mp4 -frames:v 1 /tmp/b.png -y
python3 -c "from PIL import Image;import numpy as np;\
a=np.asarray(Image.open('/tmp/a.png').convert('L').resize((160,284)),float);\
b=np.asarray(Image.open('/tmp/b.png').convert('L').resize((160,284)),float);\
print('diff',abs(a-b).mean())"
Diff < 1.0 means same take — patch that project, do not rebuild.
Project layout
merged-reel/
index.html # the whole composition: CSS cards + GSAP timeline
assets/ # face.mp4, audio, canvas PNGs
renders/ # merged-vN.mp4 outputs
make_canvas.py # generates product-UI PNGs from real JSON
Each visual is a div with data-start / data-duration / data-track-index;
hyperframes drives a GSAP timeline and screenshot-captures each frame.
Procedure
1. Map every spoken sentence to a visual
Extract word timings first, then check coverage programmatically — do not eyeball
it: for each element read id, data-start, data-duration, work out which
words it covers, and print any word window with NO card. Those are the dead beats.
This is how a 1.65s blank cream card on "numbers that were never real" was
found: the card's data-start was 5.30 but its contents didn't animate in until
6.95. A card's data-start must equal the time its first child animates.
2. Budget beats against measured references
49-99. A single card holding 12.8s across four spoken claims is the failure mode — split it so each claim gets its own reveal. Target ~15-20 visual beats/min.
3. Build evidence panels, one per claim
The pattern that works: a dark rounded panel over the proof surface, appearing on the claim's first word and leaving before the next.
tl.to("#panel-scrape", { opacity: 1, y: 0, scale: 1, duration: 0.26,
ease: "back.out(1.6)" }, 13.90);
tl.to("#panel-scrape .row", { opacity: 1, x: 0, duration: 0.2,
stagger: 0.085, ease: "power2.out" }, 13.98);
tl.to("#panel-scrape", { opacity: 0, y: -18, duration: 0.2 }, 14.74);
Register every new element in the beat's exit sweep, or it survives the cut into the next section.
4. Counters and typewriters
Animate a proxy object and write textContent — never TextPlugin (it eats
markup):
var o = { v: 0 };
tl.to(o, { v: 308, duration: 0.85, ease: "power2.out", onUpdate: function () {
document.getElementById("scrape-count").textContent = Math.round(o.v) + " found";
}}, 13.98);
Typewriter: animate {n:0} to full.length and slice(0, Math.round(o.n)).
5. Zoom/pan on a product canvas
When zooming a PNG, clamp the centre so the zoom never reveals past the edge:
def pan(px, py, s): # px,py = target % ; s = scale ; OX,OY = transform-origin
h = 50.0 / s
cx = min(max(px, h), 100 - h); cy = min(max(py, h), 100 - h)
return (50 - OX) - (cx - OX) * s, (50 - OY) - (cy - OY) * s # xPercent, yPercent
Recompute every pan when you swap the image — old coordinates point at positions that no longer exist.
6. Render and verify
npx --yes [email protected] lint # must be 0 errors
npx --yes [email protected] render -o renders/merged-vN.mp4
Render takes ~4 min for 34s (software GL). Run it with background=true, notify=true, then verify with a labelled frame grid — never ship unviewed:
ffmpeg -v error -ss 13.8 -to 18.6 -i renders/merged-vN.mp4 \
-vf "fps=2.5,scale=200:356,drawtext=text='%{eif\:t+13.8\:d}.%{eif\:mod(t*10+8\,10)\:d}':\
x=4:y=4:fontsize=17:fontcolor=yellow:box=1:[email protected],tile=6x2:padding=3:color=white" \
-frames:v 1 /tmp/check.jpg -y
Then look at it with vision_analyze. Every defect worth fixing in this project
— blank frames, overlapping panels, half-corrupted scrambles — was found this
way and would have shipped otherwise.
Honesty rules (non-negotiable)
- Claims about the user's business must be real. Lead counts, reply counts, revenue: do not put them on screen unconfirmed, even if the audio says them.
- Concept illustrations may be fabricated — a "fake dashboard" card, an
example DM, sample rows. The reference creators do exactly this (Saraev's
dental listings are all
(512) 555-xxxx). - Say which is which when delivering. Never present a rendered mock as a screenshot of the real product.
- If a real capture is impossible (no login), say so and name what would fix it.
Pitfalls
- A card whose contents animate later than its
data-start= blank screen. Always equal. - Staggered text corruption (
k*0.11 + i*0.03) can finish after a stamp covers it — keep scramble staggers under ~0.09. - Panels can collide with chips/rings in the same region; check the frame grid and suppress the weaker element.
hyperframes lintwarnings about missing assets can be false positives for paths that are reel assets (assets/face.mp4); 0 errors is the gate.- Chrome renders with software GL here (
BeginFrame did not run) — slow but correct. Don't chase it.