Every SKILL.md already declared the new name — name: frames, frames-cli, frames-core, and so on — but the directories were never moved, so the tree carried frames-* in content and hyperframes-* on disk. Everything that resolves a skill by path missed: the core-skill list, the plugin marketplace pin, and the docs the CLI reads at runtime. Eight tests failed on main because the files they open do not exist. The directories now match what the files say they are, and the guide the claude-design contract reads takes the name that contract already used.
3.5 KiB
Tracks and Clips
Clips are timed children of the composition root. Tracks are a temporal-overlap concept, not a visual-stacking concept.
What is a Clip
A clip is any DOM element with data-start, data-duration (where required), and data-track-index. Common kinds:
- Visual
<div>clips — scenes, cards, overlays. Always requiredata-duration. - Sub-composition hosts —
<div>withdata-composition-src. Always requiredata-duration. - Video clips —
<video>withmutedandplaysinline. Duration can default to media length. - Audio clips —
<audio>. Duration can default to media length. - Image clips —
<img>. Always requiredata-duration.
Add class="clip" to authored visual clips so tooling and examples can find them.
Tracks Are Temporal, Not Visual
data-track-index controls temporal overlap, not paint order:
- Two clips on the same
data-track-indexmust NOT overlap in time.frames lintflags this. - Visual layering (front/back) is controlled by CSS
z-index, not by track index.
A clip on track 5 is not "above" a clip on track 1 — it's just on a different audio/visual lane in time. Use CSS for layering, tracks for sequencing.
Picking a Track Index
There's no fixed convention, but common patterns:
- Track 0 — base video (e.g. an A-roll).
- Track 1+ — visual scenes, overlays, captions.
- Higher tracks (e.g. 10+) — audio clips, separated from visual tracks to keep linting clear.
When adding a new clip to an existing composition:
- Find an existing track that has no overlap with your new clip's
[data-start, data-start + data-duration)range. - Or pick a fresh track index.
- Never overlap two clips on the same track — the linter will fail and the render is undefined.
Clip Time Inside the Composition
data-start is in seconds, measured from the start of the composition. For sub-compositions, the sub-composition's internal timeline (its own data-duration and child clips) runs from data-start to data-start + data-duration of the host.
data-media-start (on <video>/<audio>) is an offset into the source media. Use it to skip the first few seconds of a media file without trimming the file itself.
Relative Timing
data-start accepts a clip ID instead of a number, meaning "start when that clip ends". Add + N / - N to offset; negative produces overlap (useful for crossfades).
<video id="intro" data-start="0" data-duration="10" data-track-index="0" src="..."></video>
<video id="main" data-start="intro" data-duration="20" data-track-index="0" src="..."></video>
<video
id="scene-a"
data-start="intro + 2"
data-duration="20"
data-track-index="0"
src="..."
></video>
<video
id="scene-b"
data-start="intro - 0.5"
data-duration="20"
data-track-index="1"
src="..."
></video>
Rules:
- References resolve inside the same composition only — cannot reach into a parent or sibling sub-composition.
- The referenced clip must have a known duration (explicit
data-durationor inferred from media). Otherwise the reference cannot resolve. - No circular references —
A → B → Ais rejected. Cycles are detected and error out. - A value that parses as a number is always treated as absolute seconds. Otherwise the resolver expects
<id>,<id> + <number>, or<id> - <number>(whitespace optional). - References can chain (
A → B → C). Keep chains under 3-4 levels for readability. - Negative offsets create overlap; overlapping clips must be on different tracks, same-track overlap is rejected.