HyperFrames — start here
HyperFrames renders video from HTML — a composition is an HTML file whose DOM declares timing with data-* attributes, whose animation runtime is seekable, and whose media playback is owned by the framework. The full authoring contract lives in /hyperframes-core; read it before writing composition HTML.
Below: a capability map (the domain skills, loaded on demand) and the intent router (pick a workflow for any "make me a…" request — usually a video, but also a navigable deck or a composition port). The split is ownership, not output type: a workflow owns an end-to-end deliverable (its own project dir, gated steps, sub-agents, final artifact); a domain skill is a capability layer a workflow pulls in mid-flight and never owns the task.
Capability map — the domain skills
Atomic capabilities you load on demand — not full workflows; they never own the end-to-end task. For "make me a…" intent, use the intent router below.
| You want to… | Skill |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ |
| Author / edit an HTML composition — the data-* contract, clips, tracks, sub-compositions, variables | /hyperframes-core |
| Animate — atomic motion, scene blueprints, transitions, runtime adapters (GSAP / Lottie / Three.js / Anime.js / CSS / WAAPI / TypeGPU) | /hyperframes-animation |
| Author seek-safe keyframes — GSAP timelines, CSS keyframes, Anime.js, WAAPI, FLIP, paths, masks, SVG morph/draw, 3D depth, plus hyperframes keyframes diagnostics | /hyperframes-keyframes |
| Creative direction — frame.md / design.md, palettes, typography, narration, beat planning, audio-reactive | /hyperframes-creative |
| Media — resolve/generate BGM, SFX, image, icon, brand logo, voice, color grade, LUT; TTS voiceover, transcription, background removal, captions; cross-project reuse | /media-use |
| CLI dev loop — init, lint, validate, inspect, preview, render, publish, doctor | /hyperframes-cli |
| Install registry blocks / components (hyperframes add) | /hyperframes-registry |
| Import Figma content — assets, tokens, components, storyboards→reconstructed motion (REST/CLI); Motion (MCP), shaders (MCP source / native export) | /figma |
Intent routing — pick a workflow
This section knows only the top-level workflows; it does not load their internal references or the domain skills above.
Before routing — confirm the input, not the spec
Routing needs to know what the video is about — its input and subject. If that's unspecified ("make a video about our thing" with no URL, product, topic, or asset), ask before entering any workflow — committing to a workflow IS the routing decision. At most two questions:
- Input — a product (URL / brief), a general website, a GitHub PR, a topic to explain, or an existing talking-head video?
Mode — if the request carries an ongoing autonomous signal ("surprise me", "decide for me", "just build it"), note it and pass it into the workflow: the whole run goes autonomous and no later step re-asks. With no signal, the workflow asks the mode as its first brief question. Default is collaborative. (/motion-graphics is autonomous by design.) Semantics: hyperframes-core → references/brief-contract.md.
Spec defaults — state, don't ask (they never change the route): aspect derives from the destination — social feed (X / LinkedIn / Instagram) → square 1:1, TikTok / Reels / Shorts → 9:16, YouTube / embed / unknown → 16:9; narration / caption language = the user's. The chosen workflow re-confirms its own specifics at its first step (field semantics: hyperframes-core → references/brief-contract.md).
Workflow cheat-sheet
| Workflow | Use it for |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /product-launch-video | Selling a product (SaaS, app, company / product site) — from a URL, brief, or script → a promo. The default for any commercial URL, even if the site is only named. |
| /website-to-video | Showing a site itself — a tour / showcase built from the site's own screenshots. For non-commercial sites (portfolio, blog, docs, personal, event), or when the user wants a tour, not a promo. |
| /faceless-explainer | Explaining a topic / concept from text — no product, no URL; every visual is LLM-invented |
| /pr-to-video | A GitHub PR / code change → changelog / feature-reveal / fix / refactor explainer |
| /embedded-captions | Adding captions / subtitles to an existing talking-head video (footage untouched) |
| /talking-head-recut | Packaging an existing talking-head video with designed graphic overlays — lower-thirds, data callouts, kinetic titles, pull-quotes |
| /motion-graphics | A short (~under 10s), unnarrated piece where the motion is the message — kinetic type, a stat / chart hit, a logo sting, an animated map, an animated tweet / headline, a standalone lower-third / overlay (MP4 or transparent alpha) |
| /music-to-video | A music track → a beat-synced video — lyric video, slideshow, or kinetic promo; the music drives pacing (optional user images / videos cut onto the beat grid) |
| /slideshow | A presentation / pitch deck / interactive deck — discrete slides, fragments, branching, hotspots; output is a navigable deck, not a rendered video |
| /general-video | Anything else — longer or multi-scene pieces, a static loop / poster, a custom composition |
| /remotion-to-hyperframes | Porting an existing Remotion (React) composition to HyperFrames (migration, not creation) |
Disambiguation (only where confusable):
- Motion-first & unnarrated (under ~10s, the motion is the message) →
/motion-graphics, regardless of input. - A URL or script — ask one thing: is the site selling a product? Yes (SaaS / app / product / company site) →
/product-launch-video— a promo, and the default for any commercial URL even if the site is only named. No, or the user just wants the site shown as-is (portfolio / blog / docs / personal / event) →/website-to-video— a tour. A GitHub PR link →/pr-to-video; a concept with no product or site →/faceless-explainer. - Existing footage — plain spoken-word subtitles →
/embedded-captions; designed overlay cards →/talking-head-recut. Neither edits the footage itself (re-timing / recolor / reframe / reorder / audio is NLE editing — out of scope). - A music track is the input (an audio file, or a video to pull audio from) with no narration →
/music-to-video— the music's beats/energy drive the pacing. (Narrated pieces stay with the input-matched workflow above;/motion-graphicsis for short unnarrated motion that isn't music-driven.) - A presentation / pitch deck / interactive deck (discrete slides, navigation, presenter mode) →
/slideshow— output is a navigable deck, not a rendered video. An explicit "slideshow" request proceeds directly; an adjacent trigger ("deck / slides / presentation / convert this page") makes/slideshowconfirm it's a slideshow before authoring, and switch to the appropriate non-slideshow workflow if not. - Length is a guide, not a gate — intent picks the workflow; go to
/general-videoonly when the piece is clearly longer than ~3 min, or is a static / loop / custom format.
After picking — workflow skills are vendored locally
<!-- LOCAL PATCH (connorads dotfiles): upstream's version of this section and "Keeping skills current" instruct agents to self-install/refresh skills at task time (`npx hyperframes skills update`, `npx skills add`), which bypasses this repo's pin-and-review vendoring; the full upstream skill set is vendored alongside this router instead, and refreshes go through the update-vendored-skills flow, which re-applies this patch. -->Every workflow and domain skill in the capability map is vendored alongside this router (../<workflow-name>/SKILL.md). Read it from there and continue. Do not run npx hyperframes skills update or npx skills add — skill refreshes here go through the dotfiles vendored-skills review flow, not runtime installs. If a referenced skill is missing, surface that to the user instead of installing it.
Workflow details
/product-launch-video
- Input: A product being marketed — (a) a product URL (crawled with headless Chrome for assets + brand tokens), (b) a script / brief that names the product's site even without a link (PLV resolves + crawls it, unless the user opts out), or (c) a script with no derivable site / "don't scrape" (no-capture mode — pick a style preset that supplies palette + design system). A supplied script can be the verbatim voice-over or restructured per scene — PLV asks.
- Output: a product launch / SaaS promo as a HyperFrames composition → MP4 (sweet spot 30–90s) — the product's value is the subject, not a walkthrough of the site. For a plain tour of the site, use
/website-to-video. - Triggers: "launch video for X", "promo for our site", "explain my SaaS in a minute", "turn my script into a 60s promo", "text-only launch video, don't scrape".
/website-to-video
- Input: A website / URL whose goal is to show the site itself, not to sell a product. Best for non-commercial sites (portfolio, blog, docs, personal, event), or when the user explicitly wants a tour of a site as-is. Captured with headless Chrome for real screenshots + brand assets. If the site is selling something and the user wants a promo, use
/product-launch-video. - Output: a site tour / showcase / social clip built from the site's own visuals → MP4.
- Triggers: "turn this website into a video", "site tour from ", "social clip from our homepage", "I just have a URL — make something".
/faceless-explainer
- Input: Arbitrary text — a topic, article, or notes — being explained, with no product being marketed and no site to capture. (Forked from
/product-launch-video; no headless Chrome.) - Output: faceless explainer → MP4, every visual LLM-invented per scene (typography / abstract / diagram / data-viz); ships the
pin-and-paperpreset. (sweet spot 30–90s). - Triggers: "faceless explainer about X", "explain how DNS works as a video", "turn this article into an explainer", "explainer from my notes".
/pr-to-video
- Input: A GitHub pull request — a PR URL, an
owner/repo#Nref, or "this PR" — read via theghCLI (not a site to scrape). - Output: code-change explainer (changelog / feature-reveal / fix / refactor) → MP4 — diff highlights, before/after, file-tree + impact scenes. ≤ (sweet spot 30–90s).
- Triggers: "make a video about this PR", "turn PR #1187 into a changelog video", "release-notes video from github.com/org/repo/pull/123".
/embedded-captions
- Input: An existing talking-head video (MP4) to caption — actual footage, not a URL or brief. Transcribed and matted locally (no API key) so the subject can occlude captions.
- Output: the same footage untouched, with a caption layer — one visual identity picked from its catalog (36, from a quiet verbatim rail to full VFX constitutions); the subject occludes the embedded captions. Any length.
- Triggers: "add captions / subtitles to this video", "captions behind the subject", "cinematic captions for my clip".
/talking-head-recut
- Input: An existing talking-head / interview / podcast video (MP4) to package with on-screen graphics — actual footage. Transcribed locally (Whisper). The clip plays in full underneath, untouched.
- Output: the same footage with timed graphic-overlay cards — kinetic titles, lower-thirds, data callouts, pull-quotes, side panels, picture-in-picture — synced to the transcript. Any length.
- Triggers: "package this video", "add graphic overlays / lower-thirds / data callouts to my talk", "turn this interview into a graphics-packaged edit".
/motion-graphics
- Input: A short, design-led motion graphic where the motion is the message — typically under ~10s, no narration. Genres: kinetic typography, a stat / number count-up, a chart hit, a logo sting, a lower-third / overlay, an animated map (regions / routes / zoom-to-place), a search-driven page / tweet / news-article shot, or asset-fusion (a real image's geometry becomes the chart).
- Output: a short motion graphic → MP4 or a transparent overlay (alpha WebM / MOV) for a lower-third / callout.
- Triggers: "an 8s logo sting", "animate this stat", "a kinetic-type intro", "turn this tweet into a motion graphic", "a transparent lower-third overlay".
/music-to-video
- Input: A music track — an audio file, or a video to pull the audio from — with no narration and no website capture. Optionally, user-supplied images / videos to weave in. The track is analyzed once into a deterministic beat / energy map (
audiomap.json) the whole video is built on. - Output: a beat-synced HyperFrames composition → MP4 where the music drives pacing. Typography and templates are the floor (a complete video needs zero assets); any supplied media is cut onto the same beat grid (beat-cut / ken-burns). The genre — lyric video, slideshow, kinetic promo — emerges from the per-frame choices; the pipeline never branches on it.
- Triggers: "make a video for this song", "beat-synced video from this track", "lyric video", "turn this music into a video", "music visualizer / kinetic promo to this beat".
/slideshow
- Input: A presentation / pitch deck / interactive deck to author — a brief, an outline, or an existing page to convert to slides. Not a request for a rendered video; if the intent is ambiguous, the skill confirms "do you want this as a HyperFrames slideshow?" before authoring.
- Output: a runnable HyperFrames composition + a JSON island the player's
SlideshowControllerreads to turn the GSAP timeline into a navigable deck — discrete slides, fragment reveals, branching sequences, hotspot navigation, presenter mode, and speaker notes. The deliverable is a deck, not an MP4. - Triggers: "make a pitch deck / presentation / slide deck", "an interactive deck", "convert this page into slides", "a slideshow with presenter mode".
/general-video
- Input: Anything not above — a creative brief, a single element to animate, an edit to a composition you're building. Input- and length-agnostic.
- Output: a HyperFrames composition (any length / format) via the original flow: design system → prompt expansion → plan → layout-before-animation → build (delegating to the
hyperframes-* skills) → validate. - Triggers: "make a title card", "animate this", "a longer brand / sizzle reel", "a multi-scene composition", "a static loop / poster", any "make a video" that fits no row above.
/remotion-to-hyperframes
- Input: An existing Remotion (React) composition's source — the user explicitly asks to port / convert / migrate it. One-way (Remotion → HyperFrames); not creation-from-input. A passing mention of Remotion is not a trigger.
- Output: a HyperFrames HTML composition translated from the Remotion source, graded against the Remotion render (SSIM eval harness + tiered test corpus).
- Triggers: "port my Remotion project to HyperFrames", "convert this Remotion comp", "migrate from Remotion".