Skip to content

docs(website-to-hyperframes): add load-bearing GSAP authoring rules#364

Open
ibrews wants to merge 1 commit intoheygen-com:mainfrom
ibrews:skill-load-bearing-gsap-rules
Open

docs(website-to-hyperframes): add load-bearing GSAP authoring rules#364
ibrews wants to merge 1 commit intoheygen-com:mainfrom
ibrews:skill-load-bearing-gsap-rules

Conversation

@ibrews
Copy link
Copy Markdown

@ibrews ibrews commented Apr 21, 2026

Summary

Adds a new Load-bearing rules for animation authoring subsection to skills/website-to-hyperframes/references/step-6-build.md, capturing five GSAP authoring rules the linter cannot catch but that silently ship broken output — compositions that pass lint and render elements invisible, unscrubbing, or frozen.

Evidence

Surfaced from two independent website-to-hyperframes builds on 2026-04-20:

  • spatial-deck/promo/hyperframes-auto/ — single-page SPA source
  • ~/harvardxr-auto/ — marketing-site source

Both lint-clean on the first try. Both rendered cleanly only because we injected these rules into the sub-agent prompt before dispatch. Without them, sub-agents produced lint-passing compositions with:

  • Hero images that entered then vanished (stacked y-entrance + scale Ken Burns tweens on one element)
  • Auras that looked right in the studio preview but were missing from the rendered MP4 (standalone gsap.to() that didn't scrub)
  • Scene transitions where elements flashed visible before their own entrance (gsap.from() immediateRender interacting with .clip boundaries)

Rules added

  1. No iframes for captured content — don't seek deterministically, cannot scrub.
  2. Never stack two transform tweens on one element — the second tween's immediateRender resets the first, element ends up invisible. With before/after code showing two fixes (combine into one fromTo, or split across parent/child wrappers).
  3. Prefer tl.fromTo() over tl.from() inside .clip scenesfrom()'s default immediateRender: true writes state before the scene's data-start is active and misbehaves under non-linear seeking.
  4. Ambient pulses must attach to the seekable tl, never bare gsap.to() — standalone tweens run on wallclock, don't scrub, absent from rendered output.
  5. Generalize the existing caption hard-kill rule to every scene-boundary exit — any element whose visibility changes at a beat boundary needs the deterministic tl.set() kill after its fade, not just captions.

Rules already present in the file (repeat: -1, data-start/data-duration on template roots, caption hard-kill) are untouched — these five are net-new or are generalizations.

Related observations (not in this PR, flagging for maintainers)

Two adjacent findings from the same builds, worth filing separately if you want them tracked:

  • Linter heuristic inconsistency. Identical hard-kill patterns at beat boundaries trigger overlapping_gsap_tweens on some builds but not others. Stabilizing this heuristic would remove a source of sub-agent confusion.
  • step-1-capture.md thin output on canvas-driven / deck-style sources. Single-page apps that navigate via keyboard or internal state produce sections: 0, CTAs: 0, scroll-screenshots: 1. A --deck-mode flag that navigates via keyboard and captures per-state — or a documented pre-seed-screenshots workaround — would help.

Happy to open either as a separate issue if useful.

Test plan

  • Render the diff locally and confirm markdown formatting is consistent with the rest of step-6-build.md (code fences, hyphen bullets, em-dashes).
  • Optional: re-run the website-to-hyperframes skill against a test site with these rules present vs. absent — the "ambient pulse doesn't scrub" failure is the easiest to reproduce.

Add five animation-authoring rules to step-6-build.md that the linter
cannot catch but that silently ship broken output. Surfaced from two
independent builds (2026-04-20) where compositions passed lint and
still rendered elements invisible / unscrubbing.

Rules added:
- No iframes for captured content (don't scrub)
- Never stack transform tweens on one element (entrance + Ken Burns
  on same img silently kills it)
- Prefer tl.fromTo() over tl.from() inside .clip scenes
  (immediateRender interacts badly with scene boundaries)
- Ambient pulses must attach to seekable tl, not standalone gsap.to()
- Generalize the caption hard-kill rule to every scene-boundary exit
@jrusso1020 jrusso1020 requested a review from ukimsanov April 21, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant