diff --git a/docs/guides/claude-design-hyperframes.md b/docs/guides/claude-design-hyperframes.md index 172b4b1bb5..65b391cf53 100644 --- a/docs/guides/claude-design-hyperframes.md +++ b/docs/guides/claude-design-hyperframes.md @@ -374,7 +374,7 @@ The skeleton handles most structural rules. These are the runtime rules the skel | `Math.random()` | Seeded PRNG (only if you need randomness) | | `Date.now()`, `performance.now()` | Hard-coded timing or `tl.time()` in `onUpdate` | | `setInterval`, `setTimeout` | Timeline tweens + `onUpdate` | -| `repeat: -1` | `repeat: Math.max(0, Math.floor(duration / cycle) - 1)` | +| `repeat: -1` without root `data-duration` | a finite root `data-duration` (export clips to it), or `repeat: Math.max(0, Math.floor(duration / cycle) - 1)` | | `stagger: { from: "random" }` | `from: "start"`, `"center"`, `"end"` | | Async timeline construction | Synchronous at page load | @@ -415,7 +415,7 @@ Run before delivering. Check with actual code, not assumptions. - [ ] Shader transitions have boundary INSIDE the window: `time < boundary < time + duration` - [ ] No transition shorter than 0.3s - [ ] No exit tweens except on the final scene -- [ ] No `Date.now()`, unseeded `Math.random()`, `repeat: -1` +- [ ] No `Date.now()`, unseeded `Math.random()`, or `repeat: -1` without a finite root `data-duration` - [ ] No SVG filter data URLs as `background-image` - [ ] `window.__timelines["main"] = tl` matches `data-composition-id` diff --git a/docs/guides/claude-design-send-to-hyperframes.md b/docs/guides/claude-design-send-to-hyperframes.md index c5a2e7a40b..60e842bfbd 100644 --- a/docs/guides/claude-design-send-to-hyperframes.md +++ b/docs/guides/claude-design-send-to-hyperframes.md @@ -371,7 +371,7 @@ The cloud renderer seeks the timeline frame-by-frame. Non-deterministic or self- | `Date.now()`, `performance.now()` | hard-coded timing or `tl.time()` in `onUpdate` | | `setInterval`, `setTimeout` | timeline tweens + `onUpdate` | | `requestAnimationFrame` | GSAP tweens | -| `repeat: -1` | `repeat: Math.max(0, Math.floor(duration / cycle) - 1)` | +| `repeat: -1` without root `data-duration` | a finite root `data-duration` (export clips to it), or `repeat: Math.max(0, Math.floor(duration / cycle) - 1)` | | `stagger: { from: "random" }` | `from: "start"`, `"center"`, or `"end"` | | async timeline construction | build synchronously at page load | | `video.play()` / `audio.play()` | the framework owns playback | @@ -427,6 +427,6 @@ You don't author any of this. Produce a clean, on-brand, correctly-timed silent - [ ] No exit tweens except on the final scene **Renders correctly:** -- [ ] No `Date.now()`, unseeded `Math.random()`, `setInterval/Timeout`, `requestAnimationFrame`, `repeat: -1` +- [ ] No `Date.now()`, unseeded `Math.random()`, `setInterval/Timeout`, `requestAnimationFrame`, or `repeat: -1` without a finite root `data-duration` - [ ] Timeline built synchronously; paused; framework owns playback - [ ] Colors and fonts exact; brand substance preserved: real headline/copy, distinctive figures/stats/data points, product names, and signature visuals carried over verbatim (form adapted, never genericized or invented); no placeholders; ≥2 animation patterns + mid-scene activity per scene diff --git a/skills-manifest.json b/skills-manifest.json index 97809b8906..9e67b48052 100644 --- a/skills-manifest.json +++ b/skills-manifest.json @@ -2,7 +2,7 @@ "source": "heygen-com/hyperframes", "skills": { "embedded-captions": { - "hash": "1677ab00946eb80c", + "hash": "f872cc10b6453f81", "files": 142 }, "faceless-explainer": { @@ -10,7 +10,7 @@ "files": 24 }, "figma": { - "hash": "642cce1b5e211182", + "hash": "c6854f1238f1282e", "files": 2 }, "general-video": { @@ -22,7 +22,7 @@ "files": 17 }, "hyperframes-animation": { - "hash": "a5be218c0b0fe377", + "hash": "3d35306715eec816", "files": 121 }, "hyperframes-audio": { @@ -34,7 +34,7 @@ "files": 11 }, "hyperframes-core": { - "hash": "033a6c675e66a5e7", + "hash": "c97f8f9221cf7396", "files": 20 }, "hyperframes-creative": { @@ -70,7 +70,7 @@ "files": 29 }, "remotion-to-hyperframes": { - "hash": "79fcf8e9641d126e", + "hash": "1c32548c47eb34c7", "files": 70 }, "slideshow": { @@ -78,7 +78,7 @@ "files": 2 }, "talking-head-recut": { - "hash": "2eaa83d6889537a5", + "hash": "cd9f5efc39afa67d", "files": 28 } } diff --git a/skills/embedded-captions/modes/standard/_anatomy.md b/skills/embedded-captions/modes/standard/_anatomy.md index 0eb3fa0232..74a0e9a207 100644 --- a/skills/embedded-captions/modes/standard/_anatomy.md +++ b/skills/embedded-captions/modes/standard/_anatomy.md @@ -17,7 +17,7 @@ HyperFrames-native, so anyone can reproduce it: - **One paused GSAP timeline per composition**, registered to `window.__timelines[data-composition-id]`. - All timing in **seconds**; `data-start` / `data-duration` carry the scene window. -- **Deterministic + seek-safe** only — no `Math.random()`, no `Date.now()`, no infinite repeats, no un-seekable CSS animations. Every state is reachable by seeking the timeline to a time `t`. +- **Deterministic + seek-safe** only — no `Math.random()`, no `Date.now()`, no `repeat: -1` without a finite root `data-duration`, no un-seekable CSS animations. Every state is reachable by seeking the timeline to a time `t`. - GSAP transform aliases (`x`, `y`, `scale`, `rotation`); animate `opacity`, `filter`, `clipPath`, `textShadow`, `backgroundPosition`, `letterSpacing` — never layout props (width/top/left/margin). For the composition contract see `hyperframes-core`; eases + the animated-property allowlist see `hyperframes-gsap`; caption grouping/positioning/exit guarantees see `hyperframes-captions`. @@ -218,7 +218,7 @@ The gallery used a `setInterval` loop; HyperFrames needs the same beats as **abs - Timeline **paused**; registry key = `data-composition-id`. - **No CSS keyframe animation** on caption elements — all motion is GSAP tweens at absolute times (seek-safe). -- No `Math.random` / `Date.now` / infinite repeats. +- No `Math.random` / `Date.now` / `repeat: -1` without a finite root `data-duration`. - `display:inline-block` on every `.w` and the climax `span`. - **Hard-hide** each flow group at its end time; **CLIMAX_OUT ends at `opacity:0`** (or fully-clipped) so nothing lingers. - Gradient / `background-clip:text` / stroke fills go on `.climax span`, not the transformed `.climax`. diff --git a/skills/figma/SKILL.md b/skills/figma/SKILL.md index c611e24f5f..6d099d9da7 100644 --- a/skills/figma/SKILL.md +++ b/skills/figma/SKILL.md @@ -129,4 +129,4 @@ Storyboard files follow a grammar you can parse mechanically — don't eyeball, ## Determinism -Never leave a Figma URL in the composition — freeze first. Never emit `repeat: -1`. Timelines paused, finite, literal `window.__timelines` keys. All Figma I/O at import time; render sees local files only. +Never leave a Figma URL in the composition — freeze first. Never emit `repeat: -1` without a finite root `data-duration`. Timelines paused, finite, literal `window.__timelines` keys. All Figma I/O at import time; render sees local files only. diff --git a/skills/hyperframes-animation/SKILL.md b/skills/hyperframes-animation/SKILL.md index 00aaaeed5c..a3ce0a80fb 100644 --- a/skills/hyperframes-animation/SKILL.md +++ b/skills/hyperframes-animation/SKILL.md @@ -59,7 +59,7 @@ Multiple runtimes can coexist in one composition. Each registers its instances o ## Critical Constraints -**Prerequisite: `hyperframes-core` → Non-Negotiable Rules** (single paused timeline, `data-duration` governs length, no `Math.random` / `Date.now` / `performance.now`, no `repeat: -1`, no page-load `gsap.set` on later-scene clips, no `display` or raw `visibility` tweens, and no timeline construction inside `async` / `setTimeout` / `Promise`). GSAP `autoAlpha` and zero-duration visibility sets at explicit timeline boundaries remain allowed by core. Use those exceptions only on non-clip elements or wrappers inside a clip; the framework owns `.clip` lifecycle. Don't restate the full contract here. +**Prerequisite: `hyperframes-core` → Non-Negotiable Rules** (single paused timeline, `data-duration` governs length, no `Math.random` / `Date.now` / `performance.now`, no `repeat: -1` without a finite root `data-duration`, no page-load `gsap.set` on later-scene clips, no `display` or raw `visibility` tweens, and no timeline construction inside `async` / `setTimeout` / `Promise`). GSAP `autoAlpha` and zero-duration visibility sets at explicit timeline boundaries remain allowed by core. Use those exceptions only on non-clip elements or wrappers inside a clip; the framework owns `.clip` lifecycle. Don't restate the full contract here. Animation-craft additions on top of core's contract: diff --git a/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md b/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md index 98256c8560..504b9256a1 100644 --- a/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +++ b/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md @@ -16,7 +16,7 @@ tl.to(".a", { x: 100 }).to(".b", { y: 50 }).to(".c", { opacity: 0 }); Timeline options: - **paused: true** — required in HyperFrames. The framework drives the playhead. -- **repeat**, **yoyo** — apply to the whole timeline. `repeat: -1` is forbidden; use finite counts. +- **repeat**, **yoyo** — apply to the whole timeline. `repeat: -1` requires a finite root `data-duration` (export clips to it); otherwise use finite counts. - **defaults** — vars merged into every child tween. Use this instead of repeating `ease` and `duration` on every line. ## Position Parameter diff --git a/skills/hyperframes-animation/adapters/gsap.md b/skills/hyperframes-animation/adapters/gsap.md index 6638706693..df3ec4f068 100644 --- a/skills/hyperframes-animation/adapters/gsap.md +++ b/skills/hyperframes-animation/adapters/gsap.md @@ -96,7 +96,7 @@ HyperFrames is stricter than vanilla GSAP. Animate only: - Use both `svgOrigin` and `transformOrigin` on the same SVG element. - Chain animations with `delay` when a timeline can sequence them. - Create tweens before the DOM exists. -- Use infinite `repeat: -1` in HyperFrames compositions — use finite repeat counts computed from the visible duration. +- Use infinite `repeat: -1` without a finite root `data-duration` (with one, export clips to that window); when a loop must end before the composition does, use a finite repeat count computed from the visible duration. ## Credits And References diff --git a/skills/hyperframes-animation/rules-index.md b/skills/hyperframes-animation/rules-index.md index 8568d22791..48327c8840 100644 --- a/skills/hyperframes-animation/rules-index.md +++ b/skills/hyperframes-animation/rules-index.md @@ -8,7 +8,7 @@ Stated once here so individual rules don't repeat it. Every recipe in `rules/`: - runs on ONE **paused** GSAP timeline registered on `window.__timelines` (never autoplay, never a second timeline); - is **seek-safe both directions**: `fromTo` with explicit from-states (t=0 correct under seek; `immediateRender: false` when re-owning a target), absolute values — never relative `+=` tweens; state readable as a pure function of timeline time, no mutable trackers; -- is **deterministic**: no `Math.random()`, no `Date.now()` — index-derived pseudo-random and baked schedules only; finite repeats, never `repeat: -1`; +- is **deterministic**: no `Math.random()`, no `Date.now()` — index-derived pseudo-random and baked schedules only; finite repeats (`repeat: -1` only under a finite root `data-duration`); - animates **transforms and paint-only properties** — `width`/`height`/`top`/`left` tweens are forbidden (use scale/translate proxies, masks, or `anchored-layout-expand`); - caps group staggers so an arrival reads as one beat (`items × stagger ≤ ~0.5s`); - puts **no CSS `transition`** on animated elements (they interpolate independently of seek and flicker) and hints compositors with `will-change: transform` where many tweens run at once; diff --git a/skills/hyperframes-core/SKILL.md b/skills/hyperframes-core/SKILL.md index 64268b4a33..bf17fe4567 100644 --- a/skills/hyperframes-core/SKILL.md +++ b/skills/hyperframes-core/SKILL.md @@ -69,7 +69,7 @@ A lint **error** also switches off the layout and contrast audits: `check` then 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` +- No render-time clocks / unseeded `Math.random` / network / input-state; `repeat: -1` only under a finite root `data-duration` (export clips to it — otherwise use a finite count). → `determinism-rules.md` - Never tween `display` or raw `visibility` on a clip element. The framework owns clip visibility, and `lint` rejects it. Use GSAP `autoAlpha` or a zero-duration boundary `set`. (Tweening ordinary visual properties on a clip element is fine; what lint forbids is taking over its visibility.) → `determinism-rules.md` - No `
` in body text; transformed elements must be block-level + sized; pulsing absolute decoratives need peak clearance. → `determinism-rules.md` - `