hyperframes-core
HyperFrames HTML composition contract. Use for composition structure, data attributes, clips, tracks, sub-compositions, variables, media playback, deterministic render rules, and validation of minimal renderable projects.
다음 행동
/hyperframes-core기술 README 원문 보기
설치 옵션, 예시 코드, 세부 사용법을 영어 README 원문 그대로 확인합니다.
HyperFrames Core
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.
This skill is the technical contract. Other concerns live in sibling skills:
hyperframes-animation— atomic motion rules + scene blueprints + per-runtime adapters (GSAP, Lottie, Three, Anime.js, CSS, WAAPI, TypeGPU)hyperframes-creative— palettes, typography, narration, beat planning, audio-reactivehyperframes-media— TTS, Whisper transcribe, background removal, captionshyperframes-registry— install blocks and components (hyperframes add)hyperframes-cli— dev loop commands (lint / validate / preview / render)
For Tailwind v4 projects (hyperframes init --tailwind), see references/tailwind.md — the browser-runtime contract is distinct from Studio's Tailwind v3 setup.
Routing
| Want to… | Read |
|---|---|
| See a minimal renderable composition | references/minimal-composition.md |
| Decide between monolithic single-file and modular sub-comp architecture | references/composition-patterns.md |
Structure a modular index.html (orchestrator + slots + root audio) | references/composition-patterns.md |
| Pick a sub-comp archetype (content / driver-only / multi-scene merge / audio-reactive) | references/composition-patterns.md |
Look up a data-* attribute (root, clip, sub-comp host, legacy aliases) | references/data-attributes.md |
Use class="clip" correctly | references/data-attributes.md |
Pick a data-track-index; same-track overlap; track-index vs CSS z-index | references/tracks-and-clips.md |
Time a clip relative to another (data-start="intro + 2", crossfade overlap, chains) | references/tracks-and-clips.md |
Wire a sub-composition (host attributes, <template> wrapper, per-instance variables) | references/sub-compositions.md |
Animate inside a sub-composition (gsap.fromTo over gsap.from, seek-back behavior) | references/sub-compositions.md |
Declare variables (types, extra options, defaults, --strict-variables in CI) | references/variables-and-media.md |
Place <video> / <audio>, set volume, trim with data-media-start | references/variables-and-media.md |
Build a seekable timeline (paused, sync construction, gsap.set later-scene trap) | references/determinism-rules.md |
Avoid non-deterministic state (clocks, Math.random, repeat: -1, finite repeat formula) | references/determinism-rules.md |
Know what can / cannot be animated (visual-property allowlist; not display/visibility) | references/determinism-rules.md |
Fit text and prevent overflow (fitTextFontSize signature, <br> rule, layout contract) | references/determinism-rules.md |
| Author full-frame motion with shared backgrounds | references/full-screen-motion.md |
Work in a Tailwind v4 project (init --tailwind) | references/tailwind.md |
For animation runtime specifics (GSAP API, Lottie, Three.js, etc.) go to hyperframes-animation → adapters/<runtime>.md.
Composition Structure
Two root forms; they are not interchangeable.
- Standalone (the top-level
index.html) — root<div data-composition-id="…">sits directly in<body>. No `<template>` wrapper. Wrapping a standalone root in<template>hides all content from the browser and breaks rendering. - Sub-composition (a file loaded via
data-composition-src) — root<div data-composition-id="…">must be wrapped in<template>. Without the wrapper the runtime cannot extract and mount it.
> ⚠ Sub-composition transport rule: the runtime only clones `<template>` contents into the live DOM. Everything outside the template — including <head> and any <style>/<script>/<link> that lives in <head> — is discarded. Put <style> and <script> blocks inside <template>, not in <head>. > > ⚠ Host-id rule: in the host file, data-composition-id on the slot must exactly equal the inner template's data-composition-id and the window.__timelines["<id>"] key. Do not add -mount / -slot / -host suffixes.
See references/sub-compositions.md for the file shape, host wiring, pitfall examples, and the pre-render verification checklist.
Root must be sized (silent layout bug)
The standalone root must establish an explicitly sized box, and every ancestor between it and a height: 100% element must have a resolved height. If the root or an intermediate wrapper has no height, a flex/height:100% content container collapses to ~0 and content piles into the top-left corner (often clipping the first glyph at x=0). lint, validate, and inspect do not catch this — inspect substitutes the authored data-width/data-height for a collapsed root and reports "0 layout issues."
<body style="margin: 0">
<div
id="root"
data-composition-id="main"
data-width="1920"
data-height="1080"
data-duration="5"
style="position: relative; width: 1920px; height: 1080px; overflow: hidden"
>
<!-- Center robustly: position:absolute + inset:0 fills the sized root regardless of
intermediate wrappers; or use a flex container ONLY if its parent chain is sized. -->
<section
class="clip"
data-start="0"
data-duration="5"
data-track-index="1"
style="position: absolute; inset: 0; display: grid; place-items: center; padding: 120px 160px; box-sizing: border-box"
>
<h1>Title</h1>
</section>
</div>
</body>Keep the padding (≥80px) on the centering container — it is the title-safe margin that stops large type touching the frame edge. See references/minimal-composition.md.
Timeline Contract (GSAP default)
Every composition registers exactly one GSAP timeline.
- Create with
gsap.timeline({ paused: true })— the player owns playback. - Register at
window.__timelines["<composition-id>"]; the key must exactly match the root'sdata-composition-id. Dot syntax (window.__timelines.<id> = tl) is equivalent when the id is a valid identifier; use brackets if the id contains-. - Build the timeline synchronously during page load — not inside
async,setTimeout,Promise, or event handlers. The renderer samples after page load completes; any deferred timeline construction misses the sample. - Render duration comes from
data-durationon the root, not from GSAP timeline length. Do not pad the timeline with empty tweens to set duration. - For sub-compositions, do not manually nest sub-timelines into the host (
master.add(sub)); the framework drives them independently.
For non-GSAP runtimes (Lottie / Three / WAAPI / CSS / Anime.js / TypeGPU), the equivalent contract lives in hyperframes-animation/adapters/<runtime>.md. See references/determinism-rules.md for the cross-runtime Animation Runtime Contract.
Non-Negotiable Rules
These break the renderer — or produce silent visual bugs that `lint`/`validate`/`inspect` do NOT catch (rules 3, 7-8). (Synchronous timeline construction is covered above in Timeline Contract.)
- No
Math.random()/Date.now()/performance.now()driving visuals — use a seeded PRNG. - No
repeat: -1. Userepeat: Math.max(0, Math.floor(duration / cycleDuration) - 1)— `floor`, not `ceil` (ceilovershootsdata-durationand trips thegsap_repeat_ceil_overshootlint;max(0, …)avoids a negative repeat = infinite). <video>/<audio>must be a direct child of the host root (index.html) — never inside a sub-comp<template>, never inside a wrapper<div>; otherwise it is never decoded and renders blank/black (silent). The framework owns playback: novideo.play()/audio.play()/currentTime = …. A sub-comp cannot drive host elements (selector orquerySelector), so animate host media from the main timeline at global time. Seereferences/variables-and-media.md.- No
gsap.set()on clip elements from later scenes (they are not in the DOM yet). Usetl.set(selector, vars, time)at or after the clip'sdata-start. - No animating
display/visibility. Animateopacity/ transforms; the clip lifecycle handles show/hide. - No
<br>in body text. Let text wrap viamax-width. - Transformed elements must be block-level + sized.
transform/scaleX/scaleYis a no-op on an inline `<span>`, and scaling an auto-width (0px) element shows nothing → invisible bars/fills. Give themdisplay: block/inline-block/flex-item and a realwidth/height(e.g.width: 100%inside a sized parent). - Absolutely-positioned decoratives (badges, pills, tags) that pulse or overshoot (
yoyoscale,back.out) need clearance at their peak size and must not straddle anoverflow: hiddenedge — else they overlap a neighbor or get clipped. Position for the largest frame, not the resting one.
Editing Existing Compositions
- Read the actual files before editing.
- Preserve unrelated timing, tracks, IDs, variables, and media paths.
- Match existing composition IDs and timeline registry keys.
- When adding a clip, choose a non-overlapping
data-track-indexor intentionally adjust surrounding timing. - When adding a sub-composition, verify its internal
data-composition-idbefore wiring the host.
Validation
Use hyperframes-cli for command details.
- [ ]
npx hyperframes lintpasses (0 errors) - [ ]
npx hyperframes validatepasses (0 console errors) - [ ]
npx hyperframes inspectpasses, or overflow is intentionally marked - [ ] Projects with sub-compositions:
npx hyperframes snapshot --at <midpoints>and eyeball each frame
이것도 같이 보면 좋다
같은 업무 태그와 카테고리가 겹치는 항목부터 보여줍니다.

faceless-explainer
faceless-explainer video workflow - arbitrary text (article / notes / topic / brief) -> narrator_scripts.json + audio (voice + BGM) + section_plan.md -> typography / abstract-graphics / diagram / data-viz video. Typical length up to ~3 min (sweet spot ~30-90s); a genuinely longer piece is general-video, not this workflow. Generates its OWN narration (TTS) — it does not sync to a user-supplied / pre-recorded voiceover (that is general-video). No website capture, no real product screenshots. If the text names a product / its site to promote, that is /product-launch-video; when product-vs-topic is unclear, start at /hyperframes-read-first.

general-video
Use as the fallback for custom HyperFrames HTML video composition authoring when no specialized workflow fits. Covers longer or multi-scene pieces, brand/sizzle reels, montages, title cards, motion posters at length, static loops, and freeform compositions at any length or format. Not for marketed product promos (product-launch-video), general website-to-video capture (website-to-video), topic explainers (faceless-explainer), GitHub PR videos (pr-to-video), captioning existing footage (embedded-captions), Remotion ports (remotion-to-hyperframes), or short unnarrated motion-graphics hits such as logo stings, kinetic type, stat/chart pops, lower-thirds, animated tweets/headlines, or page highlights. If a specialized workflow clearly fits the input, prefer it (see /hyperframes-read-first); use this only as the input/length-agnostic fallback.

graphic-overlays
Package an existing talking-head / interview / podcast video by layering timed, designed GRAPHIC OVERLAY cards onto the playing video — titles, lower-thirds, data callouts, quotes, side panels, picture-in-picture — synced to the transcript. The source video plays in full; the agent designs and writes each card's HTML in conversation, then renders to MP4 via hyperframes. Use when the user asks for graphic overlays, on-screen graphics / lower-thirds / data callouts / kinetic titles on a video, "package / dress up my video", "add overlay cards / graphic cards", or AI-composed graphic packaging of an existing video. NOT for plain subtitles (→ embedded-captions) or building a video from scratch (→ the creation workflows); when unsure overlays-vs-captions, see /hyperframes-read-first.