← back to Rentv Promos
RENTV: 4 HyperFrames promo videos (brand/deals/review/daily), cloned-voice narration
86470bbe470caa4c20965d70f317b82cb6aca686 · 2026-07-22 07:12:07 -0700 · Steve Abrams
Files touched
A .gitignoreA videos/brand/.media/narration.mp3A videos/brand/AGENTS.mdA videos/brand/CLAUDE.mdA videos/brand/hyperframes.jsonA videos/brand/index.htmlA videos/brand/meta.jsonA videos/brand/package.jsonA videos/daily/.media/narration.mp3A videos/daily/AGENTS.mdA videos/daily/CLAUDE.mdA videos/daily/hyperframes.jsonA videos/daily/index.htmlA videos/daily/meta.jsonA videos/daily/package.jsonA videos/deals/.media/narration.mp3A videos/deals/AGENTS.mdA videos/deals/CLAUDE.mdA videos/deals/hyperframes.jsonA videos/deals/index.htmlA videos/deals/meta.jsonA videos/deals/package.jsonA videos/review/.media/narration.mp3A videos/review/AGENTS.mdA videos/review/CLAUDE.mdA videos/review/hyperframes.jsonA videos/review/index.htmlA videos/review/meta.jsonA videos/review/package.json
Diff
commit 86470bbe470caa4c20965d70f317b82cb6aca686
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 22 07:12:07 2026 -0700
RENTV: 4 HyperFrames promo videos (brand/deals/review/daily), cloned-voice narration
---
.gitignore | 11 ++++
videos/brand/.media/narration.mp3 | Bin 0 -> 231593 bytes
videos/brand/AGENTS.md | 93 ++++++++++++++++++++++++++++++++
videos/brand/CLAUDE.md | 93 ++++++++++++++++++++++++++++++++
videos/brand/hyperframes.json | 12 +++++
videos/brand/index.html | 99 ++++++++++++++++++++++++++++++++++
videos/brand/meta.json | 5 ++
videos/brand/package.json | 11 ++++
videos/daily/.media/narration.mp3 | Bin 0 -> 188125 bytes
videos/daily/AGENTS.md | 93 ++++++++++++++++++++++++++++++++
videos/daily/CLAUDE.md | 93 ++++++++++++++++++++++++++++++++
videos/daily/hyperframes.json | 12 +++++
videos/daily/index.html | 79 +++++++++++++++++++++++++++
videos/daily/meta.json | 5 ++
videos/daily/package.json | 11 ++++
videos/deals/.media/narration.mp3 | Bin 0 -> 295123 bytes
videos/deals/AGENTS.md | 93 ++++++++++++++++++++++++++++++++
videos/deals/CLAUDE.md | 93 ++++++++++++++++++++++++++++++++
videos/deals/hyperframes.json | 12 +++++
videos/deals/index.html | 107 +++++++++++++++++++++++++++++++++++++
videos/deals/meta.json | 5 ++
videos/deals/package.json | 11 ++++
videos/review/.media/narration.mp3 | Bin 0 -> 278822 bytes
videos/review/AGENTS.md | 93 ++++++++++++++++++++++++++++++++
videos/review/CLAUDE.md | 93 ++++++++++++++++++++++++++++++++
videos/review/hyperframes.json | 12 +++++
videos/review/index.html | 82 ++++++++++++++++++++++++++++
videos/review/meta.json | 5 ++
videos/review/package.json | 11 ++++
29 files changed, 1234 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e591cb0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
+**/renders/
+**/.media/*.wav
+**/.cache/
diff --git a/videos/brand/.media/narration.mp3 b/videos/brand/.media/narration.mp3
new file mode 100644
index 0000000..0a49dda
Binary files /dev/null and b/videos/brand/.media/narration.mp3 differ
diff --git a/videos/brand/AGENTS.md b/videos/brand/AGENTS.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/brand/AGENTS.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/brand/CLAUDE.md b/videos/brand/CLAUDE.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/brand/CLAUDE.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/brand/hyperframes.json b/videos/brand/hyperframes.json
new file mode 100644
index 0000000..dc9ec2e
--- /dev/null
+++ b/videos/brand/hyperframes.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://hyperframes.heygen.com/schema/hyperframes.json",
+ "registry": "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry",
+ "paths": {
+ "blocks": "compositions",
+ "components": "compositions/components",
+ "assets": "assets"
+ },
+ "media": {
+ "autoProxy": true
+ }
+}
diff --git a/videos/brand/index.html b/videos/brand/index.html
new file mode 100644
index 0000000..8939556
--- /dev/null
+++ b/videos/brand/index.html
@@ -0,0 +1,99 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=1920, height=1080" />
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
+ <style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ html, body { width: 1920px; height: 1080px; overflow: hidden; background: #0a0e14; }
+ body { font-family: "Georgia", "Times New Roman", serif; color: #f4f6f8; }
+ .sans { font-family: "Helvetica Neue", Arial, sans-serif; }
+ #root { position: relative; width: 1920px; height: 1080px; overflow: hidden;
+ background: radial-gradient(1400px 900px at 60% 30%, #16202e 0%, #0a0e14 70%); }
+ .scene { position: absolute; inset: 0; display: flex; flex-direction: column;
+ align-items: center; justify-content: center; opacity: 0; }
+ .red { color: #c8102e; }
+ .wordmark { font-weight: 700; letter-spacing: -2px; }
+ .kicker { letter-spacing: 8px; text-transform: uppercase; font-size: 26px; color: #8fa3b8; }
+ .headline { font-size: 96px; line-height: 1.04; text-align: center; max-width: 1500px; font-weight: 700; }
+ #ticker { position: absolute; left: 0; right: 0; bottom: 90px; display: flex; gap: 70px;
+ justify-content: center; }
+ .stat { text-align: center; }
+ .stat .v { font-size: 60px; font-weight: 700; }
+ .stat .l { font-size: 22px; letter-spacing: 3px; color: #8fa3b8; text-transform: uppercase; }
+ .rule { width: 0; height: 3px; background: #c8102e; margin: 26px 0; }
+ .sect { display: flex; gap: 40px; margin-top: 30px; flex-wrap: wrap; justify-content: center; max-width: 1500px; }
+ .sect span { font-family: "Helvetica Neue", Arial, sans-serif; font-size: 30px; letter-spacing: 4px;
+ text-transform: uppercase; color: #b9c6d4; opacity: 0; }
+ </style>
+ </head>
+ <body>
+ <div id="root" data-composition-id="main" data-start="0" data-duration="14.4" data-width="1920" data-height="1080">
+
+ <div id="s1" class="scene clip" data-start="0" data-duration="4" data-track-index="1">
+ <div class="wordmark" style="font-size:180px">REN<span class="red">TV</span><span style="font-size:150px">.com</span></div>
+ <div class="rule" id="s1rule"></div>
+ <div class="kicker sans" id="s1est">Commercial Real Estate · Since 1998</div>
+ </div>
+
+ <div id="s2" class="scene clip" data-start="4" data-duration="4" data-track-index="1">
+ <div class="kicker sans" style="margin-bottom:34px">The Western U.S. Authority</div>
+ <div class="headline">The name commercial real estate <span class="red">trusts.</span></div>
+ </div>
+
+ <div id="s3" class="scene clip" data-start="8" data-duration="3.4" data-track-index="1">
+ <div class="headline" style="font-size:78px">From Los Angeles<br/>to the Mountain West</div>
+ <div class="sect sans">
+ <span>Financing</span><span>Leases</span><span>Development</span><span>Retail</span><span>Multifamily</span><span>Sales</span>
+ </div>
+ </div>
+
+ <div id="s4" class="scene clip" data-start="11.4" data-duration="3" data-track-index="1">
+ <div class="wordmark" style="font-size:150px">REN<span class="red">TV</span><span style="font-size:120px">.com</span></div>
+ <div class="rule" id="s4rule" style="width:220px"></div>
+ <div class="kicker sans" style="letter-spacing:12px; color:#f4f6f8">THE REGIONAL AUTHORITY</div>
+ </div>
+
+ <div id="ticker" class="sans clip" data-start="4" data-duration="7" data-track-index="2">
+ <div id="tickerInner" style="display:flex; gap:70px; justify-content:center; width:100%">
+ <div class="stat"><div class="v">23.1%</div><div class="l">LA Office Vac</div></div>
+ <div class="stat"><div class="v red">5.2%</div><div class="l">IE Industrial Cap</div></div>
+ <div class="stat"><div class="v">$124M</div><div class="l">Latest Deal</div></div>
+ </div>
+ </div>
+
+ <audio id="vo" src=".media/narration.wav" data-start="0" data-duration="14.4" data-track-index="10" data-volume="1"></audio>
+ </div>
+
+ <script>
+ window.__timelines = window.__timelines || {};
+ const tl = gsap.timeline({ paused: true });
+
+ tl.fromTo("#s1", {opacity:0}, {opacity:1, duration:0.6}, 0.1)
+ .from("#s1 .wordmark", {scale:0.86, y:20, filter:"blur(8px)", duration:1.0, ease:"power3.out"}, 0.2)
+ .to("#s1rule", {width:300, duration:0.8, ease:"power2.out"}, 0.9)
+ .from("#s1est", {opacity:0, y:14, duration:0.7}, 1.2)
+ .to("#s1", {opacity:0, duration:0.5}, 3.6);
+
+ tl.fromTo("#s2", {opacity:0}, {opacity:1, duration:0.5}, 4.1)
+ .from("#s2 .headline", {opacity:0, y:40, duration:0.9, ease:"power3.out"}, 4.2)
+ .fromTo("#tickerInner", {opacity:0}, {opacity:1, duration:0.6}, 4.6)
+ .from("#ticker .stat", {opacity:0, y:24, stagger:0.15, duration:0.6}, 4.8)
+ .to("#s2", {opacity:0, duration:0.5}, 7.6);
+
+ tl.fromTo("#s3", {opacity:0}, {opacity:1, duration:0.5}, 8.1)
+ .from("#s3 .headline", {opacity:0, y:36, duration:0.8, ease:"power3.out"}, 8.2)
+ .to("#s3 .sect span", {opacity:1, stagger:0.12, duration:0.4}, 8.9)
+ .to("#s3", {opacity:0, duration:0.5}, 11.0)
+ .to("#tickerInner", {opacity:0, duration:0.5}, 10.9)
+ .set("#tickerInner", {opacity:0}, 11.4);
+
+ tl.fromTo("#s4", {opacity:0}, {opacity:1, duration:0.6}, 11.5)
+ .from("#s4 .wordmark", {scale:0.9, opacity:0, duration:0.9, ease:"power3.out"}, 11.6)
+ .from("#s4 .kicker", {opacity:0, y:12, duration:0.9}, 12.2);
+
+ window.__timelines["main"] = tl;
+ </script>
+ </body>
+</html>
diff --git a/videos/brand/meta.json b/videos/brand/meta.json
new file mode 100644
index 0000000..20379e8
--- /dev/null
+++ b/videos/brand/meta.json
@@ -0,0 +1,5 @@
+{
+ "id": "brand",
+ "name": "brand",
+ "createdAt": "2026-07-22T13:58:19.313Z"
+}
\ No newline at end of file
diff --git a/videos/brand/package.json b/videos/brand/package.json
new file mode 100644
index 0000000..ee4d750
--- /dev/null
+++ b/videos/brand/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "brand",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "npx --yes hyperframes@0.7.68 preview",
+ "check": "npx --yes hyperframes@0.7.68 check",
+ "render": "npx --yes hyperframes@0.7.68 render",
+ "publish": "npx --yes hyperframes@0.7.68 publish"
+ }
+}
diff --git a/videos/daily/.media/narration.mp3 b/videos/daily/.media/narration.mp3
new file mode 100644
index 0000000..f02dc09
Binary files /dev/null and b/videos/daily/.media/narration.mp3 differ
diff --git a/videos/daily/AGENTS.md b/videos/daily/AGENTS.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/daily/AGENTS.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/daily/CLAUDE.md b/videos/daily/CLAUDE.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/daily/CLAUDE.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/daily/hyperframes.json b/videos/daily/hyperframes.json
new file mode 100644
index 0000000..dc9ec2e
--- /dev/null
+++ b/videos/daily/hyperframes.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://hyperframes.heygen.com/schema/hyperframes.json",
+ "registry": "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry",
+ "paths": {
+ "blocks": "compositions",
+ "components": "compositions/components",
+ "assets": "assets"
+ },
+ "media": {
+ "autoProxy": true
+ }
+}
diff --git a/videos/daily/index.html b/videos/daily/index.html
new file mode 100644
index 0000000..dc6d793
--- /dev/null
+++ b/videos/daily/index.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=1920, height=1080" />
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
+ <style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ html, body { width: 1920px; height: 1080px; overflow: hidden; background: #0a0e14; }
+ body { font-family: "Georgia", "Times New Roman", serif; color: #f4f6f8; }
+ .sans { font-family: "Helvetica Neue", Arial, sans-serif; }
+ #root { position: relative; width: 1920px; height: 1080px; overflow: hidden;
+ background: radial-gradient(1400px 900px at 50% 35%, #16202e 0%, #0a0e14 72%); }
+ .scene { position: absolute; inset: 0; display: flex; flex-direction: column;
+ align-items: center; justify-content: center; opacity: 0; }
+ .red { color: #c8102e; }
+ .kicker { letter-spacing: 8px; text-transform: uppercase; font-size: 26px; color: #8fa3b8; }
+ .headline { font-size: 88px; line-height: 1.06; text-align: center; max-width: 1500px; font-weight: 700; }
+ .daily { font-size: 150px; font-weight:700; letter-spacing:-3px; }
+ /* email signup mock */
+ .signup { display:flex; margin-top:44px; border:2px solid #2b3a4d; border-radius:8px; overflow:hidden; }
+ .signup .in { font-family:"Helvetica Neue",Arial,sans-serif; font-size:34px; color:#8fa3b8;
+ padding:24px 34px; background:#0e1622; width:620px; text-align:left; }
+ .signup .btn { font-family:"Helvetica Neue",Arial,sans-serif; font-size:30px; font-weight:700; color:#fff;
+ background:#c8102e; padding:24px 44px; letter-spacing:2px; text-transform:uppercase; display:flex; align-items:center; }
+ .free { display:inline-block; font-family:"Helvetica Neue",Arial,sans-serif; font-size:24px; letter-spacing:4px;
+ text-transform:uppercase; color:#c8102e; border:1px solid #c8102e; padding:8px 20px; margin-top:30px; }
+ .wordmark { font-weight:700; letter-spacing:-2px; }
+ </style>
+ </head>
+ <body>
+ <div id="root" data-composition-id="main" data-start="0" data-duration="11.7" data-width="1920" data-height="1080">
+
+ <div id="s1" class="scene clip" data-start="0" data-duration="3.6" data-track-index="1">
+ <div class="headline">The market moves before<br/>your <span class="red">first coffee.</span></div>
+ </div>
+
+ <div id="s2" class="scene clip" data-start="3.6" data-duration="4.4" data-track-index="1">
+ <div class="kicker sans" style="margin-bottom:24px">Every Western CRE deal, each morning</div>
+ <div class="daily">REN<span class="red">TV</span> Daily</div>
+ <div class="signup">
+ <div class="in">you@company.com</div>
+ <div class="btn">Subscribe</div>
+ </div>
+ <div class="free" id="s2free">Free</div>
+ </div>
+
+ <div id="s3" class="scene clip" data-start="8" data-duration="3.7" data-track-index="1">
+ <div class="kicker sans" style="margin-bottom:26px">The deals · the numbers · the edge</div>
+ <div class="headline" style="font-size:66px">Subscribe at</div>
+ <div class="wordmark" style="font-size:130px; margin-top:16px">REN<span class="red">TV</span>.com</div>
+ </div>
+
+ <audio id="vo" src=".media/narration.wav" data-start="0" data-duration="11.7" data-track-index="10" data-volume="1"></audio>
+ </div>
+
+ <script>
+ window.__timelines = window.__timelines || {};
+ const tl = gsap.timeline({ paused: true });
+
+ tl.fromTo("#s1", {opacity:0}, {opacity:1, duration:0.6}, 0.1)
+ .from("#s1 .headline", {opacity:0, y:32, duration:0.9, ease:"power3.out"}, 0.3)
+ .to("#s1", {opacity:0, duration:0.5}, 3.2);
+
+ tl.fromTo("#s2", {opacity:0}, {opacity:1, duration:0.5}, 3.7)
+ .from("#s2 .kicker", {opacity:0, y:14, duration:0.5}, 3.9)
+ .from("#s2 .daily", {opacity:0, y:24, duration:0.8, ease:"power3.out"}, 4.2)
+ .from("#s2 .signup", {opacity:0, y:26, duration:0.7}, 4.8)
+ .from("#s2free", {scale:0.7, opacity:0, duration:0.5, ease:"back.out(2)"}, 5.5)
+ .to("#s2", {opacity:0, duration:0.5}, 7.6);
+
+ tl.fromTo("#s3", {opacity:0}, {opacity:1, duration:0.5}, 8.1)
+ .from("#s3 .kicker", {opacity:0, y:14, duration:0.6}, 8.3)
+ .from("#s3 .wordmark", {opacity:0, scale:0.9, duration:0.9, ease:"power3.out"}, 8.7);
+
+ window.__timelines["main"] = tl;
+ </script>
+ </body>
+</html>
diff --git a/videos/daily/meta.json b/videos/daily/meta.json
new file mode 100644
index 0000000..b4731a2
--- /dev/null
+++ b/videos/daily/meta.json
@@ -0,0 +1,5 @@
+{
+ "id": "daily",
+ "name": "daily",
+ "createdAt": "2026-07-22T14:07:35.330Z"
+}
\ No newline at end of file
diff --git a/videos/daily/package.json b/videos/daily/package.json
new file mode 100644
index 0000000..9a4e409
--- /dev/null
+++ b/videos/daily/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "daily",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "npx --yes hyperframes@0.7.68 preview",
+ "check": "npx --yes hyperframes@0.7.68 check",
+ "render": "npx --yes hyperframes@0.7.68 render",
+ "publish": "npx --yes hyperframes@0.7.68 publish"
+ }
+}
diff --git a/videos/deals/.media/narration.mp3 b/videos/deals/.media/narration.mp3
new file mode 100644
index 0000000..3e8b953
Binary files /dev/null and b/videos/deals/.media/narration.mp3 differ
diff --git a/videos/deals/AGENTS.md b/videos/deals/AGENTS.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/deals/AGENTS.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/deals/CLAUDE.md b/videos/deals/CLAUDE.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/deals/CLAUDE.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/deals/hyperframes.json b/videos/deals/hyperframes.json
new file mode 100644
index 0000000..dc9ec2e
--- /dev/null
+++ b/videos/deals/hyperframes.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://hyperframes.heygen.com/schema/hyperframes.json",
+ "registry": "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry",
+ "paths": {
+ "blocks": "compositions",
+ "components": "compositions/components",
+ "assets": "assets"
+ },
+ "media": {
+ "autoProxy": true
+ }
+}
diff --git a/videos/deals/index.html b/videos/deals/index.html
new file mode 100644
index 0000000..f76a73b
--- /dev/null
+++ b/videos/deals/index.html
@@ -0,0 +1,107 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=1920, height=1080" />
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
+ <style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ html, body { width: 1920px; height: 1080px; overflow: hidden; background: #0a0e14; }
+ body { font-family: "Georgia", "Times New Roman", serif; color: #f4f6f8; }
+ .sans { font-family: "Helvetica Neue", Arial, sans-serif; }
+ #root { position: relative; width: 1920px; height: 1080px; overflow: hidden;
+ background: radial-gradient(1400px 900px at 40% 30%, #16202e 0%, #0a0e14 70%); }
+ .scene { position: absolute; inset: 0; display: flex; flex-direction: column;
+ align-items: center; justify-content: center; opacity: 0; }
+ .red { color: #c8102e; }
+ .kicker { letter-spacing: 8px; text-transform: uppercase; font-size: 26px; color: #8fa3b8; }
+ .headline { font-size: 92px; line-height: 1.05; text-align: center; max-width: 1500px; font-weight: 700; }
+ .breaking { font-family: "Helvetica Neue", Arial, sans-serif; background:#c8102e; color:#fff;
+ padding:10px 26px; letter-spacing:5px; text-transform:uppercase; font-size:24px; font-weight:700; }
+ /* deal card */
+ .amt { font-size: 200px; font-weight: 700; letter-spacing:-4px; line-height:1; }
+ .buyer { font-size: 58px; font-weight:700; margin-top:14px; }
+ .loc { font-family:"Helvetica Neue",Arial,sans-serif; letter-spacing:5px; text-transform:uppercase;
+ font-size:28px; color:#8fa3b8; margin-top:16px; }
+ .cat { display:inline-block; font-family:"Helvetica Neue",Arial,sans-serif; font-size:20px; letter-spacing:3px;
+ text-transform:uppercase; color:#c8102e; border:1px solid #c8102e; padding:6px 16px; margin-top:22px; }
+ .sect span { font-family:"Helvetica Neue",Arial,sans-serif; font-size:34px; letter-spacing:5px;
+ text-transform:uppercase; color:#b9c6d4; opacity:0; margin:0 22px; }
+ .wordmark { font-weight:700; letter-spacing:-2px; }
+ </style>
+ </head>
+ <body>
+ <div id="root" data-composition-id="main" data-start="0" data-duration="18.4" data-width="1920" data-height="1080">
+
+ <div id="s1" class="scene clip" data-start="0" data-duration="4" data-track-index="1">
+ <div class="breaking" id="s1b">Breaking</div>
+ <div class="headline" style="margin-top:34px">The West's biggest deals<br/><span class="red">break here first.</span></div>
+ </div>
+
+ <div id="s2" class="scene clip" data-start="4" data-duration="3.2" data-track-index="1">
+ <div class="amt red">$124M</div>
+ <div class="buyer">Camden Property Trust</div>
+ <div class="loc">Gilbert, AZ</div>
+ <div class="cat">Multifamily</div>
+ </div>
+
+ <div id="s3" class="scene clip" data-start="7.2" data-duration="2.6" data-track-index="1">
+ <div class="amt">$30M</div>
+ <div class="buyer">CentrePoint Properties</div>
+ <div class="loc">Colorado</div>
+ <div class="cat">Retail</div>
+ </div>
+
+ <div id="s4" class="scene clip" data-start="9.8" data-duration="2.9" data-track-index="1">
+ <div class="amt red">$132M</div>
+ <div class="buyer">Eagle Partners & Vistria</div>
+ <div class="loc">Garden Grove, CA</div>
+ <div class="cat">Mixed-Income</div>
+ </div>
+
+ <div id="s5" class="scene clip" data-start="12.7" data-duration="2.6" data-track-index="1">
+ <div class="sect" style="text-align:center">
+ <span>Financing</span><span>Leases</span><span>Development</span><span>Sales</span>
+ </div>
+ </div>
+
+ <div id="s6" class="scene clip" data-start="15.3" data-duration="3.1" data-track-index="1">
+ <div class="headline" style="font-size:66px">If it closed out West,<br/>it's on</div>
+ <div class="wordmark" style="font-size:120px; margin-top:20px">REN<span class="red">TV</span>.com</div>
+ </div>
+
+ <audio id="vo" src=".media/narration.wav" data-start="0" data-duration="18.4" data-track-index="10" data-volume="1"></audio>
+ </div>
+
+ <script>
+ window.__timelines = window.__timelines || {};
+ const tl = gsap.timeline({ paused: true });
+ const card = (id, t) => {
+ tl.fromTo("#"+id, {opacity:0}, {opacity:1, duration:0.45}, t)
+ .from("#"+id+" .amt", {scale:0.8, y:20, duration:0.7, ease:"power3.out"}, t+0.05)
+ .from("#"+id+" .buyer", {opacity:0, y:18, duration:0.5}, t+0.35)
+ .from("#"+id+" .loc", {opacity:0, y:12, duration:0.5}, t+0.5)
+ .from("#"+id+" .cat", {opacity:0, duration:0.5}, t+0.65);
+ };
+ // s1
+ tl.fromTo("#s1", {opacity:0}, {opacity:1, duration:0.5}, 0.1)
+ .from("#s1b", {scale:0.8, opacity:0, duration:0.5, ease:"back.out(2)"}, 0.2)
+ .from("#s1 .headline", {opacity:0, y:30, duration:0.8, ease:"power3.out"}, 0.6)
+ .to("#s1", {opacity:0, duration:0.4}, 3.7);
+ // deal cards
+ card("s2", 4.05); tl.to("#s2", {opacity:0, duration:0.35}, 6.95);
+ card("s3", 7.25); tl.to("#s3", {opacity:0, duration:0.35}, 9.55);
+ card("s4", 9.85); tl.to("#s4", {opacity:0, duration:0.35}, 12.45);
+ // s5 sections
+ tl.fromTo("#s5", {opacity:0}, {opacity:1, duration:0.4}, 12.75)
+ .to("#s5 .sect span", {opacity:1, stagger:0.18, duration:0.4}, 12.9)
+ .to("#s5", {opacity:0, duration:0.4}, 15.0);
+ // s6 signoff
+ tl.fromTo("#s6", {opacity:0}, {opacity:1, duration:0.5}, 15.4)
+ .from("#s6 .headline", {opacity:0, y:24, duration:0.7}, 15.5)
+ .from("#s6 .wordmark", {opacity:0, scale:0.9, duration:0.8, ease:"power3.out"}, 16.0);
+
+ window.__timelines["main"] = tl;
+ </script>
+ </body>
+</html>
diff --git a/videos/deals/meta.json b/videos/deals/meta.json
new file mode 100644
index 0000000..feab84f
--- /dev/null
+++ b/videos/deals/meta.json
@@ -0,0 +1,5 @@
+{
+ "id": "deals",
+ "name": "deals",
+ "createdAt": "2026-07-22T14:07:31.574Z"
+}
\ No newline at end of file
diff --git a/videos/deals/package.json b/videos/deals/package.json
new file mode 100644
index 0000000..9d02964
--- /dev/null
+++ b/videos/deals/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "deals",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "npx --yes hyperframes@0.7.68 preview",
+ "check": "npx --yes hyperframes@0.7.68 check",
+ "render": "npx --yes hyperframes@0.7.68 render",
+ "publish": "npx --yes hyperframes@0.7.68 publish"
+ }
+}
diff --git a/videos/review/.media/narration.mp3 b/videos/review/.media/narration.mp3
new file mode 100644
index 0000000..dc94c35
Binary files /dev/null and b/videos/review/.media/narration.mp3 differ
diff --git a/videos/review/AGENTS.md b/videos/review/AGENTS.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/review/AGENTS.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/review/CLAUDE.md b/videos/review/CLAUDE.md
new file mode 100644
index 0000000..a63562c
--- /dev/null
+++ b/videos/review/CLAUDE.md
@@ -0,0 +1,93 @@
+# HyperFrames Composition Project
+
+## Skills — USE THESE FIRST
+
+**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
+
+**Doing anything with HyperFrames?** Start at `/hyperframes` — it tells you what HyperFrames can do and which skill or workflow handles your intent (make a video, TTS / BGM, prep footage, author / animate, render, install blocks), confirms your brief up front (the intent layer), and routes every "make me a…" request (a video, a deck, a composition port) to the right workflow. Read it first, especially when there's no project context to orient you. The workflows it routes to:
+
+- `/product-launch-video` — any **website** URL or brief / script → a product launch / SaaS / promo video, or a site tour / showcase featuring the site's own captured visuals.
+- `/faceless-explainer` — arbitrary text (topic / article / notes), **no URL, no website capture** → 60-90s faceless explainer.
+- `/embedded-captions` — an existing talking-head video (MP4) → the same footage with captions / subtitles added (rail + embed, or pure-cinematic embed); the footage itself is untouched.
+- `/talking-head-recut` — an existing talking-head / interview / podcast video (MP4) → the same footage **packaged with designed graphic overlays** (kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, pip) synced to the transcript; the clip plays unchanged underneath. (Plain captions/subtitles → `/embedded-captions`.)
+- `/pr-to-video` — a GitHub PR (URL / `owner/repo#N` / "this PR") → 30-90s code-change explainer (changelog / feature reveal / fix / refactor).
+- `/motion-graphics` — a short (typically under 10s) design-led **motion graphic**, motion-is-the-message, no narration: kinetic type, a stat / number count-up, a chart, a logo sting, a lower-third / overlay, or an animated tweet / headline / captured-page highlight; rendered to MP4 or a transparent overlay. Longer / narrated / custom → `/general-video`.
+- `/music-to-video` — a **music track** (audio file, or video to pull audio from) → beat-synced video (lyric / slideshow / kinetic promo). Music drives pacing; user-supplied images / videos are cut onto the same beat grid.
+- `/slideshow` — a **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.
+- `/general-video` — fallback for any other video (title card, longer brand / sizzle reel, multi-scene montage, static loop, custom composition) and the home of **companion mode** — co-create with the full HyperFrames toolbox; the original hyperframes authoring flow, any length.
+
+**Porting an existing composition?** `/remotion-to-hyperframes` translates a Remotion (React) composition into HyperFrames HTML — a source migration, separate from the creation workflows above.
+
+The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-keyframes`, `/hyperframes-creative`, `/hyperframes-cli`, `/media-use`, `/hyperframes-registry`, `/figma`) and the full capability map live inside `/hyperframes` — it is the single source of truth for which skill handles which intent.
+
+> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
+
+> **Skill missing or stale?** Run `npx hyperframes skills update <name>` to install/refresh
+> the specific skill you need (the `/hyperframes` router does this automatically before
+> entering a workflow), or bare `npx hyperframes skills update` to refresh the core set plus
+> everything already installed — neither pulls the full set. Restart the agent session so
+> newly installed skills load.
+
+## Commands
+
+```bash
+npm run dev # start the preview server (long-running — keep it alive in background)
+npm run check # lint + runtime + layout + motion + contrast (one command)
+npm run render # render to MP4
+npm run publish # publish and get a shareable link
+npx hyperframes lint --verbose # include info-level findings
+npx hyperframes lint --json # machine-readable output for CI
+npx hyperframes docs <topic> # reference docs in terminal
+```
+
+> **`npm run dev` is a long-running server, not a one-shot command.** It blocks until stopped.
+> In Claude Code, always run it with `run_in_background: true`. Never run it as a foreground
+> command — it will time out and the server will die, breaking the browser preview.
+
+> **Pinned CLI version.** These scripts pin an exact `hyperframes@X.Y.Z` so this project re-renders identically over time. Weeks later that pin lags fixes shipped since. To move up: `npx hyperframes@latest upgrade --project . --check` (shows the delta), then `npx hyperframes@latest upgrade --project .` to rewrite the pins. Always unpinned — the pinned script re-runs the old version against itself.
+
+## Documentation
+
+**For quick reference**, use the local CLI docs command (no network required):
+
+```bash
+npx hyperframes docs <topic>
+```
+
+Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
+
+**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
+
+```
+https://hyperframes.heygen.com/llms.txt
+```
+
+## Project Structure
+
+- `index.html` — main composition (root timeline)
+- `compositions/` — sub-compositions referenced via `data-composition-src`
+- `meta.json` — project metadata (id, name)
+- `transcript.json` — whisper word-level transcript (if generated)
+
+## Linting — ALWAYS RUN AFTER CHANGES
+
+After creating or editing any `.html` composition, **always** run the full check before considering the task complete:
+
+```bash
+npm run check
+```
+
+Fix all errors before presenting the result. Warnings should be reviewed before rendering.
+
+## Key Rules
+
+1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
+2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
+3. Timelines must be paused and registered on `window.__timelines`:
+ ```js
+ window.__timelines = window.__timelines || {};
+ window.__timelines["composition-id"] = gsap.timeline({ paused: true });
+ ```
+4. Videos use `muted` with a separate `<audio>` element for the audio track
+5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
+6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
diff --git a/videos/review/hyperframes.json b/videos/review/hyperframes.json
new file mode 100644
index 0000000..dc9ec2e
--- /dev/null
+++ b/videos/review/hyperframes.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://hyperframes.heygen.com/schema/hyperframes.json",
+ "registry": "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry",
+ "paths": {
+ "blocks": "compositions",
+ "components": "compositions/components",
+ "assets": "assets"
+ },
+ "media": {
+ "autoProxy": true
+ }
+}
diff --git a/videos/review/index.html b/videos/review/index.html
new file mode 100644
index 0000000..a624b87
--- /dev/null
+++ b/videos/review/index.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=1920, height=1080" />
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
+ <style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ html, body { width: 1920px; height: 1080px; overflow: hidden; background: #0a0e14; }
+ body { font-family: "Georgia", "Times New Roman", serif; color: #f4f6f8; }
+ .sans { font-family: "Helvetica Neue", Arial, sans-serif; }
+ #root { position: relative; width: 1920px; height: 1080px; overflow: hidden;
+ background: radial-gradient(1400px 900px at 55% 40%, #16202e 0%, #0a0e14 72%); }
+ .scene { position: absolute; inset: 0; display: flex; flex-direction: column;
+ align-items: center; justify-content: center; opacity: 0; }
+ .red { color: #c8102e; }
+ .kicker { letter-spacing: 8px; text-transform: uppercase; font-size: 26px; color: #8fa3b8; }
+ .headline { font-size: 90px; line-height: 1.06; text-align: center; max-width: 1500px; font-weight: 700; }
+ .big { font-size: 220px; font-weight:700; letter-spacing:-4px; line-height:1; }
+ .play { width:150px; height:150px; border-radius:50%; background:#c8102e; display:flex;
+ align-items:center; justify-content:center; margin-bottom:34px; }
+ .play::after { content:""; border-left:52px solid #fff; border-top:32px solid transparent;
+ border-bottom:32px solid transparent; margin-left:14px; }
+ .three span { font-family:"Helvetica Neue",Arial,sans-serif; font-size:42px; letter-spacing:6px;
+ text-transform:uppercase; color:#b9c6d4; display:block; margin:14px 0; opacity:0; }
+ .wordmark { font-weight:700; letter-spacing:-2px; }
+ </style>
+ </head>
+ <body>
+ <div id="root" data-composition-id="main" data-start="0" data-duration="17.4" data-width="1920" data-height="1080">
+
+ <div id="s1" class="scene clip" data-start="0" data-duration="4.6" data-track-index="1">
+ <div class="headline">It isn't just headlines.<br/>It's the <span class="red">people</span> behind them.</div>
+ </div>
+
+ <div id="s2" class="scene clip" data-start="4.6" data-duration="4.4" data-track-index="1">
+ <div class="play" id="s2play"></div>
+ <div class="big">The <span class="red">RE</span>view</div>
+ <div class="kicker sans" style="margin-top:26px">Face to face with the dealmakers</div>
+ </div>
+
+ <div id="s3" class="scene clip" data-start="9" data-duration="4" data-track-index="1">
+ <div class="three" style="text-align:center">
+ <span>Interviews</span><span>Insight</span><span>The stories behind the numbers</span>
+ </div>
+ </div>
+
+ <div id="s4" class="scene clip" data-start="13" data-duration="4.4" data-track-index="1">
+ <div class="kicker sans" style="margin-bottom:26px">Watch The REview</div>
+ <div class="headline" style="font-size:70px">Only on</div>
+ <div class="wordmark" style="font-size:130px; margin-top:16px">REN<span class="red">TV</span>.com</div>
+ </div>
+
+ <audio id="vo" src=".media/narration.wav" data-start="0" data-duration="17.4" data-track-index="10" data-volume="1"></audio>
+ </div>
+
+ <script>
+ window.__timelines = window.__timelines || {};
+ const tl = gsap.timeline({ paused: true });
+
+ tl.fromTo("#s1", {opacity:0}, {opacity:1, duration:0.6}, 0.1)
+ .from("#s1 .headline", {opacity:0, y:34, duration:0.9, ease:"power3.out"}, 0.3)
+ .to("#s1", {opacity:0, duration:0.5}, 4.2);
+
+ tl.fromTo("#s2", {opacity:0}, {opacity:1, duration:0.5}, 4.7)
+ .from("#s2play", {scale:0.6, opacity:0, duration:0.6, ease:"back.out(2)"}, 4.8)
+ .from("#s2 .big", {opacity:0, y:26, duration:0.8, ease:"power3.out"}, 5.1)
+ .from("#s2 .kicker", {opacity:0, y:14, duration:0.6}, 5.6)
+ .to("#s2", {opacity:0, duration:0.5}, 8.6);
+
+ tl.fromTo("#s3", {opacity:0}, {opacity:1, duration:0.5}, 9.1)
+ .to("#s3 .three span", {opacity:1, stagger:0.4, duration:0.5}, 9.3)
+ .to("#s3", {opacity:0, duration:0.5}, 12.6);
+
+ tl.fromTo("#s4", {opacity:0}, {opacity:1, duration:0.5}, 13.1)
+ .from("#s4 .kicker", {opacity:0, y:14, duration:0.6}, 13.3)
+ .from("#s4 .wordmark", {opacity:0, scale:0.9, duration:0.9, ease:"power3.out"}, 13.7);
+
+ window.__timelines["main"] = tl;
+ </script>
+ </body>
+</html>
diff --git a/videos/review/meta.json b/videos/review/meta.json
new file mode 100644
index 0000000..565d64f
--- /dev/null
+++ b/videos/review/meta.json
@@ -0,0 +1,5 @@
+{
+ "id": "review",
+ "name": "review",
+ "createdAt": "2026-07-22T14:07:33.440Z"
+}
\ No newline at end of file
diff --git a/videos/review/package.json b/videos/review/package.json
new file mode 100644
index 0000000..b5f0b16
--- /dev/null
+++ b/videos/review/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "review",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "npx --yes hyperframes@0.7.68 preview",
+ "check": "npx --yes hyperframes@0.7.68 check",
+ "render": "npx --yes hyperframes@0.7.68 render",
+ "publish": "npx --yes hyperframes@0.7.68 publish"
+ }
+}
(oldest)
·
back to Rentv Promos
·
auto-save: 2026-07-22T13:44:34 (1 files) — recap-v2/ 263c1a0 →