Skip to main content

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.

Source facts

Repository
coco-research/Mira
Last source activity
June 30, 2026 at 16:32
Detected SKILL.md language
English
Stars
6
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
11 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
hyperframes-core
description
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 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-reactive - `hyperframes-media` — TTS, Whisper transcribe, background removal, captions - `hyperframes-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." ```html <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's `data-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-duration` on 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**.) 1. No `Math.random()` / `Date.now()` / `performance.now()` driving visuals — use a seeded PRNG. 2. No `repeat: -1`. Use `repeat: Math.max(0, Math.floor(duration / cycleDuration) - 1)` — **`floor`, not `ceil`** (`ceil` overshoots `data-duration` and trips the `gsap_repeat_ceil_overshoot` lint; `max(0, …)` avoids a negative repeat = infinite). 3. `<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: no `video.play()` / `audio.play()` / `currentTime = …`. A sub-comp **cannot** drive host elements (selector or `querySelector`), so animate host media from the **main timeline** at global time. See `references/variables-and-media.md`. 4. No `gsap.set()` on clip elements from later scenes (they are not in the DOM yet). Use `tl.set(selector, vars, time)` at or after the clip's `data-start`. 5. No animating `display` / `visibility`. Animate `opacity` / transforms; the clip lifecycle handles show/hide. 6. No `<br>` in body text. Let text wrap via `max-width`. 7. Transformed elements must be block-level + sized. `transform`/`scaleX`/`scaleY` is a **no-op on an inline `<span>`**, and scaling an auto-width (0px) element shows nothing → invisible bars/fills. Give them `display: block`/`inline-block`/flex-item **and** a real `width`/`height` (e.g. `width: 100%` inside a sized parent). 8. Absolutely-positioned decoratives (badges, pills, tags) that **pulse or overshoot** (`yoyo` scale, `back.out`) need clearance at their **peak** size and must not straddle an `overflow: hidden` edge — 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-index` or intentionally adjust surrounding timing. - When adding a sub-composition, verify its internal `data-composition-id` before wiring the host. ## Validation Use `hyperframes-cli` for command details. - [ ] `npx hyperframes lint` passes (0 errors) - [ ] `npx hyperframes validate` passes (0 console errors) - [ ] `npx hyperframes inspect` passes, or overflow is intentionally marked - [ ] Projects with sub-compositions: `npx hyperframes snapshot --at <midpoints>` and eyeball each frame
View on GitHub