docs: address prompt guide review findings

This commit is contained in:
Vance Ingalls
2026-07-30 04:54:27 -07:00
parent 8fb1482e7f
commit 73ebc7c621
40 changed files with 127 additions and 127 deletions
+2 -1
View File
@@ -493,7 +493,8 @@
"redirects": [
{
"source": "/guides/prompting",
"destination": "/prompting/overview"
"destination": "/prompting/overview",
"permanent": true
}
]
}
+1 -1
View File
@@ -135,7 +135,7 @@ HyperFrames projects created with `npx hyperframes init` scaffold both `CLAUDE.m
## Next steps
<CardGroup cols={2}>
<Card title="Prompting guide" icon="message" href="/guides/prompting">
<Card title="Prompting guide" icon="message" href="/prompting/overview">
Vocabulary and patterns that produce better compositions.
</Card>
<Card title="Catalog" icon="grid-2" href="/catalog/blocks/data-chart">
+1 -1
View File
@@ -143,7 +143,7 @@ Then iterate:
## Next steps
<CardGroup cols={2}>
<Card title="Prompt Guide" icon="message" href="/guides/prompting">
<Card title="Prompt Guide" icon="message" href="/prompting/overview">
More prompt patterns for HyperFrames across Claude Code, Claude Design, and other agents.
</Card>
<Card title="@hyperframes/player" icon="play" href="/packages/player">
+1 -1
View File
@@ -175,7 +175,7 @@ Authorize via OAuth when prompted. See the [MCP guide](/guides/mcp) for full det
## Next steps
<CardGroup cols={2}>
<Card title="Prompting guide" icon="message" href="/guides/prompting">
<Card title="Prompting guide" icon="message" href="/prompting/overview">
Vocabulary and patterns that produce better compositions.
</Card>
<Card title="Catalog" icon="grid-2" href="/catalog/blocks/data-chart">
+1 -1
View File
@@ -320,7 +320,7 @@ The MCP is a HeyGen-hosted product that wraps:
<Card title="Quickstart" href="/quickstart">
Try HyperFrames locally with the open-source CLI.
</Card>
<Card title="Prompting guide" href="/guides/prompting">
<Card title="Prompting guide" href="/prompting/overview">
Tips for getting the best results when working with AI agents.
</Card>
<Card title="Catalog" href="/catalog/blocks/data-chart">
+1 -1
View File
@@ -169,7 +169,7 @@ Then iterate the same way as the Claude Design path:
<Card title="Claude Design Guide" icon="message" href="/guides/claude-design">
The closed-source flavor of the same workflow — useful when you don't have a CLI on your laptop.
</Card>
<Card title="Prompt Guide" icon="message" href="/guides/prompting">
<Card title="Prompt Guide" icon="message" href="/prompting/overview">
More prompt patterns for HyperFrames across Claude Code, Claude Design, Open Design, and other agents.
</Card>
</CardGroup>
+3 -3
View File
@@ -141,7 +141,7 @@ npx hyperframes transcribe narration.wav
| `narration.txt` | The exact spoken text with pronunciation substitutions applied (`API` → `A P I`, `$2T` → `two trillion`). Distinct from `SCRIPT.md` so you can regenerate the audio later with a different voice without redoing the substitutions. |
| `transcript.json`| `[{ text, start, end }]` for every word. Every later step reads this for timing. |
Hyperframes ships multiple TTS adapters (Kokoro, ElevenLabs, HeyGen); see [`/media-use`](/guides/prompting) for the skill that picks one. After generating audio, update `STORYBOARD.md` with the real beat boundaries from `transcript.json`.
Hyperframes ships multiple TTS adapters (Kokoro, ElevenLabs, HeyGen); see [`/media-use`](/guides/skills#domain-skills-loaded-on-demand) for the skill that picks one. After generating audio, update `STORYBOARD.md` with the real beat boundaries from `transcript.json`.
**Gate:** `narration.wav`, `narration.txt`, and `transcript.json` exist. `STORYBOARD.md` beat timings reference real timestamps, not estimates.
@@ -153,7 +153,7 @@ This is where the storyboard becomes runnable HTML. Each composition is a self-c
For multi-beat videos, spawn a focused sub-agent per beat. Each one gets fresh context, the storyboard section for its beat, the asset paths it needs, and the relevant technique references. That produces noticeably better output than building every beat in one long-running context.
After each composition is built, run a self-review for layout, asset placement, and animation quality. The [`/hyperframes-core`](/guides/prompting) skill encodes the composition rules — required `class="clip"` attributes, `data-*` attribute semantics — and [`/hyperframes-animation`](/guides/prompting) covers GSAP timeline registration and adapter registries.
After each composition is built, run a self-review for layout, asset placement, and animation quality. The [`/hyperframes-core`](/guides/skills#domain-skills-loaded-on-demand) skill encodes the composition rules — required `class="clip"` attributes, `data-*` attribute semantics — and [`/hyperframes-animation`](/guides/skills#domain-skills-loaded-on-demand) covers GSAP timeline registration and adapter registries.
**Gate:** Every composition is self-reviewed. No overlapping elements, no misplaced assets, no static images sitting unanimated.
@@ -209,7 +209,7 @@ For a 5-second one-shot animation, a single hand-authored composition is fine; t
<Card title="Website to Video" icon="globe" href="/guides/website-to-video">
The full website-to-video guide built on this pipeline.
</Card>
<Card title="Prompting" icon="comment" href="/guides/prompting">
<Card title="Prompting" icon="comment" href="/prompting/overview">
How to invoke the pipeline through your AI agent.
</Card>
<Card title="Launch Videos" icon="rocket" href="/launch-videos">
+2 -3
View File
@@ -217,14 +217,13 @@ For GSAP animation, register one paused timeline per composition:
const tl = gsap.timeline({ paused: true });
tl.from("#title", { opacity: 0, y: 40, duration: 0.6 });
tl.set({}, {}, 5); // keeps the timeline at least 5 seconds long
window.__timelines["main"] = tl;
</script>
```
<Warning>
If a video cuts off early, check that the GSAP timeline is at least as long as the intended edit. The final `tl.set({}, {}, 5)` pattern is the fix.
Render duration comes from `data-duration` on the composition and clips, not from GSAP timeline length. If a video cuts off early, check those timing attributes. Do not pad the timeline with an empty `tl.set()` sentinel.
</Warning>
## Render Presets
@@ -285,7 +284,7 @@ For editor-facing changes, keep `npx hyperframes preview` running, then have the
| Need to share editable project | `npx hyperframes publish` |
<CardGroup cols={2}>
<Card title="Prompt Guide" icon="wand-magic-sparkles" href="/guides/prompting">
<Card title="Prompt Guide" icon="wand-magic-sparkles" href="/prompting/overview">
How to direct AI agents to build better videos
</Card>
<Card title="Timeline Editing" icon="timeline" href="/guides/timeline-editing">
+3 -3
View File
@@ -27,7 +27,7 @@ Assembled:
> /motion-graphics Make an 8-second 1920x1080 video. Beat 1 (0-4s): dark macOS terminal types "npx skills add heygen-com/hyperframes" character by character, then hold on the blinking cursor. Beat 2 (4-5s): the terminal shatters into fragments. Beat 3 (5-8s): bold white kinetic text on black slams in word by word, snappy: "YOU JUST MADE THIS / WITH HYPERFRAMES." Adapt the `code-typing` and `vfx-shatter` registry blocks; hand-author the kinetic text. No narration, no image or media files.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
<Note>
@@ -88,7 +88,7 @@ The skeleton above is how you ask. This is what the agent writes, and it's worth
| --- | --- |
| `class="clip"` | Marks a timed section. The framework owns its visibility — never animate a clip's own opacity or `display` to hide it. |
| `data-start` / `data-duration` / `data-track-index` | When the clip begins, how long it runs, and which track it sits on. Two clips on the same track index must not overlap in time. |
| `window.__timelines["<id>"]` | Every composition registers exactly one paused GSAP timeline here, built synchronously at load. The renderer seeks that timeline frame by frame — which is why nothing may depend on wall-clock time or unseeded randomness. |
| `window.__timelines["<id>"]` | Every GSAP-driven composition registers exactly one paused timeline here, built synchronously at load. The renderer seeks that timeline frame by frame — which is why nothing may depend on wall-clock time or unseeded randomness. Other adapters, including Lottie, CSS animations, and WAAPI, register through their own seekable runtime contracts. |
| `<video muted>` + a separate `<audio>` | Video elements render muted and their sound rides a sibling audio element, so the mixer can duck and balance it independently. |
You rarely write these by hand, but naming them in a prompt is legitimate and sometimes necessary — "put the captions on their own track index," "keep it one composition file, one timeline" — and it's the vocabulary every error message uses. The full contract lives in the `/hyperframes-core` skill; the [appendix](/prompting/rules-and-anti-patterns) carries the rules that most often bite.
@@ -101,7 +101,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **Mount (714s).** Traveling along the wire: it splits into three parallel track lanes; clip chips slide in along the direction of travel and seat onto the lanes on their spoken cues (audio track chip, video track chip, our protagonist chip among them). Small mono labels (`data-start`, `data-track-index`) tag themselves onto chips as the camera passes. The lanes merge back to one wire as the camera accelerates out.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-mount.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-mount.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [The specification dial](/prompting/specification-dial) — how much of the skeleton to fill in, and when density stops being optional.*
+2 -2
View File
@@ -3,7 +3,7 @@ title: Capstone — every technique, one journey
description: "One prompt, one continuous camera move, every technique in this guide — the viewer rides the timeline itself from typed markup to rendered MP4."
---
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*"The Timeline" — 1920x1080, ~62 seconds, one prompt, one unbroken camera move, unedited.*
If you read the guide in order, you have already seen every piece of this film. Each region was cut out and embedded in the chapter that teaches its technique — the typed opening in [Code animations](/prompting/code-blocks), the chart and map in [Data and maps](/prompting/data-and-maps), the footage pipeline in [Media and audio](/prompting/media-and-audio), the glass and mural in [VFX](/prompting/vfx-and-liquid-glass) and [Generated artwork](/prompting/generated-artwork), the beat grid in [Music](/prompting/music-and-slideshows), the 3D coil in [Runtimes and 3D](/prompting/runtimes-and-3d), the continuous camera in [Motion](/prompting/motion), the seeded finale in [Rendering and output](/prompting/rendering-and-output). This page is where the pieces become one composition, and the prompt below is the glue: every paragraph of it is a chapter of this guide restated as a binding clause.
@@ -109,7 +109,7 @@ HyperFrames scopes `data-composition-variables` **per composition file**, so the
hyperframes render --variables '{"ground":"#0d1420","ink":"#c8ff3d"}' --strict-variables
```
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-reskin.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-reskin.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*The same composition, navy/acid-green — the wire, ruler, chart, map, glass, and even the generated mural all follow the override.*
The mural trick from the previous capstone carries over: the artwork is generated **palette-neutral** (grayscale) and duotoned live by CSS layers driven by the `ground`/`ink` variables, so even the raster re-skins. Keep color in CSS and shapes in the raster whenever a template frame needs to survive a re-skin.
@@ -12,7 +12,7 @@ One prompt to [`/embedded-captions`](/prompting/overview), pointed at an existin
Captions route by **identity**, not by mode. You pick one look from the catalog; the engine behind it is a lookup detail you never have to name. The default is a clean verbatim rail — `anchor` — with the occasional peak word composited behind the subject.
> /embedded-captions Add captions to ./interview.mp4. Use the `anchor` identity — clean verbatim rail carrying the spoken words, readable lower-third. Promote the single hardest-hitting word to an embed behind the speaker; highlight one key word in each rail line. Keep the source aspect ratio. Footage stays untouched.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/captions-anchor-rail.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/captions-anchor-rail.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above on generated avatar footage, unedited — one earned embed behind the speaker, everything else on the rail.*
+4 -4
View File
@@ -40,7 +40,7 @@ Three [Text Effects](/catalog/components/morph-text) components do one focused j
> /faceless-explainer 30-second vertical explainer. Add [`caption-highlight`](/catalog/components/caption-highlight) captions, TikTok-style — the visible line stays up, one word highlighted at a time.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-captions-catalog.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-captions-catalog.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -50,13 +50,13 @@ Three [Text Effects](/catalog/components/morph-text) components do one focused j
> Hype captions with [`caption-kinetic-slam`](/catalog/components/caption-kinetic-slam): one full-screen word per beat, alternating slam-in direction.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-kinetic-slam.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-kinetic-slam.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above with an authored 24-word line, unedited.*
> Neon music-video captions using [`caption-neon-glow`](/catalog/components/caption-neon-glow). Make brand names larger with an accent color and highlight the numbers differently.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-neon-glow.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-neon-glow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — the brand renders 1.4x in magenta, numbers in amber, distinct from the default cyan.*
@@ -100,7 +100,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> THEN they speak, and the main **keywords of their own line — derived from the clip's transcription — land word-synced as huge display text BEHIND the cutout**, each keyword slamming in on its spoken moment with the subject's silhouette occluding it (the two-layer text-behind-subject plate); style the keyword type by adapting a bold **catalog caption component** (`caption-kinetic-slam` or similar) at display scale.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [When to generate artwork](/prompting/generated-artwork) — where hand-drawn HTML/CSS/SVG wins, and where a generated image beats it.*
+2 -2
View File
@@ -13,7 +13,7 @@ Verified, from the [examples](/prompting/examples) page — a 30-second feature
> /pr-to-video Make a 30-second 1920x1080 feature-reveal video from [PR URL]. Lead with what users get, not the diff; show the key code change with the `code-diff` block for one beat only; end on version number + repo URL. No narration, kinetic captions instead.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -48,7 +48,7 @@ What you can already steer from the prompt, before you've learned any technique.
<Accordion title="Changelog roundup">
> /pr-to-video Make a ~40-second 1920x1080 changelog video from [PR URL]. Changelog angle: open with the release line, then one beat per notable change — a short label and a one-line "what it does" each. Show at most two `code-diff` hunks across the whole video. End on version + repo URL. Calm male TTS narration, no captions.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-pr-changelog.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-pr-changelog.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from this prompt with [PR URL] = heygen-com/hyperframes#2092, unedited.*
A changelog trades depth for breadth — many small changes, each a beat, rather than one change explored deeply. Keep code beats sparse so the pace stays fast. A PR doesn't carry its shipping version — the agent finds it from the release tag or the package manifest on main.
+6 -6
View File
@@ -44,7 +44,7 @@ The first four are the workhorses of a code *walkthrough* — they keep the code
> ```
> Use the `code-typing` registry block. No narration, no image or media files.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-typing.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-typing.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -65,13 +65,13 @@ For "here's what changed," hand `code-diff` the before and after and let it colo
> added: `const res = await fetch(url, { signal })`
> Use the `code-diff` registry block. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-diff.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-diff.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
> /motion-graphics 5-second 1920x1080 video. Show a 12-line config file; a highlight band sweeps to line 7 (`timeout: 30_000`) while the surrounding lines dim. Hold with line 7 lit and the cursor blinking. Use the `code-highlight` registry block. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-highlight.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-highlight.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — the agent authors plausible surrounding config lines; paste all 12 if the exact file matters.*
@@ -85,7 +85,7 @@ For "here's what changed," hand `code-diff` the before and after and let it colo
> /motion-graphics 6-second 1920x1080 video. Scroll a ~60-line source file so line 44 (`return dedupeFrames(frames)`) arrives at center and gets spotlighted; ease the scroll and let it settle without snapping. Use the `code-scroll` registry block. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/code-scroll.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/code-scroll.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
**Ask the scroll to ease and settle, not snap.** A linear scroll that stops dead reads mechanical.
@@ -120,7 +120,7 @@ The [Code Snippets](/catalog/blocks/code-snippet-monokai) blocks are pre-styled
> /motion-graphics 5-second 1920x1080 video. A macOS Terminal window in the Ocean profile types `npx skills add heygen-com/hyperframes` character by character, then holds on the typed, unexecuted command with the cursor blinking — no output, no second prompt. Use the `code-snippet-apple-terminal-ocean` registry block. No narration.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/terminal-ocean.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/terminal-ocean.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -151,7 +151,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **Type (07s).** Black-on-charcoal close-up: a cursor types real HyperFrames markup character by character — `<div class="clip" data-start="0" data-duration="4">` and a `gsap.timeline({ paused: true })` line. As the typed line completes, the text's baseline extends and becomes **the wire** — the underline literally grows into the timeline and the camera begins its dolly along it. The typed div folds into a compact clip chip (persistent element 3) that drops onto the wire. Kinetic display type states "WRITE HTML." as the travel begins.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-type.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-type.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Data and maps](/prompting/data-and-maps) — the same named-block, quoted-copy pattern, for charts, stats, and maps instead of code.*
+6 -6
View File
@@ -22,12 +22,12 @@ Feed data inline or as a file. Small series go straight in the prompt; a CSV get
> ```
> Use the `data-chart` registry block. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/chart-languages.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/chart-languages.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — labels count up while the next bar is already growing.*
> /motion-graphics 10-second 1920x1080 video, dark slate background. Title "Top languages 2026" top-left. Five horizontal bars (Python, TypeScript, Rust, Go, Java) grow from zero with staggered starts, overtaking each other twice mid-animation; each bar has a right-edge value label counting up to its final %. End state holds 2s, alive — the leader pulses once, timed to finish exactly on the last frame, never a frozen tail. Hand-author the marks (no chart library) and make them *look* hand-drawn: wobbly ink strokes, not clean rectangles. Say which two pairs overtake and when, or the reveal will land on a different number of crossings each run. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/barrace-handdrawn.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/barrace-handdrawn.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — hand-authored ink strokes, no chart library; ranks swap twice.*
@@ -45,7 +45,7 @@ For a single hero number, [`apple-money-count`](/catalog/blocks/apple-money-coun
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then settles into a gentle ambient idle. Use the `apple-money-count` registry block as base. No narration.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/money-count.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/money-count.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -66,7 +66,7 @@ The US map encodings combine — asking to "shade states *and* draw flows betwee
> /motion-graphics 12-second 1920x1080 video. A US choropleth shades states by adoption rate with staggered reveals and a gradient legend, then connection arcs draw between San Francisco, Austin, and New York. Use the `us-map` and `us-map-flow` registry blocks. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-us-map-flows.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-us-map-flows.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -88,7 +88,7 @@ For a point-to-point journey — a route drawing across a map with a landing bea
> /motion-graphics 6-second 1920x1080 video. A realistic map with a plane flying between two cities, a marker circle at the origin, and a landing pop at the destination. Use the `nyc-paris-flight` registry block as base — the route runs New York (JFK) → Paris (CDG), labelled at both ends. Keep the block's own title card and route ticks. End on the settled map, not on the block's white-out hand-off frame. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/flight-route.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/flight-route.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -113,7 +113,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
>
> **Everywhere (2128s).** The wire arcs and the ground falls away: adapt the **`world-map` registry block** — the dotted world map scrolls beneath while the wire becomes a great-circle route arcing across it. Real render infrastructure, truthfully labeled: pulses light up at AWS and Google Cloud regions (US-EAST-1 · EU-WEST-1 · AP-SOUTH-1) with a "CLOUD RENDER · LAMBDA + CLOUD RUN" kicker […]
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-data-map.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-data-map.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Overlays and lower thirds](/prompting/overlays-and-lower-thirds) — naming timed blocks that sit above your footage or scene, instead of ones that render the scene itself.*
+2 -2
View File
@@ -53,7 +53,7 @@ For a series — a launch set, a weekly clip, a per-region cut — consistency c
> All four videos share `frame.md` for palette and type. Only the headline and the stat change per video.
Because the runtime exposes every declared brand token as a CSS custom property, the parts that stay constant come from the one spec (or one set of imported Figma tokens), and the parts that vary become [variables](/prompting/variables-and-templating). Change one brand value in the spec and every video re-skins on the next render — you don't touch four files. This is where design systems and templating meet: the brand is shared, the content is parameterized.
The parts that stay constant come from the one authoring spec (or one set of imported Figma tokens), and the parts that vary become [variables](/prompting/variables-and-templating). When `frame.md` changes, rerun the workflow steps that generate or assemble the affected compositions so the authored HTML picks up the new brand value. For existing compositions that must re-skin at render time, declare the shared brand tokens as composition variables and bind them through CSS custom properties. This is where design systems and templating meet: the brand is shared, the content is parameterized.
## Supplying brand assets by path
@@ -97,7 +97,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **Design system: the provided `frame.md` is the single source of brand truth — read it first and obey it exactly.** It is the real HyperFrames brand (by HeyGen), dark-first: flat near-black ground […] **mint `#3CE6AC` used sparingly as the single accent — mint means go / primary / active**. The mint→cyan gradient (`#3CE6AC → #00E3FF`) appears in exactly one place in the whole film: the final CTA lockup.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause paying off, rendered — the closing lockup, where the brand file's display face and its one sanctioned gradient finally appear together.*
*Next: [Variables and templating](/prompting/variables-and-templating) — turn the brand tokens that repeat across a series into named slots you fill per render.*
+4 -4
View File
@@ -39,10 +39,10 @@ Bound moves by the composition's length — a 4-second clip moved to 0:08 in a 1
- ❌ `tighten up the opening`
- ✅ `intro clip duration = 3s; leave its animation and position alone` — one attribute, and the freeze clause stops a rebuild from drifting on axes you'd already settled
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-before.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-before.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Before — the untouched composition.*
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-after.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*After — four verbatim edits from this page (move, right-trim, retime, restyle-with-freeze); each touched exactly the attribute the verb map promises, gates green after every edit.*
@@ -56,7 +56,7 @@ Name the exact cut point. The agent turns one clip into two adjacent clips; you
## Retime a scene
Retiming is a duration change, but with one catch worth knowing: a scene driven by a GSAP timeline needs the timeline to be at least as long as the new duration, or the render cuts off early.
Retiming starts with the scene's `data-duration`. If the motion should keep its original speed, the timeline can finish early and hold its final state while the scene continues. If the motion itself should slow down or spread across the longer scene, ask the agent to retime the affected tweens as well.
> Make scene 2 run 4 seconds instead of 2.5 — keep the animation, just give it more room.
@@ -64,7 +64,7 @@ Retiming is a duration change, but with one catch worth knowing: a scene driven
- ✅ `scene 2 duration = 4s, same motion, add the extra time as a hold at the end`
<Warning>
If a retimed scene cuts off before its new end, the fix is extending the GSAP timeline length (the `tl.set({}, {}, <seconds>)` sentinel pattern). The agent handles this; it's the single most common reason a lengthened clip renders short. See the [Video editor cheatsheet](/guides/video-editor-cheatsheet#timing-cheatsheet).
Render duration comes from `data-duration`, not GSAP timeline length. Do not pad a timeline with an empty `tl.set({}, {}, <seconds>)` sentinel. If a scene still ends early, check the scene and composition timing attributes in the [Video editor cheatsheet](/guides/video-editor-cheatsheet#timing-cheatsheet).
</Warning>
## Make it snappier (retiming *feel*, not just duration)
+18 -18
View File
@@ -16,44 +16,44 @@ Every prompt below has been run end-to-end and one-shots a finished video that p
<AccordionGroup>
<Accordion title="Stat count-up">
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then everything settles into a gentle ambient idle (subtle breathing scale, slow particle drift). Use the `apple-money-count` registry block as base. No narration. **Spectacle beat:** On the land at 4s, a burst of ~60 paper money notes erupts from behind the numeral and flutters down, seeded so every render is identical, settled by 5.5s — the one exaggeration.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Animated social post">
> /motion-graphics 7-second 1080x1350 vertical video. A real tweet card (handle @hyperframes, text "we render video from HTML now. no timeline UI. just code.") slides up over a soft animated gradient, likes counter ticks 0→1.2K, then the card tilts in 3D and a highlight sweeps the second sentence. Hold on the card at the end. Use the `x-post` and `vfx-liquid-background` registry blocks. No narration, no image or media files. **Spectacle beat:** When the like count lands, the heart pops to 1.6× with a radial burst of ~24 seeded particles and settles — one moment, nothing else exaggerated.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-tweet.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-tweet.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Map route">
> /motion-graphics 8-second 1920x1080 video. Dark world map, a glowing arc animates from San Francisco to Tokyo over 3s, destination pin drops with a pulse, then camera zooms into Tokyo and the label "LATENCY: 89ms" types on. Use the `nyc-paris-flight` registry block as the base pattern, restyle to teal on charcoal. No narration. **Spectacle beat:** The destination pin's landing fires a triple concentric shockwave that expands past the label and fades, with a brief chromatic split on the pin.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-map-route.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-map-route.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Logo sting with shader transition">
> /motion-graphics 5-second 1920x1080 logo sting. Beat 1 (0-2s): the word "ACME" assembles from scattered particles. Beat 2 (2-3s): full-frame `swirl-vortex` shader transition. Beat 3 (3-5s): logo lockup + tagline "Ship faster." settles on white, holds. Use `code-particle-assemble` for the assembly. **Spectacle beat:** The particle assembly IS the spectacle — ~1200 seeded particles converging with visible motion trails, and a single bloom flash on the frame the wordmark completes.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-logo-sting.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-logo-sting.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Product launch from a URL">
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB. **Spectacle beat:** One exaggerated moment: the end card's logo lands with a bloom flash and a fast light-sweep across the wordmark. Feature beats stay restrained.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Explainer from pasted text">
> /faceless-explainer Turn this into a ~60-second 1080x1920 vertical explainer: [paste your text]. One idea per scene, big typography, diagrams over stock footage, brand color #FF5533 on off-black. Male TTS voice, calm. Embedded captions, keywords highlighted in the brand color. **Spectacle beat:** One exaggerated moment: the final CTA's key phrase slams in at 1.5× with a chromatic split that resolves in 0.2s. Every other scene stays typographically calm.
With a verbatim script, final duration follows the narration — ask for "~60 seconds", not exactly 60.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="GitHub PR reveal">
> /pr-to-video Make a 30-second 1920x1080 feature-reveal video from [PR URL]. Lead with what users get, not the diff; show the key code change with the `code-diff` block for one beat only; end on version number + repo URL. No narration, kinetic captions instead. **Spectacle beat:** The added line in the diff ignites — a green light-sweep travels its length and the line blooms as the camera settles on it.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Beat-synced slideshow">
> /music-to-video 20-second 1080x1080 video. Resolve a dark, driving electronic track and cut to its analyzed beat grid — one image per bar, punch-in on downbeats, whip-pan transitions on phrase changes. Generate the eight images rather than using stock: brutalist concrete details as high-contrast monochrome abstracts, one consistent visual language across all eight, each carrying a single cyan light thread. Chrome: a `PLATE 0N/08` counter. End card "CAST IN PLACE" in condensed caps over a hard-edged opaque scrim, with the sub-line "EIGHT SURFACES · ONE HUNDRED BPM". No TTS. **Spectacle beat:** On the loudest downbeat, one image punches to 1.25× with an RGB channel split that snaps back on the next beat. The other cuts stay clean.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
</AccordionGroup>
@@ -63,52 +63,52 @@ Every prompt below has been run end-to-end and one-shots a finished video that p
<AccordionGroup>
<Accordion title="Kinetic quote">
> 12-second 1920x1080 video, off-white background. The quote "Simplicity is the ultimate sophistication" builds word by word in massive black serif type, each word snapping in with a slight overshoot; "sophistication" lands last in italic with a hand-drawn underline drawing on. Attribution "— Leonardo da Vinci" fades in small, bottom-right, at 9s. Settle into a barely-visible ambient idle to the end. No audio. **Spectacle beat:** The final word lands 1.4× oversized with an ink-bleed bloom before settling to its true size — the sentence's payoff.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-kinetic-quote.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-kinetic-quote.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Countdown title card">
> 6-second 1920x1080 video. Numbers 3, 2, 1 each fill the frame for one second — each number wipes in with a diagonal mask and its background alternates black/white with inverted text. At 3s the frame slams to "LAUNCH DAY" in condensed caps with a screen-shake, holds with a subtle grain flicker. No audio. **Spectacle beat:** The frame snap at 3s is the moment — a hard white flash frame and a 1.5° rotation kick settling in 0.25s.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-countdown.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-countdown.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Bar chart race">
> 10-second 1920x1080 video, dark slate background. Title "Top languages 2026" top-left. Five horizontal bars (Python, TypeScript, Rust, Go, Java) grow from zero with staggered starts, overtaking each other twice mid-animation; each bar has a right-edge value label counting up to its final %. End state holds 2s with the leader pulsing once. Hand-draw everything — no chart library. No audio. **Spectacle beat:** The leader's single end pulse is the moment — a +16px overshoot and a bright cap flare, returning to rest exactly on the last frame.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-bar-race.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-bar-race.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Before / after split">
> 8-second 1920x1080 video. Vertical split: left half labeled "BEFORE" shows a cluttered mock UI (grey, 12 overlapping windows drawn in CSS), right half "AFTER" shows one clean card. Both halves settle within the first second. A vertical divider line sweeps left to right at 4s, wiping the clutter into the clean state across the full frame. End on "One tool." centered. No audio. **Spectacle beat:** The divider's wipe is the moment — a bright scan-line travels the split with a bloom as it crosses, and the AFTER half resolves behind it.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-before-after.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-before-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Loader → reveal">
> 7-second 1920x1080 video, black background. A thin white progress ring draws from 0° to 360° over 4s while a percentage counter (0→100) ticks in the center in mono type, matching the arc exactly. Ring and counter fade out fully by 4.2s; at 4.2s the ring bursts outward into short radial dashes and "READY." stamps into the center, then holds. No audio. **Spectacle beat:** The ring's completion at 100% detonates — it flashes white, expands past frame, and the reveal rides that expansion out.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-loader-ready.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-loader-ready.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="3D cards (Three.js)">
> 9-second 1920x1080 video, light warm cream background. Build the scene in Three.js via the adapter: three rounded card meshes labeled "Design", "Build", "Ship" lie flat on the ground plane, camera at a fixed 3/4 isometric angle, soft directional light + ambient so the cards cast soft shadows. One at a time each card lifts and straightens upright to face the viewer center-frame while the other two slide apart and dim; then it returns. Finish with all three standing upright in a row by 8.5s, hold. All easing power3.inOut. No audio. **Spectacle beat:** As the cards rise into their stack, a single specular sweep rakes across all three faces in sequence, catching each edge.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="SVG line-draw logo reveal">
> 6-second 1920x1080 video, deep green background. A minimal mountain-range logo draws on as an SVG stroke over 2.5s, then the stroke fills with cream, the wordmark "NORTHTRAIL" letterspaces in beneath it, and a thin rule expands from center. Hold the last 1.5s. No audio. **Spectacle beat:** The stroke's completion is the moment — the drawn path flares once along its whole length, then the fill floods from that flare.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-svg-logo.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-svg-logo.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Word-swap headline">
> 8-second 1920x1080 video, white background. Static sentence "Make it ___." in huge black type stays centered while the blank cycles through "faster", "simpler", "yours" — each swap flips vertically like a split-flap board, 1.5s apart, with a slight blur on motion. Final word "yours." lands in orange and the period pops. No audio. **Spectacle beat:** The last swap lands hardest — that word arrives 1.3× behind a motion-blur streak that resolves as it settles.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-word-swap.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-word-swap.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Stat tile dashboard">
> 10-second 1920x1080 video, near-black background. Four stat tiles slide up in a 2x2 grid, staggered: "99.99% uptime", "42ms p50", "18M req/day", "0 incidents". Each tile's number counts or decrements to its value with its own easing; sparklines draw underneath in teal. At 8s the grid scales back and "Built to hold." fades in above. No audio. **Spectacle beat:** When the fourth tile lands, all four numerals flare in unison for three frames — one synchronized accent, then back to restrained idles.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-data-ticker.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-data-ticker.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
<Accordion title="Vertical social hook">
> 9-second 1080x1920 vertical video, charcoal background. Social-style hook: "nobody talks about this" types on center in bold white, then each following phrase replaces it on a hard cut every 1.5s — "it's not your code", "it's your prompts", "here's the fix" — with yellow highlight bars behind key words, alternating tilt. Last phrase holds with an arrow-down bounce. No audio. **Spectacle beat:** The final phrase is the payoff — it slams in at 1.35× with a three-frame shake and a chromatic split that resolves fast.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-vertical-hook.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-vertical-hook.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
</Accordion>
</AccordionGroup>
+2 -2
View File
@@ -13,7 +13,7 @@ Verified, from the [examples](/prompting/examples) page — a ~60-second vertica
> /faceless-explainer Turn this into a ~60-second 1080x1920 vertical explainer: [paste your text]. One idea per scene, big typography, diagrams over stock footage, brand color #FF5533 on off-black. Male TTS voice, calm. Embedded captions, keywords highlighted in the brand color.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -51,7 +51,7 @@ What you can already steer from the prompt, before you've learned any technique.
Shorter runtime, landscape for YouTube / embed. Fewer scenes means the topic has to compress — naming the takeaway tells the workflow what to keep.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-explainer-landscape.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-explainer-landscape.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from this prompt with the topic swapped to HTTP caching (cache diagram as the metaphor), unedited — 26s, because the narration sets the length.*
</Accordion>
+3 -3
View File
@@ -19,10 +19,10 @@ Three rules that make this work:
The same brief — four people arm in arm, warm gradient sweaters, flat-illustration style — built both ways. Same animation beats, same craft layer (lighting, atmosphere, grade); the only variable is where the figures came from.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-hand-drawn.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-hand-drawn.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Hand-drawn SVG figures — clean, but the proportions and gesture read as clipart.*
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-generated.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-generated.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Generated illustration animated as layers — real anatomy and editorial shading; the animated line still passes behind the figures because the artwork was keyed to transparency.*
<Note>
@@ -33,7 +33,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> […] over a **generated-artwork backdrop** — a flat abstract mural evoking motion trails, generated **palette-neutral (grayscale) and duotoned live by CSS** from the two variables so it re-skins with everything else. **The mural is a full-frame, screen-fixed backdrop: it never moves on screen — the widening iris circle alone reveals it already in place at full frame […] and it exits by fading out.**
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [VFX and liquid glass](/prompting/vfx-and-liquid-glass) — device mockups, frosted glass, and cinematic effects for when the layer on top needs its own spectacle.*
+2 -2
View File
@@ -96,7 +96,7 @@ None of this changes how you phrase the ask: name the footage by path like any o
> Build a short picture-in-picture piece from `source-hevc.mp4` — inset it bottom-right over a full-bleed background scene, with a soft rounded border.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/proxy-footage.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/proxy-footage.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — the source clip is a plain H.265/HEVC file; render decoded it directly via FFmpeg, while preview would have used the automatic H.264 proxy.*
See the [Rendering guide](/guides/rendering#input-video-codecs) for the mechanics — proxy generation, caching, and which codecs it covers.
@@ -136,7 +136,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> […] a real talking-head clip (generate a short clip of a person speaking one neutral line via the media pipeline's avatar video generation […] **transcode it to HEVC `hvc1`** so the automatic proxy subsystem carries preview) sits as a clip on the wire. The order of operations IS the story: as the camera arrives and BEFORE the person speaks, the framework mattes the footage — **the background peels away via background removal** […] THEN they speak, and the main **keywords of their own line — derived from the clip's transcription — land word-synced** […] The clip's own audio ducks the BGM briefly; the VO resumes as the camera pulls away.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Design systems and brand](/prompting/design-systems) — pointing the agent at a source of brand truth instead of describing a vibe.*
+1 -1
View File
@@ -13,7 +13,7 @@ The canonical shape: routed, spec'd, beat-timestamped, copy quoted, technique pi
> /motion-graphics Make an 8-second 1920x1080 video. Beat 1 (0-4s): dark macOS terminal types "npx skills add heygen-com/hyperframes" character by character, then hold on the blinking cursor. Beat 2 (4-5s): the terminal shatters into fragments. Beat 3 (5-8s): bold white kinetic text on black slams in word by word, snappy: "YOU JUST MADE THIS / WITH HYPERFRAMES." Adapt the `code-typing` and `vfx-shatter` registry blocks; hand-author the kinetic text. No narration, no image or media files.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
+12 -12
View File
@@ -59,7 +59,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> 6-second 1920x1080 live telemetry panel: an `ARR · LIVE` eyebrow with a status dot, `PROD · US-EAST-1` opposite, `$4.200M` at display scale with a delta chip, a sparkline of the reading history beneath, and a footer row reading `LAST SYNC` and `READINGS`. The panel rises in and lands by 1.9s, then stays alive because the feed is — a new reading arrives every 300ms and each one moves exactly what it should: the last digits change, the sparkline extends one segment with its leading dot, `LAST SYNC` restamps, `READINGS` increments. The status dot keeps a 1s heartbeat because the connection is up. Nothing else moves. Fix the sparkline's y-scale up front so an arriving reading never rescales the axis.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule1-nothing-stops.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule1-nothing-stops.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — from 2.0s the left's 120 remaining frames share a single hash; all 180 of the right's are distinct. Every movement on the right answers "because": the dot beats because the connection is up, the digits change because a reading arrived, the sparkline extends because that reading is now history. That's the test — not "is there enough motion" but "can each thing that moves say why".*
*The clearest artifact is the footer. The frozen half reads `LAST SYNC 09:41:21.75 · READINGS 22` while the live one reads `09:41:23.95 · 30`. A still frame of the left half looks like a perfectly good stat card; the moment it sits next to a running one you can read exactly how long the feed has been dead. That is what a frozen hold communicates to a viewer, whether or not you meant it.*
@@ -74,7 +74,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …an isometric deploy pipeline of five stages, each with its own accent colour — `SOURCE` mint, `BUILD` cyan, `TEST` violet, `DEPLOY` amber, `EDGE` rose — bolted along a rail with support posts and numbered floor bays. The block at each stage and its card wear the same colour. Lay the stages out where they really are, 640px apart across 2.5 frame widths, and **move the camera** across the whole run in one continuous linear pass, `ease: none`. The floor and rail travel with the camera 1:1 because they are the same space; distant structures track at a fifth. A packet of work runs the wire and ignites each stage in its colour as it reaches it, so a stage is revealed by arriving at it rather than by appearing.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule2-camera-actor-v2.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule2-camera-actor-v2.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — same five stages, same colours, same six seconds. On the left the block never leaves the centre of frame: five stages, one place. On the right you travel to each one, and neighbours stay visible on the way, so the five read as five points along a single run.*
*The rule is usually stated as "give every scene a camera move," which undersells it. The real claim is about what a **cut throws away**. A move carries the spatial relationship between two shots; a cross-fade carries none, so the colour simply becomes a different colour where it stood. Watch the amber `DEPLOY` block still sitting behind frame-left as the camera settles on rose `EDGE` — that adjacency is information, and it does not survive a dissolve.*
@@ -91,7 +91,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …`Rolling out to every region` over a dotted world map with twelve edge regions marked and a live `n / 12` tally. A progressive rollout spreads outward from `us-east-1`, reaching each region in order of its distance from the origin, 0.09s apart: a link draws from the nearest already-live region and lands exactly as that region's core ignites, its dot field turns mint, a ping carries onward and an ACK dash returns up the link. Each region's 0.5s ignite is still running when the next three begin.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule3-overlapping-action.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule3-overlapping-action.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — twelve distinct ignition frames on the right, 0.088s apart, against a single frame on the left. At peak, all twelve regions are animating at once.*
*Stagger here isn't a styling preference, it's the difference between a true statement and a false one. A rollout propagates; twelve regions cannot go live on the same frame, and the simultaneous version says something about the system that isn't true. Watch the tally: the left jumps `0 → 12` in one frame and the map gives you no way to tell where the rollout started, because there is no order to read. Note also what is **not** staggered — the twelve region markers all appear on the same frame in both halves, because the regions already existed. Stagger what is happening, not what is merely present.*
@@ -106,7 +106,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …an itemized coffee-shop receipt; a payment-confirmation sheet rises 470px over 1.2s to cover its lower half while fading up from 0. Rotation, scale and blur are never touched. The receipt dims behind it. The sequence plays twice.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule4-compound-properties.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule4-compound-properties.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — identical travel (470px), identical window (0.25s → 1.45s), identical ease. The only difference is how many properties ride along. Both halves are pixel-identical at rest, so everything you see mid-flight is the cost of the extra three. On the left, "Payment confirmed" is an unreadable tilted smear for most of its arrival; on the right it is legible the whole way up. Two properties agreeing on one claim — this is arriving — beat four properties each making a different one.*
### Rule 5 — Overshoot and follow-through
@@ -119,7 +119,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …a bolted airport departure board, `HF 402 · SAN FRANCISCO`, its split-flap gate cells riffling to **42**. The flap plates drop 34px and rotate from 16° on `back.out(5)`, swinging past their rest position and settling back; the housing recoils ~7px when they land, and each plate's cast shadow reaches its own peak one frame later than the plate that casts it. Transforms only — the gate number never overshoots **42**. The sequence plays twice.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule5-overshoot.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule5-overshoot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — the right's plates swing 1.51× past their travel before settling; every transform on the left has peak == final. The shadow's lag is measured at 0.033s, exactly one frame at 30fps. Note the one thing that does **not** overshoot on either side: the number itself tops out at 42 and stays there. Overshoot is a claim about mass, and a value has none — a counter that flies to 47 and falls back is reporting a number that was never true.*
### Rule 6 — Depth planes
@@ -132,7 +132,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …a render-farm corridor: CSS-3D floor and ceiling converging on a single vanishing point, a bank of server racks with blinking status LEDs, a distant rack row near the horizon, and one rack column close to the lens. `CLUSTER 04 · WEST / Every frame, in parallel.` on a camera-locked HUD panel. The camera trucks forward for the full 6s and each plane drifts at its own distance: the horizon row at a fifth of the room's rate, the room and its racks at full rate, and the near column sweeping past at six times — `blur(22px)`, close enough to cross in front of the headline. Haze the far plane slightly.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule6-depth-planes.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule6-depth-planes.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — measured travel ratios on the right are exactly 0.20× / 1.00× / 6.00×; on the left all five planes displace an identical 240px with `filter: none`. The strongest cue isn't the blur, it's the occlusion: the near column crosses in front of the headline for about a third of the shot, which is only possible if it's in the room. One foreground element does this — a second would just be clutter with a blur on it.*
### Rule 7 — Match pacing to genre
@@ -145,7 +145,7 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …a three-beat product showreel, each beat a titled panel with its own live evidence: `SEEK ANY FRAME` over a scrubbing timeline reading out frame 147, `RENDER ON LAMBDA` over six worker lanes filling their own frame ranges, `SHIP THE MP4` over a player with an encode bar. Showreel pace — 1.1 seconds per beat, cutting hard rather than dissolving, all three delivered by 3.3s, then hold the last beat on a live idle. A rail under each half tracks time consumed and time spare.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule7-pacing.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule7-pacing.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — same three ideas, same evidence, same 6 seconds. At 3.6s the left is still working through beat 2 with `SPARE 0.00`; the right has already delivered all three and banked `+0.33s`. The left is not badly animated, it is correctly animated at the wrong tempo — which is why this failure survives review so often. Pace is a genre decision you make before you touch an ease.*
### Rule 8 — Handmade imperfection stays reproducible
@@ -158,17 +158,17 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
> …a hanging paper mobile: five cut-paper shapes on fine visible wires from a wooden dowel, each with real paper grain, irregular hand-cut edges and its own layered drop shadow. They sway through the same ±12° arc, but driven by a mulberry32 PRNG seeded once at composition start and stepped on a two-frame hold quantized to the integer frame index — so the cadence is stop-motion, not a tween, and every render is byte-identical. A readout shows the current frame and how many distinct states the six seconds contain.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule8-seeded-handmade.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule8-seeded-handmade.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Left `WITHOUT`, right `WITH` — the right holds each pose for exactly two frames: 90 states across 180 frames, no irregular holds, while the left has 180 distinct ones. Rendered twice, the whole thing came back byte-identical both times. This is the rule that is easy to get wrong in the wrong direction — reaching for `Math.random()` to buy the same irregularity produces a composition that renders differently every time and can never be re-rendered or resumed.*
## The grammar, measured
The same composition built twice — identical content, identical layout; the only variable is the motion treatment. The first build commits the anti-patterns above: simultaneous identical entrances, no camera, a frozen final 2.4 seconds. The second applies the eight rules.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-before.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-before.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Every anti-pattern: tiles enter together, nothing overlaps, the last seconds are a freeze-frame.*
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-after.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*The eight rules: staggered overshoot entrances, a continuous 5% push, ambient idle, a blurred foreground plane, sparkline draw-ins as secondary motion.*
The difference is measurable, not just visible: in the final second the frozen build has bit-identical consecutive frames, while the motion-grammar build changes every single frame — corroborated by the encoder (211KB vs 2.5MB for the same content). A frozen final second is the cheap-motion tell you can test for.
@@ -200,7 +200,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> ONE continuous camera journey with a dwell-and-sweep rhythm. The whole film is a single wide world (one large scene space) that the camera dollies across […] in one unbroken move with NO hard cuts anywhere except inside the two sanctioned seam moments named below. The rhythm: the camera SWEEPS between regions, then eases to a genuine REST at each region's hero moment — a full stop of roughly 1.52.5 seconds while the main point lands […] then accelerates away. The dwell is what gives the sweep meaning: without the rest, emphasis dies mid-motion. During a dwell the WORLD keeps resolving (counters tick, labels stamp, secondary motion continues) — the camera rests, the film never freezes.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-camera.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-camera.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered: accelerating out of one region, arriving in the next, stopping to let the beat land — no cut anywhere in the span.*
This method is expensive. One continuous space is more to author than a cut, and it only pays when the piece has a through-line worth following. For a 6-second stat card, cut.
@@ -226,7 +226,7 @@ Rule 1's ambient idle is *continuous* — a slow, smooth breathing scale. Rule 8
> A paper-cutout garden scene: flowers, leaves, and a bee drifting on visible wires, like stop-motion. Seed a random offset per element at the start (same seed every render) so each leaf sways to a slightly different rhythm, but hold each position for exactly two frames before stepping to the next — discrete jumps, not a smooth tween. It should read as intentionally handmade, not glitchy.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-handmade.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-handmade.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — paper cutouts on visible wires, every position held for exactly two frames, and byte-identical across two separate renders.*
Name the seed and the hold length explicitly — "seeded" and "two-frame hold" are the two words that keep an agent from reaching for `Math.random()` and quietly breaking every re-render.
+2 -2
View File
@@ -13,7 +13,7 @@ The verified starting point: photos cut to a track, exported to a square MP4.
> /music-to-video 20-second 1080x1080 video from ./track.mp3 (pick the best 20 seconds of the track) and the 8 photos in ./shots/. Cut on the beat grid, one photo per bar, punch-in on downbeats, `whip-pan` transitions on phrase changes. End on the last photo with "SUMMER '26" in condensed caps. No TTS.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -88,7 +88,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **Rhythm (4552s).** The wire becomes a waveform: **resolve the BGM first, run `hyperframes beats` on it, and drive this region on the detected grid** — the waveform pulses and compact media cards (a lyric line, a photo card, a chart flash) snap onto the wire on real analyzed beats while the camera keeps traveling; each snap gets a tick SFX. At least six beat-hits. SANCTIONED SEAM #2: the beat-hits may hard-cut card content ON the beat — the sanctioned exception, because the camera itself never stops moving through them.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-rhythm.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-rhythm.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Motion graphics](/prompting/motion-graphics) — the shortest one yet, a single motion graphic where motion alone is the message.*
+4 -4
View File
@@ -51,7 +51,7 @@ Quote the exact copy — unquoted names and titles get paraphrased (see [anatomy
> Add a lower third at 0:03 for 5 seconds, on a track above the footage, with [`lt-clean-bar`](/catalog/blocks/lt-clean-bar). Name: "Dana Ríos". Title: "Head of Design".
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-lower-third.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-lower-third.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above over stand-in footage, unedited.*
@@ -63,13 +63,13 @@ Quote the exact copy — unquoted names and titles get paraphrased (see [anatomy
> During the intro, show an [`x-post`](/catalog/blocks/x-post) card with the quote "we shipped it in a weekend" and 12.4K likes, then slide it out before the demo.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-xpost.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-xpost.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above over stand-in scenes, unedited — the card's built-in like-tap ticks 12.4K → 12.5K.*
> /motion-graphics Transparent overlay only — a [`spotify-card`](/catalog/blocks/spotify-card) now-playing widget animating in, bottom-left. Export as transparent WebM so I can drop it over footage in my editor.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*MP4 preview of the transparent WebM over a checkerboard — the delivered file carries real VP9 alpha (verified via ALPHA_MODE + alphaextract).*
@@ -112,7 +112,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> […] as the camera arrives and BEFORE the person speaks, the framework mattes the footage — **the background peels away via background removal**, sliding off along the travel direction and leaving the cutout standing alone on the brand ground. […] A designed lower-third chip renders behind the subject.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Caption styles](/prompting/captions-catalog) — the same timed-block pattern, tuned to on-screen text instead of name cards and social replicas.*
+4 -4
View File
@@ -3,7 +3,7 @@ title: Prompt Guide
description: "How to prompt AI agents to author HyperFrames videos — setup, the two prompt shapes, and the map of this guide."
---
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*By the end of this guide, you can build this with a prompt.*
HyperFrames is built for AI agents — compositions are plain HTML, the CLI is non-interactive, and the framework ships [skills](https://github.com/vercel-labs/skills) that teach agents the patterns docs alone don't cover. This guide shows how to prompt agents effectively once skills are installed — the vocabulary that changes output, the iteration patterns that save time, and the rules that prevent breakage.
@@ -128,17 +128,17 @@ Three prompts from this guide and their unedited renders — one workflow warm s
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then everything settles into a gentle ambient idle. Use the `apple-money-count` registry block as base. No narration.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
And at the far end of the [specification dial](/prompting/specification-dial), a full visual+motion spec one-shots a broadcast-style animated globe — see [Recreating something you saw](/prompting/recreating-references) for the spec:
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*One-shot render from the distilled spec, no iteration.*
## Explore the guide
+2 -2
View File
@@ -13,7 +13,7 @@ Verified, from the [examples](/prompting/examples) page — a 45-second launch f
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -62,7 +62,7 @@ What you can already steer from the prompt, before you've learned any technique.
With no URL the workflow takes the no-capture path: no screenshots, no site palette to borrow, so name your brand colors and fonts if you have them (or the agent invents a palette). Verbatim scripts set the duration — figure roughly 130 spoken words per minute, so a 30-second video wants a 6570 word script. Saying "use it verbatim" pre-answers the workflow's keep-or-restructure question.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-launch-script.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-launch-script.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from this prompt shape with a different, longer script (78 words, fictional dev-tool "Relay"), unedited — it ran 35.5s because the words set the length.*
</Accordion>
+1 -1
View File
@@ -33,7 +33,7 @@ A distilled spec that one-shots a broadcast-style animated globe:
> CAPTION: "Across 82 Countries" — Inter 300, 34px, 0.06em tracking, white at 90%, top-center 12% from the top; left-to-right per-letter fade starting t=1.0s completing ~1.45s, then a slow 6px upward drift still easing at the final frame.
>
> No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*The one-shot render produced by this exact spec on a fresh build — no iteration.*
</Accordion>
+2 -2
View File
@@ -41,7 +41,7 @@ Transparency also only *means something* on a design that has empty space to see
- ❌ `render my full-screen product promo as a transparent WebM`
- ✅ `render the promo as MP4; export just the lower-third overlay as transparent WebM` — transparency belongs to the layer meant to sit *over* other footage, not the finished full-frame film
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*A transparent VP9 WebM overlay previewed over a checkerboard. To verify alpha from the CLI: VP9 stores it out-of-band, so look for ALPHA_MODE=1 in ffprobe (a pix_fmt-only check false-negatives) or extract it with ffmpeg alphaextract.*
@@ -124,7 +124,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> A **seeded confetti burst** fires — mulberry32, **seed 42, each piece holding position for exactly two frames before stepping** (stop-motion feel) — and the VO lands the honest punchline: identical on every render, because determinism is the whole point.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the seeded confetti, identical on every render of this composition.*
*Next: [Porting from Remotion](/prompting/remotion-migration) — bringing an existing Remotion project into everything you now know.*
+2 -2
View File
@@ -3,7 +3,7 @@ title: Rules and anti-patterns
description: "The technical rules that keep renders correct, and the prompt patterns that cause friction."
---
Almost every rule below is taught in context somewhere earlier in this guide; a few of the narrower lint rules appear only here, because they surface as an error message before they ever matter to a prompt. This page is the lookup table: skim it when you're debugging a render or hand-editing a composition, and follow a rule's link back to the chapter that explains *why* it exists. The lint-rule rows extend the same eight rules with more specific cases the linter now catches automatically.
Almost every rule below is taught in context somewhere earlier in this guide; a few of the narrower lint rules appear only here, because they surface as an error message before they ever matter to a prompt. This page is the lookup table: skim it when you're debugging a render or hand-editing a composition, and follow a rule's link back to the chapter that explains *why* it exists. The lint-rule rows extend the same seven rules with more specific cases the linter now catches automatically.
## Rules to know
@@ -23,7 +23,7 @@ The skills enforce these automatically, but if you hand-edit compositions or deb
## Lint rules to know
The linter added eight more rules that catch subtler seek-order and SVG-drawing mistakes — cases where a render can look right in the live preview and still render wrong on a cold, non-linear render worker. Phrase prompts to avoid these up front rather than debugging them after a render.
The linter added eight more rules that catch subtler seek-order and SVG-drawing mistakes — cases where a render can look right in the live preview and still render wrong on a cold, non-linear render worker. Two further hazards below carry no rule code: they surface in the render, not the linter. Phrase prompts to avoid these up front rather than debugging them after a render.
### Cold-seek visibility
+3 -3
View File
@@ -16,7 +16,7 @@ This is the one pin to state every time. For anything with genuine **depth, ligh
- ❌ `isometric cards floating in CSS 3D with perspective`
- ✅ `build the isometric scene in Three.js via the adapter, with real depth and lighting`
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*The Three.js version of the isometric-cards prompt — real shadows and lighting, one-shot.*
@@ -24,7 +24,7 @@ The engine rationale: CSS `perspective` transforms skew flat planes — they rea
Camera moves are part of the same rule. A "drone orbit", dolly, or push-in only exists where there's an actual camera:
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*A seek-driven Three.js drone orbit — the camera sweeps a continuous arc; impossible with CSS transforms.*
@@ -94,7 +94,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **Depth (5256s).** The wire spirals off the flat plane into real 3D — a **Three.js scene via the frame adapter** (never CSS fake-3D): the camera descends following the wire as it coils around a rim-lit faceted form (ink material on charcoal), mono axis readouts landing on cue, then rises back to the plane with the wire leading the way out. The coil winds up out of the wire and collapses back onto it — its ends never float cut off in mid-air — and the protagonist chip joins the 3D scene for the crossing: it rides the wire straight through the coil's loops and passes behind the form with true depth occlusion, never floating over the geometry as a flat overlay.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-depth.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-depth.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Media and audio](/prompting/media-and-audio) — precise phrasing for voiceover, music, sound, and assets, instead of motion and rendering.*
+2 -2
View File
@@ -79,7 +79,7 @@ Without stating the return explicitly, a rebuild is free to treat the early moti
>
> Frame 3 — Landing (10.015.0s), type: cta, persuasion: callback + distillation, beat: resolve + inevitability, focal: the completed motif. At 10.0s: the accent dot from frames 12 expands and fills into the full Fernwell wordmark lockup — same motif, now complete, denser and larger. At 12.0s: tagline "Fernwell. Built for flow." stamps in below it. Hold 13.515.0s.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/storyboard-mini.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/storyboard-mini.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — no audio track, exactly as asked.*
## Related
@@ -107,7 +107,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> **The clip card** — the `<div class="clip">` typed in the opening travels the whole journey: it slides onto the wire as a clip chip after being typed, rides ahead of the camera between regions (handing itself off — visible leaving one region and arriving in the next), and is the thing that finally renders at the end. It is the protagonist.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause paying off, rendered — the protagonist chip arriving at the render slot after a full minute on the wire.*
*Next: [Editing existing videos](/prompting/editing-existing-videos) — the editor verbs that turn a first render, storyboard or not, into the twenty edits after it.*
+2 -2
View File
@@ -54,7 +54,7 @@ Name the block and the seam — transitions are the one place where per-seam con
> /general-video Six-scene SaaS explainer. Use [`whip-pan`](/catalog/blocks/whip-pan) as the primary transition between related points, and one [`cinematic-zoom`](/catalog/blocks/cinematic-zoom) into the final pricing reveal. Medium energy, ~0.4s each.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-transitions.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-transitions.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — whip-pan on four seams, cinematic-zoom into the pricing reveal.*
@@ -98,7 +98,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> SANCTIONED SEAM #1: the camera pushes through an **`sdf-iris` shader transition** — the iris opens ONTO the continuation of the same wire (the wire is visible through the iris throughout; this is a lens the journey passes through, not a cut).
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Code animations](/prompting/code-blocks) — naming a block and pasting real code for walkthroughs, diffs, and terminal takes.*
+5 -5
View File
@@ -9,9 +9,9 @@ The trigger phrase is simple — call out the slots:
> Build a 6-second title card. Make the **name**, the **logo**, and the **accent color** variables; everything else stays fixed.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-default.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Default variable values.*
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-variant.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-variant.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*The same composition re-rendered with `--variables` overrides — different name, logo, and accent, zero re-prompting.*
@@ -67,13 +67,13 @@ hyperframes render --output default.mp4
hyperframes render --variables '{"ground":"#0d1420","ink":"#c8ff3d"}' --strict-variables --output reskin.mp4
```
Two identical files mean the override never landed. The usual cause is scope: `data-composition-variables` is declared **per composition file**, so variables declared inside a sub-composition pulled in with `data-composition-src` do not inherit a root-level `--variables` override — the sub-composition keeps its own defaults and a root override silently does nothing.
Two identical files mean the override never reached the property you expected. Check that the variable ID is declared, the render command uses that exact ID, and the visible property is actually bound to its CSS custom property or variable value.
This is not hypothetical. The first build of this guide's [capstone](/prompting/capstone) was authored as seven sub-composition files, each declaring its own palette variables. Every gate passed, the re-skin render succeeded, and it came out identical to the default. That is why the capstone prompt now carries a hard architecture constraint — one `index.html`, one variable scope — and why it names both renders it expects:
Render-time `--variables` overrides are global by variable ID. The compiler applies a matching override to CSS custom properties declared by the root and by sub-compositions pulled in with `data-composition-src`, while `data-variable-values` remains the per-instance way to give two mounts different values. Scoped JavaScript inside a sub-composition reads its per-instance variable table, so forward values at the mount point when that script calls `getVariables()` instead of reading CSS.
> **Variables:** expose `ground` (default `#0a0a0a`) and `ink` (default `#3CE6AC`) as composition variables on the single root file, bound via CSS custom properties everywhere (including the duotoned mural), so one `--variables` call re-skins the entire journey. It will be rendered twice: the default brand palette, and a second full render with `{"ground":"#0d1420","ink":"#c8ff3d"}`.
If you need sub-compositions *and* a template, forward the values explicitly at each mount point rather than assuming they inherit.
The [capstone](/prompting/capstone) keeps these variables on one root file for simplicity, not because templates require one file. Sub-compositions work as long as shared CSS-bound IDs are declared consistently; use mount-point values for instance-specific or JavaScript-read inputs.
## What can't be a variable
+6 -6
View File
@@ -11,7 +11,7 @@ To put your product UI inside a real phone or laptop, name [`vfx-iphone-device`]
> /product-launch-video 15-second 1920x1080 video. Our dashboard UI lives on the screen of a real iPhone 15 Pro Max that turntables slowly under product-review lighting, then a MacBook Pro slides in beside it showing the same UI wider. Use the `vfx-iphone-device` registry block. No narration.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-device-mockup.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-device-mockup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above (the block's demo UI on screen), unedited.*
@@ -36,7 +36,7 @@ The four `liquid-glass-*` panel blocks share the aurora-shader stage, so they co
> /motion-graphics 8-second 1920x1080 video. Frosted glass notification cards drift in and stack over an aurora shader background, each reading a fake alert ("Build passed", "Deploy live", "0 incidents"). Real translucency — the aurora must be visible through each card. Smoke the glass enough to keep white text above 3:1 against the brightest part of the aurora. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/glass-notify.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/glass-notify.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — CSS `backdrop-filter` glass over a Three.js aurora.*
<Warning>
@@ -63,7 +63,7 @@ The `vfx-*` blocks are single cinematic beats — spend them on a transition or
> /motion-graphics 8-second 1920x1080 video. Beat 1 (0-4s): a landing-page hero holds under directional light. Beat 2 (4-6s): the whole page shatters into glass fragments that scatter. Beat 3 (6-8s): bold white text slams in on black. Use the `vfx-shatter` registry block; the final beat reads "HTML IS VIDEO". No narration, no image or media files.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/vfx-shatter.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/vfx-shatter.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited.*
@@ -88,7 +88,7 @@ These are the ambient layer of the [motion grammar](/prompting/motion): grain an
> /motion-graphics 6-second 1920x1080 video. A wordmark logo — "HYPERFRAMES" in platinum on near-black — settles center-frame, then holds — but keep it alive with a film grain overlay and a slow 3% push-in, plus one shimmer sweep across the wordmark at 4s. Use the `grain-overlay`, `parallax-zoom`, and `shimmer-sweep` registry components. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/logo-polish.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/logo-polish.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the prompt above, unedited — the "hold" stays alive on grain, a 3% push, and one shimmer pass.*
@@ -100,7 +100,7 @@ These are the ambient layer of the [motion grammar](/prompting/motion): grain an
The distinction that trips people up: the **HTML-in-Canvas blocks are not CSS**. The device mockups, liquid-glass stages, and `vfx-*` blocks render live DOM into WebGL textures via the experimental `drawElementImage` API — which needs a Chrome flag. The [HTML-in-Canvas guide](/guides/html-in-canvas) documents the real behavior:
- **Rendering enables the flag automatically** (`--enable-features=CanvasDrawElement`), including inside Docker — so a video render of these blocks works with no setup.
- **Rendering enables CanvasDrawElement automatically** (`--enable-features=CanvasDrawElement`), including inside Docker. That is enough for CanvasDrawElement-only blocks. Liquid-glass blocks that combine it with WebGPU still need a compatible browser such as Brave or Chrome Canary configured through `PRODUCER_HEADLESS_SHELL_PATH`; the bundled headless shell cannot run that combination.
- **Live preview in the Studio needs the flag turned on manually** (`chrome://flags/#canvas-draw-element` → *Enabled* → restart). Without it, these blocks fall back rather than showing the effect in preview.
- The blocks **feature-detect and degrade gracefully**, so a browser without the flag won't crash — it just won't show the WebGL treatment.
@@ -125,7 +125,7 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
> Inside: frosted-glass inspector panels (real translucency — blur over what's behind; the product's Studio design language) hover above the wire carrying live values (`ease: power3.out`, a color token, an fps readout) […] Glass surfaces use the file's `--glass-*` tokens with real backdrop blur.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*That clause, rendered — the region cut from the finished film.*
*Next: [Runtimes and 3D](/prompting/runtimes-and-3d) — picking GSAP, Three.js, or Lottie by what the moment actually needs, including the real depth these effects render on.*
+3 -3
View File
@@ -7,7 +7,7 @@ This is the dial's third setting, [full visual spec](/prompting/specification-di
> 8-second 1920x1080 title card. Scene, back to front: #0a0e2a night sky with faint grain; an orange radial glow (#ff6a2b core ~150px, falling off to transparent by ~430px) igniting at the mountain peak's right shoulder from 2s, positioned so its upper falloff reaches the wordmark's baseline; over it a huge concentric ring system (5 rings, 1px strokes at 8% white opacity, innermost ring glowing #4a5fd9) centered 40% from the top; a low-poly mountain (6-8 dark navy facets, #141a3d#1e2650) filling the lower third with its apex left of center, a white road S-curving up its face with a soft glow; thin horizontal cloud streaks (white, 6% opacity) drifting right at two heights; a man's silhouette, pure black, ~90px tall, bottom-right, fading in at 2.5s. At 3.5s "SHOWREEL" — thin geometric sans, ~140px, 0.35em tracking, white at 90% — fades in per letter across the ring center, the glow bleeding up through the letterforms above the peak. Slow 4% push-in across the full 8s. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-showreel.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-showreel.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the spec above, unedited.*
<Note>
@@ -33,12 +33,12 @@ The same density applied to a product-UI piece and a typographic piece — both
> 6-second 1920x1080. A frosted-glass command palette (640x84px, 20px radius, rgba(255,255,255,0.08) fill, 1px rgba(255,255,255,0.25) border, heavy backdrop blur) centered on a #0b0f1a field with two soft accent glows drifting slowly — #5b6cff upper-left, #22d3a5 lower-right, ~400px, 20% opacity. At 0.4s the palette scales in 0.96→1 settling with back.out(1.2). At 0.8s a grey placeholder "Search commands…" types on; at 2.2s it fades out over 0.2s and the query "render 4k" types in white. At 2.8s three result rows (56px tall, 12px gaps: icon square, label, shortcut chip) cascade in as a detached list below the fixed bar, staggered 0.12s, each rising 12px with back.out(1.4). At 4.2s a 10%-opacity #5b6cff fill sweeps left to right across the first row and its shortcut chip pulses once. Rows and glows keep a barely-visible drift to the end. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-command-palette.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-command-palette.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the spec above, unedited.*
> 7-second 1920x1080. Off-black #101014 field with fine static film grain at 4%. The word "PRECISION" in ~220px heavy condensed caps (a heavy system face condensed with scaleX 0.82), white, 0.02em tracking, centered: its letters assemble from alternating top/bottom 40px offsets with power3.out and a 0.05s stagger, starting 0.3s. At 1.8s a 2px hairline rule draws left-to-right beneath the word, 60% of its width, centered. At 2.4s a 40px tabular-mono counter fades in below and ticks 99.999 → 00.001 mm over 2.2s with expo.out deceleration. At 5.2s the whole lockup eases to 1.03 scale over 0.5s while the word cools from white to #d8d8de, then settles into a slow ±1% breathing idle to the end. No audio.
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-precision-type.mp4" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-precision-type.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
*Rendered from the spec above, unedited.*
*Next: [Verified example prompts](/prompting/examples) — the level's gallery, read with the vocabulary you now have.*
+5 -5
View File
@@ -23,8 +23,8 @@ Describe how motion should *feel* and the agent picks the matching GSAP ease:
Each word, rendered — the same move, only the ease changes:
<table><tbody>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power2-out.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>smooth · power2.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power4-out.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>snappy · power4.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-back-out.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>bouncy · back.out</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-elastic-out.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>springy · elastic.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-expo-out.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>dramatic · expo.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-sine-inout.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>dreamy · sine.inOut</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power2-out.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>smooth · power2.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power4-out.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>snappy · power4.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-back-out.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>bouncy · back.out</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-elastic-out.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>springy · elastic.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-expo-out.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>dramatic · expo.out</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-sine-inout.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>dreamy · sine.inOut</div></td></tr>
</tbody></table>
@@ -45,8 +45,8 @@ Compositions have no physical camera, but camera words translate directly into s
The same scene under each camera word:
<table><tbody>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-push-in.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>slow push-in</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pull-back.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>pull back</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pan.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>pan across</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-crane.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>crane down</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-whip.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>whip to</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-parallax.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>parallax</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>drone orbit (Three.js)</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-push-in.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>slow push-in</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pull-back.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>pull back</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pan.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>pan across</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-crane.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>crane down</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-whip.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>whip to</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-parallax.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>parallax</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>drone orbit (Three.js)</div></td></tr>
</tbody></table>
@@ -162,7 +162,7 @@ Hand-drawn emphasis effects for text:
The five modes on the same sentence:
<table><tbody>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-highlight.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>highlight</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-circle.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>circle</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-burst.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>burst</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-scribble.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>scribble</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-sketchout.mp4" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>sketchout</div></td></tr>
<tr><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-highlight.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>highlight</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-circle.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>circle</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-burst.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>burst</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-scribble.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>scribble</div></td><td style={{ padding: "6px", border: "none" }}><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-sketchout.mp4#t=0.1" style={{ width: "100%", borderRadius: "0.4rem" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7 }}>sketchout</div></td></tr>
</tbody></table>
## Text-to-speech voices
+1 -1
View File
@@ -63,7 +63,7 @@ Copy any of these into your agent to get started.
</Card>
</CardGroup>
The agent handles scaffolding, animation, and rendering. See the [prompting guide](/guides/prompting) for more patterns, or the [pipeline guide](/guides/pipeline) for the 7-step structure (DESIGN, SCRIPT, STORYBOARD, …) that AI agents follow for multi-beat videos.
The agent handles scaffolding, animation, and rendering. See the [prompting guide](/prompting/overview) for more patterns, or the [pipeline guide](/guides/pipeline) for the 7-step structure (DESIGN, SCRIPT, STORYBOARD, …) that AI agents follow for multi-beat videos.
<Tip>
Skills encode HyperFrames-specific patterns — like required `class="clip"` on timed elements, GSAP timeline registration, adapter registries such as `window.__hfLottie`, and `data-*` attribute semantics — that are not in generic web docs. Using skills produces correct compositions from the start.
+1 -1
View File
@@ -960,7 +960,7 @@ export default defineCommand({
console.log(
` ${c.dim('"Using /hyperframes, create a 15-second intro about [your topic]"')}`,
);
console.log(` ${c.dim("More patterns: hyperframes.heygen.com/guides/prompting")}`);
console.log(` ${c.dim("More patterns: hyperframes.heygen.com/prompting/overview")}`);
console.log();
console.log(` ${c.accent("4.")} Preview in the browser:`);
console.log(` ${c.accent(`cd ${name}`)} && ${c.accent("npm run dev")}`);
@@ -54,7 +54,7 @@ Animate any custom property. Works for color, length, number — anything CSS wi
- `svgOrigin` sets transform origin in the SVG's global coordinate space (not the element's local box). **Do not** combine `svgOrigin` with `transformOrigin` on the same element — pick one.
- Animate SVG transform attributes via the same alias names (`x`, `y`, `rotation`) — GSAP handles the SVG-specific quirks.
- **Runtime-created SVG (`createElementNS`) has no reliable center pivot.** GSAP can't resolve `transformOrigin`/`svgOrigin` to the geometric center of an element built at runtime, so `scale`/`rotation` pivot on the SVG's `(0,0)` origin instead of the shape's middle. Fix: draw the animated geometry centered at local `(0,0)` and place it with a wrapping `<g transform="translate(x,y)">` — the group positions it, the tween scales/rotates it about its own center.
- **Resolve SVG geometry before building center-based transforms.** `createElementNS` is supported, but a detached, hidden, or zero-size element may not expose usable geometry when GSAP resolves a percentage `transformOrigin`. Attach and size the SVG before constructing the timeline, use an explicit `svgOrigin` when you know the canvas coordinates, or draw animated geometry around local `(0,0)` inside a positioning `<g>` for a center pivot that does not depend on a measured bounding box.
## Performance Rules