算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
video-editing【设计与创意】Turn an approved script, provided talking-head/voiceover media, and gathered assets into a polished, creator-grade vertical (9:16) short rendered with HyperFrames. Encodes a non-negotiable init→preview→lint→render→verify workflow; a reusable editorial house look (mixed serif/sans headlines, paper-stage and dark-grid grounds, stacked splits with seam …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Use this skill when you have an approved script, provided voice/talking-head media, and gathered assets, and need to turn them into a finished vertical (9:16) short. You are the main editor, not a clip-stitcher. The bar is creator-grade shorts (Kallaway / Varun Mayya density): every beat earns attention. Generic AI-tool output — uniform 1s cuts, default fonts, linear/jittery transforms, a stock-template look — is a failure, not a deliverable.
Default ratio is 9:16 (1080×1920). The style packs also define 16:9 and 1:1 behavior, so the same look can be retargeted — but this skill's pacing and hook grammar are written for vertical short-form first.
Authoring index.html by hand from nothing breaks live-reload and project structure. Always:
npx hyperframes init edit inside your project's edit/ folder — creates the scaffold (index.html, meta.json, hyperframes.json, CLAUDE.md, package.json).cd edit and modify the generated project files to build the actual edit. Add fonts/, assets/sfx/, sub-compositions under compositions/.npx hyperframes preview (long-running — run in background) — verify in the browser with live reload. Use a browser tool to inspect and screenshot. Confirm pacing, layout, text timing, and animation smoothness before rendering.npx hyperframes lint / npm run check — fix every error; review warnings.npx hyperframes render — final MP4.ffprobe (9:16 dimensions, duration, codec) + ffmpeg frame spot-checks against a contact sheet. Run the bundled gate script (below).Use the hyperframes docs (npx hyperframes docs) for API/feature reference and the references in this skill for the editing standard. If HyperFrames tooling is missing or broken, stop and tell the user rather than hand-authoring a generic edit.
npx hyperframes. This skill is the editing standard on top of HyperFrames; it does not replace it.npx and the verification script).styles/<style>/FRAME.md (this skill ships vibe-life as a worked example and _template as a starting point — see styles/README.md).Work from one project folder. A recommended layout (adapt to yours):
your-project/
├── script.md # approved script with beats/timestamps, supers, energy cues — THE SPINE
├── voiceover/ # provided voice / talking-head media (the A-roll)
├── avatar/ # optional talking-head media
├── assets/
│ ├── manifest.json # gathered B-roll + per-beat asset map + rights notes
│ └── ... # the gathered media
└── edit/ # YOUR output (created by `npx hyperframes init edit`)
Read (do not edit) the script, the voice/avatar media, and the asset manifest. Pick the style pack the video should use (styles/<style>/FRAME.md).
Write everything under your project's edit/ folder:
index.html + compositions/ + fonts/ + assets/sfx/ + assets/master_audio.*).edit-report.md — a handoff note: per-beat edit decisions, assets used (with manifest references), SFX/music used, preview/render verification notes, and anything you flagged for final review. Template in references/edit-report-template.md (appended below).Each item below is a quality gate, not a suggestion.
The house visual language is the editorial look — see "editorial-look" below. Frames are designed pages, not video with text on top: mixed serif-italic/heavy-sans editorial headlines, paper-stage and dark-grid-interstitial grounds, the stacked split (B-roll top / talking head bottom) as the default A-roll/B-roll layout, highlight-bar supers with keyword color emphasis, seam captions and name pills, headline cards, and UI-card stacks. Build every short from those ten patterns, themed per style pack.
object-position so the face sits centered in the panel's visible area, eyes in the upper third — the default 50% 50% is almost always wrong for talking-head sources and cuts heads off. Camera moves on a person-panel must keep the face in frame for the entire move. An off-center or cropped face is a gate failure. See "editorial-look" §4 "Face-safe framing".FRAME.md.Derive the visual identity from the style pack first — colors, type, motion personality, and graphic language all come from styles/<style>/FRAME.md. Different style → different look. See "style-theming" below for turning FRAME.md into a concrete frame.md design spec (palette tokens, @font-face for local fonts, motion personality → easing/cut choices). The shipped vibe-life example uses a cream/ink/peach/butter palette; Space Grotesk + Instrument Serif italic + JetBrains Mono; paper-cut motion (hard cuts masked by SFX, not crossfades); one italic-serif accent word per frame in a pill; flat hard ink shadows. Your own style fills the same roles with its own tokens.
data-start, data-duration, data-track-index and class="clip" (the framework controls visibility via clip)..clip element itself — the framework owns its visibility/transform. Animate a child wrapper (e.g. .cam, .inner).gsap.timeline({ paused: true }) and registered on window.__timelines["main"] (id matches data-composition-id).Math.random(), no Date.now(), no network fetches, no repeat: -1. Renders are frame-sampled and must be reproducible.#root { container-type: size; } so cqw/cqh resolve against the frame (1cqw = 10.8px). Size type/graphics in cqw/cqh, not vw/vh.3.2 + 0.35 = 3.5500000000000003, which overlaps a clip starting at 3.55 and trips overlapping_clips_same_track. Leave a gap or use durations like 0.34. (Adopted from hyperframes-helper's lint gotchas.)muted with a separate <audio> element. Prefer one pre-mixed master audio track (VO + SFX mixed via ffmpeg adelay+amix) over many <audio> elements — multiple tracks cause echo/desync. Put it on a high, dedicated data-track-index.timeline_track_too_dense (many timed elements on one track) is advisory for a short pilot but real at scale — split scenes into sub-compositions (data-composition-src="compositions/file.html") for production-length edits.styles/<style>/FRAME.md. Produce the concrete design spec: palette tokens, local @font-face declarations, motion personality, graphic language. (See "style-theming".)build-in-editor (yours to build as motion graphics), which are alternate swaps. Never put placeholder/unlicensed media in a final render — flag gaps in the report.npx hyperframes init edit. Scaffold first. Then add fonts/ (local woff2 subsets), assets/sfx/, compositions/.index.html (and sub-compositions for length). Apply the editing grammar: engineered hook, A-roll/B-roll cover, non-metronomic cuts, split-screens, eased camera moves, kinetic text, themed MGs, logo animation. Animate child wrappers, never the .clip.anoisesrc/aevalsrc/sine) or use cleared assets; mix VO + SFX into one master track. (See "sfx-and-audio".)npx hyperframes preview in background; open in the browser; screenshot key beats; confirm pacing, layout, text timing, and motion smoothness. Fix before rendering.npm run check / npx hyperframes lint --verbose. Fix all errors; review warnings (note known false positives — e.g. WCAG-contrast warnings sampled at timestamps where a high-contrast card is hidden).npx hyperframes render → MP4.node scripts/verify-render.mjs <path-to-mp4> — asserts 9:16, expected duration, h264/yuv420p, audio present. Then ffmpeg frame spot-checks into a contact sheet and eyeball against the preview.edit-report.md and set disposition (done / in_review / blocked). Attach the MP4 + contact sheet.Run the verification gate (the script ships in scripts/verify-render.mjs next to this file):
node scripts/verify-render.mjs path/to/edit/<file>.mp4
Optionally assert exact specs:
node scripts/verify-render.mjs <file>.mp4 --duration 12 --tolerance 0.5
If a beat needs an asset your assets/ doesn't have:
alternate or build-in-editor rows first — custom motion-graphic beats are yours to build, not a blocker.edit-report.md.h264 / yuv420p, audio stream present. The gate script enforces this.ffmpeg extract frames across the timeline into a contact sheet; confirm each required technique renders on-style and matches the preview.edit-report.md under "Design decisions", with the reason. Visual changes are fine; silent visual changes are not.This skill researched the hyperframes docs, github.com/robonuggets/hyperframes-helper, and reference frames from creator-grade shorts, then went beyond them. See "standard-provenance" below for the breakdown. Summary:
data-* timing attributes + class="clip"; paused timelines on window.__timelines; GSAP power2/power3.out eases; white-glow caption styling; SVG underline emphasis; the lint gotcha list (overlap float-precision, deterministic-only, muted-video-plus-audio, etc.).FRAME.md → concrete design spec; rights-free SFX synthesis + single pre-mixed master-track discipline; and a render verification gate (ffprobe assertions + contact-sheet spot-checks).The authoring source keeps these as separate files under references/; they are inlined here so the skill is a single self-contained SKILL.md.
Distilled from stills of creator-grade shorts (Kallaway / Varun Mayya class) into ten
named patterns. These are the house layouts: build every short from them, themed
with your style pack's tokens (styles/<style>/FRAME.md). The recipes below show a
mapping for the shipped vibe-life example; substitute your own tokens.
The unifying idea: frames are designed pages, not video with text on top. Type is editorial (a heavy grotesque playing against an italic serif), media sits in cards or panels on a textured ground, and supers are typeset objects (bars, pills, underlines) — never bare drop-shadowed text.
One headline, two voices: heavy sans for the statement, italic serif for the twist word(s), plus a hand-drawn underline or highlight on the payoff.
Claude Just *Changed* ← serif italic on the verb
SOCIAL MEDIA FOREVER ← heavy grotesque, tight leading
━━━━━━━━━━━━ ← accent underline (brand accent)
.headline { text-align: center; line-height: 0.95; color: var(--fg); }
.headline .sans { font: 500 9cqw/0.96 "Space Grotesk"; letter-spacing: -0.32cqw; }
.headline .serif { font: italic 400 9cqw/0.96 "Instrument Serif"; }
.headline .underline {
display: block; width: 46cqw; height: 0.9cqw; margin: 1.6cqw auto 0;
background: var(--accent-strong); border-radius: 999px;
transform-origin: left center; /* animate scaleX 0→1, power3.out */
}
Rules: serif italic on one or two words max (the verb or the twist), never the whole
line. Underline draws in with scaleX after the words land. Mixed-case serif against
caps/title-case sans is the signature.
Full-frame off-white "paper" with a faint grid — media and graphics sit on it as cards. Used for hooks, logo beats, UI-stack beats.
.paper {
background:
linear-gradient(var(--line-faint) 1px, transparent 1px),
linear-gradient(90deg, var(--line-faint) 1px, transparent 1px),
var(--bg); /* e.g. #f3ecd9 */
background-size: 6cqw 6cqw, 6cqw 6cqw, auto;
}
/* --line-faint: color-mix(in srgb, var(--fg) 7%, transparent) */
Optional grain: a deterministic SVG feTurbulence data-URI at 4–6% opacity (fixed seed
— renders must stay reproducible). Never a looping video texture.
Full-frame ink wall with a visible grid, a centered mixed-type claim, and one lit accent cell — a typographic pattern interrupt between sections. Hold 0.6–1.2s.
.grid-wall {
background:
linear-gradient(rgba(255,255,255,0.07) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.07) 1px, transparent 1px),
#121110;
background-size: 4.5cqw 4.5cqw;
}
.grid-wall .cell { /* the single accent pixel */
position: absolute; width: 4.5cqw; height: 4.5cqw;
background: var(--accent-strong); filter: blur(0.15cqw);
}
Type on the wall follows pattern 1 (small serif italic line above, heavy sans claim,
serif italic tail below, ragged-right offset). A handful of grid cells may flicker
brighter — animate opacity on 2–4 cells, staggered, deterministic.
B-roll panel top (~52–56cqh), talking-head panel bottom, with the caption at the seam. This is the default A-roll/B-roll layout — full-frame B-roll cover is the exception, not the rule.
<div class="stack">
<div class="panel top"><video class="fill" ...></video></div>
<div class="seam-caption">For <em>13 years</em></div>
<div class="panel bottom"><video class="fill" ...></video></div>
</div>
.stack .panel { position: absolute; left: 0; right: 0; overflow: hidden; }
.stack .top { top: 0; height: 54cqh; }
.stack .bottom { bottom: 0; height: 46cqh; }
.seam-caption {
position: absolute; top: 54cqh; left: 0; right: 0; z-index: 2;
transform: translateY(-50%); text-align: center;
}
Moves in/out of full frame are deliberate: a panel grows into the full 9:16 (animate
height/y on the panel wrapper, power3.inOut, 0.45–0.6s, whoosh on the move) or the
top panel slides off and the bottom takes over. Panels can sit inside a dark grid frame
(pattern 3 ground showing at the edges) for a premium "mounted" look.
A panel crops the source video, and the default crop (object-position: 50% 50%) cuts
heads off or pushes the face to a corner. The face must sit centered in the panel's
visible area, eyes in the upper third. Never let a seam, caption, or panel edge crop
the face.
.panel video.fill { width: 100%; height: 100%; object-fit: cover; }
.panel.bottom video.fill { object-position: 50% 22%; } /* bias crop toward the face */
Procedure:
object-position: 50% <face-y>% per panel so the face lands mid-panel. A 46cqh
bottom panel showing a 9:16 source needs the y-bias — 50% 50% is almost always wrong.The big super is type inside a solid bar, one or two stacked bars, with the keyword in the accent color. Black-bar/white-text (newspaper) and accent-bar variants.
.bar-super { text-align: center; }
.bar-super .bar {
display: inline-block; padding: 0.8cqw 3cqw;
background: var(--fg); color: var(--bg); /* ink bar */
font: 500 7.4cqw/1.18 "Space Grotesk"; letter-spacing: -0.2cqw;
box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.bar-super .bar.accent { background: var(--accent-strong); } /* accent bar variant */
.bar-super .kw { color: var(--butter); } /* keyword pop inside the bar */
Two-line bars are staggered (second bar lands 0.08–0.12s after the first, y: 30 → 0,
power3.out). Numbers get the keyword color: **1** out of 3 employees.
Small rounded pill identifying who/what is on screen, or carrying the serif accent word
at a panel seam. Enters with scale: 0 → 1, back.out(2), a click SFX, sits for the beat,
exits before the panel changes.
A "clipping" for news/announcement beats: serif headline with an ink highlight bar over the key phrase, photo cut-outs below separated by a jagged divider (lightning-bolt SVG path), all on the paper stage.
.clipping h1 { font: italic 400 6.4cqw/1.15 "Instrument Serif"; color: var(--fg); }
.clipping h1 mark { background: var(--fg); color: var(--bg); padding: 0 1cqw; }
.clipping .photos { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6cqw; }
Animate like a build: headline types/slides in, highlight mark wipes across
(scaleX, origin left), photos drop in 0.1s apart with the divider flash.
Real screenshots (profiles, posts, dashboards, JSON) presented as a stack of rounded
cards with borders/shadows on the paper stage — evidence, typeset. Cards cascade in
(y-offset + stagger 0.1–0.14s, power3.out), slightly overlapping, ±1–2° rotation on
alternating cards. One small word super beneath ("connect") in heavy sans.
For a single hype word over B-roll: script/serif word small above, the big word in heavy
caps with an outlined-glow twin behind it (-webkit-text-stroke + soft text-shadow in
the accent). At most once per short — it is the loudest element in the kit.
Captions live at layout seams (between stacked panels) or in the scrim band over the
talking head — small serif italic phrases (For 13 years, order sunlight) in the
accent or paper color. One short phrase at a time, timed to the VO clause, fade or
rise 20–30px in. Never paragraph captions; never full-sentence karaoke captions in this
look.
FRAME.md.Before designing anything, turn your style pack's styles/<style>/FRAME.md into a
concrete, usable design spec for the edit. Different style → different look. Never
ship a generic theme.
Palette → CSS custom properties. Pull every named color and define tokens on
:root so every scene references the same source of truth:
:root {
--cream: #f4efe6; --ink: #1a1714; --peach: #f2a07a;
--butter: #f5cf6a; --moss: #8a9b6e; --sky: #8fb3c4; --plum: #9a7aa0;
}
Typography → local @font-face. Renders must be deterministic and offline —
never rely on a font CDN at render time. Download woff2 subsets into fonts/ and
declare them locally:
@font-face { font-family: "Space Grotesk"; src: url("fonts/spacegrotesk.woff2") format("woff2"); }
@font-face { font-family: "Instrument Serif"; src: url("fonts/instrumentserif.woff2") format("woff2"); font-style: italic; }
@font-face { font-family: "JetBrains Mono"; src: url("fonts/jetbrainsmono.woff2") format("woff2"); }
Fetch the latin subset, largest woff2 per family (a too-small file is usually a wrong/partial subset). Map each face to its role: display sans for headlines, italic serif for the accent word, mono for spec/number/code cards.
Motion personality → easing & cut style. FRAME.md describes how the style moves. Translate it:
power1.inOut drifts; no bouncy back/elastic on the spine.power3.out arrivals, occasional back.out
accents.
Reconcile a calm personality with short-form energy by keeping transitions on-style
(hard cuts) while letting pacing (cut frequency) carry the energy.Graphic language → MG recipes. FRAME.md's signature devices become reusable motion graphics: e.g. one italic-serif accent word per frame in an accent pill; flat hard ink shadows (offset solid, never blurred); number/ledger cards on a paper stage.
HyperFrames prefers a lowercase frame.md as the per-project design spec. Produce one in
edit/ capturing: the token palette, the three font roles, the motion-personality
decision, and the graphic devices you'll reuse. This keeps every scene coherent and gives
the next editor a single reference.
Set #root { container-type: size; } and size type/graphics in cqw/cqh (1cqw = 10.8px
at 1080 wide). This keeps proportions identical between preview and render and lets spacing
scale cleanly. Avoid vw/vh — they resolve against the viewport, not the frame.
HyperFrames renders by seeking a paused GSAP timeline to sampled frame times and screenshotting. Camera motion that looks fine in a live preview can stutter or shimmer in the render if the transform isn't GPU-promoted and sub-pixel-stable. This is the single biggest gap between "AI-tool output" and creator-grade. hyperframes-helper has no camera system — this is added by this skill and mandatory.
Never animate the .clip element. The framework owns its visibility and base
transform. Put a .cam wrapper inside the clip and animate that.
<div class="clip" data-start="5.0" data-duration="2.6" data-track-index="1">
<div class="cam"> ... scene content ... </div>
</div>
GPU-promote the moving layer so the compositor (not layout) handles the transform — this is what kills jitter:
.cam {
will-change: transform;
backface-visibility: hidden;
transform: translateZ(0); /* forces its own compositor layer */
}
Force 3D on the tween so GSAP writes matrix3d, not matrix:
gsap.set(".cam", { force3D: true });
Ease, never linear. Linear camera moves read as robotic. Use power1.inOut for
slow drifts, power2.out/power3.out for arrivals. Reserve expo/back for accents,
not the base camera.
Keep magnitudes small. A push is scale 1.0 → 1.12 over 2–3s, a pan is
xPercent ±1.5 — not ±20. Big fast moves amplify sampling stutter and read as cheap.
Slow, subtle, eased.
Anchor the zoom. Set transform-origin deliberately (center, or toward the
subject) so a zoom pushes into the point of interest, not the geometric center by
accident.
Eased zoom-in push:
tl.set("#s4 .cam", { force3D: true });
tl.fromTo("#s4 .cam",
{ scale: 1.0, xPercent: -1.5 },
{ scale: 1.12, xPercent: 1.5, duration: 2.6, ease: "power1.inOut" },
5.0
);
Push left/right pan: animate xPercent only, small magnitude, power1.inOut. Combine
with a tiny scale: 1.04 so edges never reveal the frame boundary.
Split → full-frame grow: a panel starts as half-frame (width: 50cqw) and grows to
full (100cqw) with power3.out, while the sibling panel slides out. This is the
"character grows into the full 9:16 frame" hook move — eased arrival, masked by a whoosh
SFX on the cut.
Live preview interpolates smoothly; the render samples discrete frames. After rendering,
extract 3–5 frames across the camera move with ffmpeg and check for: shimmer on text
edges, sub-pixel jutter, or a "pop" at the start/end (usually a missing fromTo start
state or animating the clip instead of the wrapper).
SFX separate creator-grade edits from silent slideshows: whooshes on camera moves, clicks on text entrances, risers into reveals, impacts on graphic hits — all subtle, mixed under the voice. Two hard problems: getting rights-free SFX, and avoiding echo/desync from multiple audio elements.
No licensing, no provenance burden — synthesize SFX deterministically. Generate each into
assets/sfx/:
Whoosh (cut / camera move) — filtered pink noise with a fast envelope:
ffmpeg -f lavfi -i "anoisesrc=duration=0.45:color=pink:sample_rate=48000:amplitude=0.5" \
-af "afade=t=in:st=0:d=0.05,afade=t=out:st=0.2:d=0.25,highpass=f=300,lowpass=f=6000" \
assets/sfx/whoosh.wav
Gotcha: always quote the lavfi arg. An unquoted
*elsewhere in the command can glob and shift ffmpeg's positional args, mis-parsingr=$SRetc.
Click (text/UI entrance) — short high sine blip:
ffmpeg -f lavfi -i "sine=frequency=2200:duration=0.04:sample_rate=48000" \
-af "afade=t=out:st=0.01:d=0.03" assets/sfx/click.wav
Riser (build into a reveal) — rising sweep via aevalsrc/sine with frequency ramp,
~0.6–1.0s, fade in.
Impact (graphic hit / landing) — low sine (~80–120Hz) + short noise burst, fast decay.
Keep SFX −18 to −12 dB under the voice. They punctuate; they don't compete.
<audio> elements)Multiple simultaneous <audio> elements cause echo, drift, and desync in the render.
Instead, mix VO + all SFX into one master track offline with ffmpeg, placing each SFX
at its cut time via adelay, then amix:
ffmpeg \
-i voiceover/vo.wav \
-i assets/sfx/whoosh.wav -i assets/sfx/click.wav -i assets/sfx/riser.wav -i assets/sfx/impact.wav \
-filter_complex "\
[1]adelay=2200|2200,volume=0.5[w]; \
[2]adelay=3200|3200,volume=0.4[c]; \
[3]adelay=7000|7000,volume=0.45[r]; \
[4]adelay=7600|7600,volume=0.6[i]; \
[0][w][c][r][i]amix=inputs=5:duration=longest:normalize=0[mix]" \
-map "[mix]" -ar 48000 -ac 2 assets/master_audio.wav
adelay is in milliseconds per channel (ms|ms for stereo). normalize=0 keeps the
VO from being attenuated by the mixer. Then encode to .m4a (AAC) for the render and
reference the single file from one <audio> element on a dedicated high data-track-index:
ffmpeg -i assets/master_audio.wav -c:a aac -b:a 192k assets/master_audio.m4a
<audio class="clip" data-start="0" data-duration="12" data-track-index="9"
src="assets/master_audio.m4a"></audio>
Videos stay muted; their audio (if any) is pre-mixed into the master too. Keep the master
length == composition duration so the gate script's audio + duration checks pass.
Write this to your project's edit/edit-report.md. It is the editor→reviewer handoff.
Fill every section; do not leave placeholders.
# Edit report — {project}: {title}
**Disposition:** done | in_review | blocked
**Output:** edit/{file}.mp4 — {WxH}, {duration}s, {codec}, audio {present/absent}
**Style:** {style} (theme from styles/{style}/FRAME.md)
## Beat-by-beat edit decisions
| Beat / ts | A-roll | B-roll / MG | Cut & camera | On-screen super | SFX |
|-----------|--------|-------------|--------------|-----------------|-----|
| S1 0–2.2s | VO hook | — | kinetic text in | "..." (accent word) | click |
| ... | | | | | |
## Assets used
- {manifest file} → beat {S#}: {how used in the cut}. status: {gathered/alternate}.
- Built-in-editor MGs: {list} (no stock equivalent — designed on the style theme).
- Self-fetched (if any): {file} ← {source URL}, {tool}, {license}.
## Audio
- Voiceover: {voiceover/file}
- SFX: {list} — synthesized via ffmpeg (rights-free) | cleared asset {provenance}
- Mixed to single master: assets/master_audio.m4a ({duration}s, 48kHz stereo)
## Design decisions
- {any deviation from the style spec or editorial-look patterns: what changed, why.
"None" if the edit is fully on-pattern.}
## Verification
- Preview: {beats screenshotted; pacing/layout/timing confirmed}
- Face check: {every person-frame shows the whole face centered in its panel — confirmed}
- Lint: {errors fixed}; warnings: {list + which are known false positives and why}
- ffprobe: {WxH} / {codec} / {fps} / {frames} / {duration} / {audio}
- Frame spot-checks: contact sheet at {path}; all required techniques render on-style.
- Gate script: PASS
## Rights flags
- needs-final-review: {assets, if any — confirm a license before publish}
- missing: {NONE in render — listed here if a beat still wants an official file}
## Gaps / next steps
- {anything deferred, any follow-up needed from the user}
Keep it readable: decisions and evidence, not narration. If blocked, the disposition line and the gaps section must make the blocker and the next action unambiguous.
Recorded so anyone reading the skill can see what is reused convention vs. added here.
npx hyperframes docs, llms.txt index).data-start/data-duration/
data-track-index/data-media-start timing; class="clip" for framework visibility
control.window.__timelines["<composition-id>"];
deterministic-only constraint (no random/now/fetch/repeat:-1).power2.out / power3.out for arrivals, power1.inOut
for drifts.overlapping_clips_same_track
trap, muted video + separate <audio>, and the self-attribute-selector warning.will-change/backface-visibility/translateZ(0)/force3D, animate-the-wrapper-not-
the-clip, small eased magnitudes, verify-in-render). hyperframes-helper has no camera
system at all.styles/<style>/FRAME.md → concrete frame.md design spec
(palette tokens, local @font-face for offline-deterministic renders, motion-personality
→ easing/cut mapping, graphic devices).<audio> echo/desync.scripts/verify-render.mjs — ffprobe assertions (9:16,
duration±tol, h264/yuv420p, audio present) plus contact-sheet frame spot-checks. Turns
"looks fine in preview" into a hard, scriptable acceptance check.container-type: size on #root + cqw/cqh sizing so
preview and render match exactly at 1080×1920.