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 — how to build one hyperframes project. The body below is the build guide; per-topic detail lives in references/ (index next), read on demand. Other concerns live in the sibling domain skills — hyperframes-animation, hyperframes-creative, media-use, hyperframes-cli, hyperframes-registry. The capability map in /hyperframes says what each one covers.
References
| File |
Read it to… |
references/minimal-composition.md |
start from the smallest renderable composition skeleton |
references/composition-patterns.md |
choose monolithic vs modular; structure a modular index.html; pick a sub-comp archetype |
references/data-attributes.md |
look up any data-* (root / clip / sub-comp host / legacy aliases); use class="clip" |
references/tracks-and-clips.md |
pick data-track-index, handle same-track overlap / z-index, time a clip relative to another |
references/sub-compositions.md |
wire a sub-composition (host attrs, <template>, per-instance vars) and animate inside it |
references/variables-and-media.md |
declare variables; place <video>/<audio>, set volume, trim |
references/determinism-rules.md |
build a seekable timeline; determinism bans; the animatable-property allowlist; layout / text fit |
references/full-screen-motion.md |
author full-frame motion with shared backgrounds |
references/storyboard-format.md |
author a STORYBOARD.md plan (+ the parsed manifest) |
references/review-loop.md |
run the plan → sketch → build review passes on a live board — shared by every storyboard-planning workflow |
references/production-loop.md |
take an approved plan to a delivered video — the stage dependencies (audio, frames, assembly, transitions, captions, verify, deliver) a freeform build follows directly |
references/brief-contract.md |
the brief's ground rules — mode derivation (collaborative / autonomous), shared field registry, question invariants (the asking itself lives in /hyperframes → the intent layer) |
references/brief-format.md |
author BRIEF.md — the confirmed intent document a workflow's Setup writes and every later step reads |
references/script-format.md |
author the optional SCRIPT.md locked narration |
references/subagent-dispatch.md |
map subagent dispatch verbs (parallel fan-out / background / wait) to your harness |
references/tailwind.md |
work in a Tailwind v4 project (init --tailwind; runtime contract differs from Studio's v3) |
For animation runtime specifics (GSAP API, Lottie, Three.js, etc.) go to hyperframes-animation → adapters/<runtime>.md.
Building a composition
Two root forms (not interchangeable)
- Standalone (top-level
index.html) — root <div data-composition-id="…"> sits directly in <body>, no <template> wrapper (wrapping it hides all content and breaks rendering).
- Sub-composition (loaded via
data-composition-src) — root must be wrapped in <template>.
⚠ Transport rule: the runtime only clones <template> contents; everything outside (incl. <head> styles/scripts) is discarded — put <style>/<script> inside the template.
⚠ Host-id rule: the host slot's data-composition-id must exactly equal the inner template's data-composition-id and the window.__timelines["<id>"] key — no -mount/-slot/-host suffix.
File shape, host wiring, and the pre-render checklist → references/sub-compositions.md.
Root must be sized (silent layout bug)
The standalone root needs an explicit sized box (width/height in px), and every ancestor down to a height:100% element must have a resolved height — otherwise a flex/100% child collapses to ~0 and content piles into the top-left corner. Do not rely on automated gates alone to catch this; inspect a snapshot. Skeleton → references/minimal-composition.md.
One paused timeline
Each composition registers exactly one gsap.timeline({ paused: true }) at window.__timelines["<id>"] (key = root data-composition-id), built synchronously at page load. Render duration = root data-duration, not timeline length. Don't manually nest sub-timelines into the host. Full contract (incl. non-GSAP runtimes) → references/determinism-rules.md + hyperframes-animation/adapters/.
Non-negotiable rules (silent bugs automated gates may miss)
Surfaced here; full rationale in the linked reference. Do not violate:
- No render-time clocks / unseeded
Math.random / network / input-state; no repeat: -1 (use a finite count). → determinism-rules.md
- Animate only the visual-property allowlist; never tween
display or raw visibility. GSAP autoAlpha and zero-duration timeline boundary sets are the only visibility exceptions, and only on non-clip elements or wrappers inside a clip. The framework alone controls .clip visibility. Do not gsap.set later-scene clips at page load. → determinism-rules.md
- No
<br> in body text; transformed elements must be block-level + sized; pulsing absolute decoratives need peak clearance. → determinism-rules.md
<video>/<audio> must be a direct child of the host root (never inside a sub-comp <template>/wrapper); the framework owns playback. → variables-and-media.md
- Every
id must be unique across the assembled page; inside a sub-comp, prefix ids with the composition id (#<id>-hero). Duplicate <video>/<img> ids render blank — the producer injects frames by getElementById, and cross-file dupes slip past lint. → composition-patterns.md
- A full-screen scene fill goes on a full-bleed child (
position:absolute; inset:0), never on the composition root itself — the producer's frame compositing can drop the root element's own background (the frame renders black) even though preview/snapshot show it correctly. → composition-patterns.md
Editing existing compositions
- Read the files first. Preserve unrelated timing, tracks, IDs, variables, media paths.
- Match existing composition IDs and timeline keys.
- Adding a clip: pick a non-overlapping
data-track-index or adjust surrounding timing intentionally.
data-hidden on any composition element hides it in BOTH preview and render, overriding its time window; it is non-destructive/reversible and toggled by Studio's timeline eye icon.
- Adding a sub-composition: verify its internal
data-composition-id before wiring the host.
Validation
Use hyperframes-cli for command details
1---2name: hyperframes-core3description: Build a single renderable HyperFrames composition using HTML with data-* timing attributes, clips, tracks, sub-compositions, variables, and deterministic rendering rules.4---56# HyperFrames Core78HyperFrames 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.910This skill is the **technical contract** — how to build one hyperframes project. The body below is the build guide; per-topic detail lives in `references/` (index next), read on demand. Other concerns live in the sibling domain skills — `hyperframes-animation`, `hyperframes-creative`, `media-use`, `hyperframes-cli`, `hyperframes-registry`. The capability map in `/hyperframes` says what each one covers.1112## References1314| File | Read it to… |15| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |16| `references/minimal-composition.md` | start from the smallest renderable composition skeleton |17| `references/composition-patterns.md` | choose monolithic vs modular; structure a modular `index.html`; pick a sub-comp archetype |18| `references/data-attributes.md` | look up any `data-*` (root / clip / sub-comp host / legacy aliases); use `class="clip"` |19| `references/tracks-and-clips.md` | pick `data-track-index`, handle same-track overlap / z-index, time a clip relative to another |20| `references/sub-compositions.md` | wire a sub-composition (host attrs, `<template>`, per-instance vars) and animate inside it |21| `references/variables-and-media.md` | declare variables; place `<video>`/`<audio>`, set volume, trim |22| `references/determinism-rules.md` | build a seekable timeline; determinism bans; the animatable-property allowlist; layout / text fit |23| `references/full-screen-motion.md` | author full-frame motion with shared backgrounds |24| `references/storyboard-format.md` | author a `STORYBOARD.md` plan (+ the parsed manifest) |25| `references/review-loop.md` | run the plan → sketch → build review passes on a live board — shared by every storyboard-planning workflow |26| `references/production-loop.md` | take an approved plan to a delivered video — the stage dependencies (audio, frames, assembly, transitions, captions, verify, deliver) a freeform build follows directly |27| `references/brief-contract.md` | the brief's ground rules — mode derivation (collaborative / autonomous), shared field registry, question invariants (the asking itself lives in `/hyperframes` → the intent layer) |28| `references/brief-format.md` | author `BRIEF.md` — the confirmed intent document a workflow's Setup writes and every later step reads |29| `references/script-format.md` | author the optional `SCRIPT.md` locked narration |30| `references/subagent-dispatch.md` | map subagent dispatch verbs (parallel fan-out / background / wait) to your harness |31| `references/tailwind.md` | work in a Tailwind v4 project (`init --tailwind`; runtime contract differs from Studio's v3) |3233For animation runtime specifics (GSAP API, Lottie, Three.js, etc.) go to `hyperframes-animation` → `adapters/<runtime>.md`.3435## Building a composition3637### Two root forms (not interchangeable)3839- **Standalone** (top-level `index.html`) — root `<div data-composition-id="…">` sits directly in `<body>`, **no `<template>` wrapper** (wrapping it hides all content and breaks rendering).40- **Sub-composition** (loaded via `data-composition-src`) — root **must** be wrapped in `<template>`.4142> ⚠ Transport rule: the runtime **only clones `<template>` contents**; everything outside (incl. `<head>` styles/scripts) is discarded — put `<style>`/`<script>` **inside** the template.43> ⚠ Host-id rule: the host slot's `data-composition-id` must **exactly equal** the inner template's `data-composition-id` **and** the `window.__timelines["<id>"]` key — no `-mount`/`-slot`/`-host` suffix.4445File shape, host wiring, and the pre-render checklist → `references/sub-compositions.md`.4647### Root must be sized (silent layout bug)4849The standalone root needs an explicit **sized box** (`width`/`height` in px), and every ancestor down to a `height:100%` element must have a resolved height — otherwise a flex/`100%` child collapses to ~0 and content piles into the top-left corner. Do not rely on automated gates alone to catch this; inspect a snapshot. Skeleton → `references/minimal-composition.md`.5051### One paused timeline5253Each composition registers **exactly one** `gsap.timeline({ paused: true })` at `window.__timelines["<id>"]` (key = root `data-composition-id`), built **synchronously** at page load. Render duration = root `data-duration`, not timeline length. Don't manually nest sub-timelines into the host. Full contract (incl. non-GSAP runtimes) → `references/determinism-rules.md` + `hyperframes-animation/adapters/`.5455### Non-negotiable rules (silent bugs automated gates may miss)5657Surfaced here; full rationale in the linked reference. Do not violate:5859- No render-time clocks / unseeded `Math.random` / network / input-state; no `repeat: -1` (use a finite count). → `determinism-rules.md`60- Animate only the visual-property allowlist; never tween `display` or raw `visibility`. GSAP `autoAlpha` and zero-duration timeline boundary sets are the only visibility exceptions, and only on non-clip elements or wrappers inside a clip. The framework alone controls `.clip` visibility. Do not `gsap.set` later-scene clips at page load. → `determinism-rules.md`61- No `<br>` in body text; transformed elements must be block-level + sized; pulsing absolute decoratives need peak clearance. → `determinism-rules.md`62- `<video>`/`<audio>` must be a **direct child of the host root** (never inside a sub-comp `<template>`/wrapper); the framework owns playback. → `variables-and-media.md`63- Every `id` must be unique across the **assembled** page; inside a sub-comp, prefix ids with the composition id (`#<id>-hero`). Duplicate `<video>`/`<img>` ids render **blank** — the producer injects frames by `getElementById`, and cross-file dupes slip past `lint`. → `composition-patterns.md`64- A full-screen scene fill goes on a full-bleed **child** (`position:absolute; inset:0`), never on the composition root itself — the producer's frame compositing can drop the root element's own `background` (the frame renders **black**) even though preview/`snapshot` show it correctly. → `composition-patterns.md`6566## Editing existing compositions6768- Read the files first. Preserve unrelated timing, tracks, IDs, variables, media paths.69- Match existing composition IDs and timeline keys.70- Adding a clip: pick a non-overlapping `data-track-index` or adjust surrounding timing intentionally.71- `data-hidden` on any composition element hides it in BOTH preview and render, overriding its time window; it is non-destructive/reversible and toggled by Studio's timeline eye icon.72- Adding a sub-composition: verify its internal `data-composition-id` before wiring the host.7374## Validation7576Use `hyperframes-cli` for command details7778- [ ] `npx hyperframes check` passes (0 findings across lint, runtime, layout, motion, and contrast)79- [ ] Projects with sub-compositions: `npx hyperframes snapshot --at <midpoints>` and eyeball each frame80- [ ] `npx hyperframes preview` for review (the user can edit anything in Studio's timeline)81- [ ] `npx hyperframes render` only after the user approves