Skip to main content
HyperFrames uses normal HTML and CSS for appearance. A small set of attributes declares the frame size, duration, clips, media, and nested compositions. For a gentler explanation, start with Compositions and Data attributes.

Minimal composition

The root is a real, explicitly sized box. Its data-composition-id matches the timeline registry key.

Composition root

An explicit root data-duration is the render length. The compiler reads it before composition scripts run, so a script or variable override cannot change that value for the same render. The root may omit data-duration only when HyperFrames can infer a finite duration from the registered animation runtime or timed media. Three.js, unbounded animation, and timeline-free compositions need an explicit duration.

Timed clips

data-track-index does not control paint order. Use CSS z-index for front-to-back layering. Two clips on the same track must not overlap in time. Video visibility is managed as media and does not require class="clip". Audio has no visual lifecycle.

Media

Video and audio may omit data-duration when their intrinsic duration is known and the whole remaining source should play. Do not imperatively call play(), pause(), or set currentTime. HyperFrames owns media playback and seeking. A video should be muted unless it is intentionally audible and declares data-has-audio="true". Media can live inside nested composition markup. Keep element IDs unique across the assembled project because render-time frame injection targets those IDs.

Color grading and media effects

Studio and the CLI store color correction, grading, finishing controls, LUTs, and media effects on an image or video with data-color-grading:
The current effect families include essentials, retro and glitch, print, and art treatments. Run npx hyperframes media-treatment --capabilities --json for the current machine-readable surface instead of hard-coding an old effect list. The grading pipeline applies to real <img> and <video> elements. It does not grade a complete HTML scene. Use Studio or media-treatment for normal authoring; see Color Grading and Media Effects for the workflow and current SDR/HDR boundary.

Relative timing

A non-numeric data-start refers to the end of another clip in the same composition:
Supported forms are clip-id, clip-id + seconds, and clip-id - seconds. References stay within one composition, must resolve to a known duration, and cannot form a cycle. Put intentional overlaps on different tracks.

Nested compositions

The host declares a fixed timeline window:
The host data-composition-id must match the ID inside the source file and its timeline registry key. The host data-duration controls how long the nested composition remains visible. A shorter inner timeline holds its final state; a shorter host duration cuts the slot. A nested composition file transports its live markup through <template>. Styles and scripts needed by that composition must be inside the template:
HyperFrames seeks nested timelines independently. Do not add a child timeline manually to the parent GSAP timeline.

Variables

Declare the schema with data-composition-variables, then pass values through a render or a nested host:
Use data-var-text, data-var-src, or CSS var(--variableId) for direct bindings. Use getVariables() when the value affects logic.

Animation contract

A composition using GSAP must:
  • create one finite timeline with { paused: true };
  • register it synchronously on window.__timelines;
  • use the same key as data-composition-id;
  • avoid wall-clock state, unseeded randomness, and infinite repeats.
HyperFrames controls seeking. Composition code describes how the visual state looks at a given time.

Validate

lint checks the static contract. check opens the project in a browser and checks runtime behavior, layout, motion, and contrast. Watch representative snapshots and the finished render as the final visual gate.