feat: HyperFrames-grade video design bar — vendored craft references + catalog vocabulary (#550)

* feat(motion): demo-register visual design bar, vendored craft references, catalog vocabulary index

* fix(motion): correct design-bar composition claims after adversarial fact-check

* docs(map,rag): design-bar, vendored references, and catalog index on the video-engine surfaces

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
Renzo F
2026-07-18 00:46:01 +02:00
committed by GitHub
co-authored by Renn F
parent c5dfbf6063
commit c9c1f62981
10 changed files with 675 additions and 2 deletions
+13 -1
View File
@@ -36,6 +36,18 @@ This composition is the library's reference point — match its restraint, don't
- **Layout** — anchor content asymmetrically (this clip sits in the lower two-thirds, left-aligned); avoid a perfectly centered card, which reads as a generic template rather than a designed frame.
- **AI tells to avoid** — no default AI-purple gradient wash, no centered-everything, no emoji as design elements, no one-font-one-size, no em dash in on-screen copy (voiceover script, highlight bullets, kicker text) or filler verbs ("Elevate", "Seamless", "Unleash", "Next-Gen").
## Visual design bar (demo/kit register)
The design bar above governs the text-card register; `kit/` pieces answer to the same restraint, but the tells are different — a demo clip fails by looking like a slide deck wearing the panel's colors, not by looking like a marketing card. Ground every rule below in the actual `pk-*` classes (`kit/kit.css`) and the shipped release compositions before inventing a new pattern; the vendored craft references now living in `skills/references/` (see the Cinematography section below) back every rule here with the underlying design theory.
- **Spacing and hierarchy** — `pk-column`'s 56px left inset is fixed, and the kit's card padding (32px/36px) and title size (34px) are the vertical-cut baseline — square cuts legitimately tighten them per orientation (`release-0.25.0/square.html` runs 18px/24px padding and a 28px title), but that's a per-orientation override, never a per-beat one. Don't crowd a second full card into the same beat just because there's vertical room: `release-0.25.0` gives each card its own ~5s scene, and `release-recap` caps its visible stack at three compact cards with tight margins. A card's own internal rhythm (title, a gap, the chip row, another gap, the status pill) is load-bearing — don't add a second meta row or a second pill just to fill space.
- **Beat density and pacing variation** — identical entrance intervals across many beats (every 5.0s via `animation-delay`, as `release-0.25.0`'s cards do — beats ride delayed CSS animations, never `data-start` clip windows; see the clip-window rule below) are fine for a receipt-style listing where the viewer is meant to learn the rhythm, but the entrance itself must still vary: swap `--pk-ease` for a springy overshoot (`cubic-bezier(0.34, 1.4, 0.64, 1)`, as `release-0.25.0` does on its cards) on at least one beat type so the library doesn't share byte-identical timing everywhere. Past ~4 evenly-spaced beats the interval itself starts to read metronomic — vary it, or break the pattern with a different-shaped beat (a receipt, a stat overlay) before the count gets there.
- **Chip and pill color-variant discipline** — `pk-pill` variants are STATUS-semantic (`progress`/`review`/`approved`/`completed` map onto real lifecycle states); never pick one for how it looks against the frame. `pk-chip` variants are CATEGORY-semantic — reuse the same variant for the same real-world category across a whole clip (and across the library), rather than rotating colors per beat for visual variety. A frame carrying four-plus chip colors with no categorical reason reads decorative, not designed.
- **Camera + cursor + beat rhythm reading as filmed** — treat each card's build (entrance), breathe (pill hold while the camera settles or pushes), and resolve (pill swap, cursor click) as its own three-phase unit, and point `pk-camera`'s `data-shots` at whichever card is actually completing rather than a fixed frame the beats happen to pass through — `release-0.25.0`'s shot list re-centers on each card in turn. Chain `pk-cursor` waypoints with room for the idle-hand sway (`kit.js`) to run between legs; a cursor that jumps beat to beat with zero rest reads like a pointer teleporting, not a hand moving.
- **Anti-generic tells** — a uniform grid of same-size cards with no hierarchy difference (reach for a one-card-per-scene sequence like `release-0.25.0`, or `release-recap`'s compact three-card stack, instead); the same ease and duration on every entrance across a whole clip (`skills/references/motion-principles.md`'s "same ease on every tween" guardrail is a CSS problem too, not just a GSAP one); and decorative motion with no product meaning — `pk-frame__statusdot`'s pulse earns its place because "Live" really is pulsing, but a second unrelated glow added only to fill a frame doesn't.
For visual vocabulary beyond what `kit/` covers today, see `skills/hyperframes-catalog-index.md` — it names which effects map onto an existing `pk-*` piece and which would need a new one.
## Cinematography & rhythm (demo register)
A panel-demo clip is a FILM of software being used, not a screenshot with captions. Before authoring, write a shot list: for every beat, where is the camera, where is the cursor, what changes on screen, and what caused it. Then build to it. The specific tells that get a cut bounced:
@@ -44,7 +56,7 @@ A panel-demo clip is a FILM of software being used, not a screenshot with captio
- **A cursor that doesn't behave like a hand.** Drive it with `data-waypoints`: it fades in, travels with eased legs, rests with an idle sway (kit adds this), clicks with a visible cause→effect (the click precedes the thing it triggers), and leaves the frame — it never pops in, freezes pixel-still, or blinks out mid-scene.
- **A metronome.** Identical beat lengths with identical flat entrances read as a slideshow. Vary entrance energy (the kit cards take a springy overshoot well), let a beat breathe after a click, and give the climax (stats/receipt) a different rhythm than the build.
- **Verify motion, not stills.** After `request_render`, sample PAIRS of frames ~0.5s apart around each cursor/camera beat and compare positions — a single frame proves presence, only a pair proves movement.
- **The vendor's authoring doctrine is vendored in `skills/`.** Read `skills/hyperframes-core.md` (composition contract), `skills/hyperframes-keyframes.md` (seek-safe keyframes across runtimes), and `skills/hyperframes-creative.md` (beat planning) before authoring — they are the official HyperFrames agent skills, vendored at a pinned upstream commit (Apache-2.0, header in each file; re-vendor when bumping `@hyperframes/producer`). Note the vendor's primary seek-safe animation primitive is GSAP tweens registered on `window.__timelines` — this kit's CSS-animation register is a house pattern, and the clip-window rule below is its empirically-derived seek-safety companion.
- **The vendor's authoring doctrine is vendored in `skills/`.** Read `skills/hyperframes-core.md` (composition contract), `skills/hyperframes-keyframes.md` (seek-safe keyframes across runtimes), and `skills/hyperframes-creative.md` (beat planning) before authoring — they are the official HyperFrames agent skills, vendored at a pinned upstream commit (Apache-2.0, header in each file; re-vendor when bumping `@hyperframes/producer`). `skills/hyperframes-creative.md` in turn points at `skills/references/house-style.md`, `video-composition.md`, `beat-direction.md`, and `motion-principles.md` — four of its own reference docs, vendored the same way, that cover palette/lazy-defaults, video-medium scale and density, per-beat rhythm planning, and ease/speed/direction variance in more depth than the summary above. Note the vendor's primary seek-safe animation primitive is GSAP tweens registered on `window.__timelines` — this kit's CSS-animation register is a house pattern, and the clip-window rule below is its empirically-derived seek-safety companion.
- **Clip windows are for structural layers only.** The renderer's per-clip visibility scheduler drifts badly behind the encoded timeline on long compositions (measured live: a 40s cut whose per-beat clips only reached the ~19s mark by the final frame — the entire tail silently missing from the MP4). Give `class="clip"` + `data-start`/`data-duration` only to full-length structural layers (the cold-open, the panel frame), and drive every BEAT inside them with the kit's pattern instead: base-hidden styles (`opacity: 0`) plus a delayed CSS animation (`animation-delay` + `forwards`/`both` fill) — those run on the correct clock. If a beat must also disappear, give it an exit animation, not a clip window.
## Panel-demo kit (`kit/`)
+4
View File
@@ -21,6 +21,10 @@ Every class is namespaced `pk-`. See `compositions/panel-demo/` for a full worke
- **`pk-cursor`** — a small CSS-shape cursor (`pk-cursor__glyph`). Preferred: give it `data-waypoints="t x y [click]; t x y; ..."` (composition-absolute seconds, content-box px) and call `PanelKit.choreographAllCursors()` in the composition's inline script — kit.js generates a multi-leg eased path, a fade-in/out (never pop in or blink out), an idle-hand sway between legs, and a click ring + glyph press dip at every waypoint flagged `click`. The click should land ~0.2s BEFORE the thing it visually triggers. Legacy single-glide via `--pk-cursor-x0/y0/x1/y1` + `--pk-cursor-delay`/`--pk-click-delay` still works for a one-move cameo.
- **`pk-camera`** — a full-stage wrapper driven by `data-shots="t x y scale; ..."` + `PanelKit.choreographAllCameras()`: eased camera moves (push-ins toward the beat's focal point, pull-backs for reveals). Wrap the whole `pk-frame` in one; everything inside, cursor included, rides the move. Keep it subtle — `scale <= 1.08`, translate <= ~160px — and end settled at identity.
## Reaching for a catalog-grade beat
`kit/kit.css` already has the piece for most beats: a `pk-chip` for a one-word category tag, a `pk-pill` for a lifecycle status (never the other way around — see "Chip and pill color-variant discipline" in `motion/README.md`'s Visual design bar section), a `pk-card` when the beat is about one real thing gaining detail over time, and a `pk-toast` for a one-shot confirmation that shouldn't compete with the column. When a brief wants a look nothing here covers — a code diff, a chart, a device 3D showcase — check `motion/skills/hyperframes-catalog-index.md` for the closest public HyperFrames reference before improvising a one-off composition-local hack; it also says which effects already map onto `pk-*` and which would need a genuinely new kit piece (a normal dev task, not a composition workaround).
## Offline constraints (same as every composition)
No CDN, no npm runtime deps, no bundler — plain files only, loaded via relative paths (`../../kit/...` from a composition two levels down). Fonts are the vendored `motion/public/fonts/*.woff2`, loaded via `@font-face` in `kit.css`. Motion is CSS keyframes timed with `animation-delay` (seconds from frame 0 — no `requestAnimationFrame`, no `Date.now()`), so a render is frame-deterministic.
+186
View File
@@ -0,0 +1,186 @@
# HyperFrames catalog index
RoboCo-authored reference index of the public HyperFrames catalog (`https://hyperframes.heygen.com`, machine index `llms.txt`, fetched 2026-07-17) — 109 blocks + 24 components, 133 entries total, grouped below by kind. This is design vocabulary to study and EMULATE with the RoboCo kit (`motion/kit/`), not a list of installable dependencies: none of this is vendored code, `npx hyperframes add` is not part of this repo's toolchain, and the offline-render constraint (no CDN, no npm runtime deps — see `motion/kit/README.md`) still applies to every composition regardless of what inspired it. Read this file on demand when planning a beat that needs more visual range than the current `pk-*` pieces cover; it is not injected into any agent prompt.
## How to use this index
- Skim the category you need, find a slug whose description matches the beat you're planning, then ask: does an existing `pk-*` piece already cover this look, or does it need a new one?
- **Maps onto existing kit pieces.** Most caption styles, lower-thirds, and social overlays describe a LOOK a `pk-card`/`pk-pill`/`pk-toast`/`pk-outro` variant could already achieve with a new modifier class or animation curve. Before writing new CSS, check `motion/kit/kit.css` and the "Visual design bar" section in `motion/README.md` for the closest existing pattern to extend rather than a one-off composition-local hack.
- **Maps onto the choreography engines.** Camera pushes/pulls (`pk-camera` + `data-shots`) and cursor travel (`pk-cursor` + `data-waypoints`) already cover most "reads as filmed" and "cursor behaves like a hand" needs the shader/transition entries below gesture at; a CSS crossfade or hard cut between `.clip` layers is usually enough for a scene change. Reach for a shader transition only when a composition genuinely needs a GPU effect no CSS transform can fake — and note the shader packages themselves are not vendored here, only the idea of what they look like.
- **Needs a new kit piece.** Code blocks, charts/flowcharts, maps, VFX, and liquid-glass/3D-device blocks have no RoboCo kit equivalent today. If a brief genuinely needs one — a code-diff beat for a dev-tooling release clip, say — that's a normal dev task: build a new `pk-*` piece under `motion/kit/kit.css` following the design bar in `motion/README.md`, not a composition-local hack. Don't reach for one of these categories to decorate a beat a `pk-card`/`pk-chip` variant would serve just as well — see "Anti-generic tells" in `motion/README.md`'s Visual design bar section.
- Full craft rules behind any of this (palette, density, motion, frame composition, rhythm planning) live in the vendored references at `references/``house-style.md`, `video-composition.md`, `beat-direction.md`, `motion-principles.md` — read those before choosing colors or timing for anything below.
## Catalog
### Code blocks (33) — VS Code / Apple Terminal theme skins + animated code effects
- `code-3d-extrude` (Code 3D Extrude) — Syntax-highlighted code on a lit, beveled 3D slab that rotates through real space and settles to a readable rest — true WebGL depth and lighting, not a 2D transform.
- `code-diff` (Code Diff) — An edit shown as a colored diff — removed lines collapse in red, added lines expand in green.
- `code-highlight` (Code Highlight Sweep) — A highlight band sweeps across a target line while the surrounding context dims — draws the eye to one line. `line` is 0-based: `line: 1` targets the second displayed line (unlike code-scroll, whose target is 1-based).
- `code-morph` (Code Morph) — One snippet transforms into another — tokens glide between positions, leavers fade out, enterers fade in. Shiki Magic Move re-driven as a paused GSAP timeline.
- `code-particle-assemble` (Code Particle Assemble) — Thousands of GPU points scatter through space and fly to the exact glyph pixels of the code, resolving into readable syntax-highlighted text — a particle system, not a token tween.
- `code-scroll` (Code Scroll To Line) — The camera scrolls a long file to bring a target line to center and spotlights it — for walking through real modules.
- `code-shader-dissolve` (Code Shader Dissolve) — The code compiles into existence: a GPU fragment shader resolves it out of seeded noise with a chromatic dissolve front and edge glow, then holds crisp.
- `code-snippet-flight` (Code Snippet Flight) — Discrete code snippets fly in from the side and assemble into a stacked program, staggered. Block-level FLIP.
- `code-typing` (Code Typing) — Token-streamed typing reveal with a caret that tracks the frontier — deterministic, no CSS animation.
- `code-snippet-dark-2026` (Dark 2026) — The newest VS Code dark theme with refined token scopes and updated palette.
- `code-snippet-dark-modern` (Dark Modern) — The default dark theme — clean and contemporary with comfortable contrast.
- `code-snippet-dark-plus` (Dark+) — Classic dark theme with enhanced syntax highlighting for popular languages.
- `code-snippet-high-contrast` (High Contrast) — Maximum contrast dark theme for accessibility.
- `code-snippet-high-contrast-light` (High Contrast Light) — Maximum contrast light theme for accessibility.
- `code-snippet-light-2026` (Light 2026) — The newest VS Code light theme with refined token scopes and updated palette.
- `code-snippet-light-modern` (Light Modern) — The default light theme — a fresh, modern take on the classic VS light experience.
- `code-snippet-light-plus` (Light+) — Classic light theme with enhanced syntax highlighting for popular languages.
- `code-snippet-monokai` (Monokai) — The iconic warm-toned dark theme beloved by developers worldwide.
- `code-snippet-solarized-light` (Solarized Light) — Ethan Schoonover's precision-engineered light color scheme.
- `code-snippet-visual-studio-dark` (Visual Studio Dark) — The traditional Visual Studio dark color scheme.
- `code-snippet-visual-studio-light` (Visual Studio Light) — The traditional Visual Studio light color scheme.
- `code-snippet-apple-terminal-basic` (Apple Terminal Basic) — Apple Terminal Basic profile with white background and black text, per-character typing animation.
- `code-snippet-apple-terminal-clear-dark` (Apple Terminal Clear Dark) — Apple Terminal Clear Dark profile with semi-transparent dark background and white text, per-character typing animation.
- `code-snippet-apple-terminal-clear-light` (Apple Terminal Clear Light) — Apple Terminal Clear Light profile with semi-transparent white background and black text, per-character typing animation.
- `code-snippet-apple-terminal-grass` (Apple Terminal Grass) — Apple Terminal Grass profile with black background and bright green text, per-character typing animation.
- `code-snippet-apple-terminal-homebrew` (Apple Terminal Homebrew) — Apple Terminal Homebrew profile with black background, bright green text and lime cursor, per-character typing animation.
- `code-snippet-apple-terminal-man-page` (Apple Terminal Man Page) — Apple Terminal Man Page profile with pale yellow background and black text, per-character typing animation.
- `code-snippet-apple-terminal-novel` (Apple Terminal Novel) — Apple Terminal Novel profile with warm parchment background and dark brown text, per-character typing animation.
- `code-snippet-apple-terminal-ocean` (Apple Terminal Ocean) — Apple Terminal Ocean profile with deep blue background and white text, per-character typing animation.
- `code-snippet-apple-terminal-pro` (Apple Terminal Pro) — Apple Terminal Pro profile with black background, grey text and lime green cursor, per-character typing animation.
- `code-snippet-apple-terminal-red-sands` (Apple Terminal Red Sands) — Apple Terminal Red Sands profile with deep red background and sandy text, per-character typing animation.
- `code-snippet-apple-terminal-silver-aerogel` (Apple Terminal Silver Aerogel) — Apple Terminal Silver Aerogel profile with dark grey background and white text, per-character typing animation.
- `code-snippet-apple-terminal-solid-colors` (Apple Terminal Solid Colors) — Apple Terminal Solid Colors profile with deep purple background and white text, per-character typing animation.
### Shader transitions (14) — WebGL GPU scene-to-scene effects
- `chromatic-radial-split` (Chromatic Radial Split) — Shader transition with chromatic aberration radial split
- `cinematic-zoom` (Cinematic Zoom) — Shader transition with dramatic zoom blur
- `cross-warp-morph` (Cross Warp Morph) — Shader transition with cross-warped morphing
- `domain-warp-dissolve` (Domain Warp Dissolve) — Shader transition with fractal noise domain warping
- `flash-through-white` (Flash Through White) — Shader transition with white flash crossfade
- `glitch` (Glitch) — Shader transition with digital glitch artifacts
- `gravitational-lens` (Gravitational Lens) — Shader transition with gravitational lensing distortion
- `light-leak` (Light Leak) — Shader transition with cinematic light leak overlay
- `ridged-burn` (Ridged Burn) — Shader transition with ridged turbulence burn effect
- `ripple-waves` (Ripple Waves) — Shader transition with concentric ripple wave distortion
- `sdf-iris` (SDF Iris) — Shader transition with signed distance field iris reveal
- `swirl-vortex` (Swirl Vortex) — Shader transition with swirling vortex distortion
- `thermal-distortion` (Thermal Distortion) — Shader transition with heat haze thermal distortion
- `whip-pan` (Whip Pan) — Shader transition simulating a fast camera whip pan
### Transition showcase groups (13) — CSS transition families (non-shader)
- `transitions-3d` (3D Transitions) — Showcase of 3D perspective flip and rotate transitions
- `transitions-blur` (Blur Transitions) — Showcase of blur-based transitions between scenes
- `transitions-cover` (Cover Transitions) — Showcase of cover/uncover slide transitions
- `transitions-destruction` (Destruction Transitions) — Showcase of destructive break-apart transitions
- `transitions-dissolve` (Dissolve Transitions) — Showcase of dissolve and fade transitions
- `transitions-distortion` (Distortion Transitions) — Showcase of warp and distortion transitions
- `transitions-grid` (Grid Transitions) — Showcase of grid-based tile transitions
- `transitions-light` (Light Transitions) — Showcase of light-based glow and flash transitions
- `transitions-mechanical` (Mechanical Transitions) — Showcase of mechanical shutter and iris transitions
- `transitions-other` (Other Transitions) — Showcase of miscellaneous creative transitions
- `transitions-push` (Push Transitions) — Showcase of push and slide transitions
- `transitions-radial` (Radial Transitions) — Showcase of radial wipe and reveal transitions
- `transitions-scale` (Scale Transitions) — Showcase of scale and zoom transitions
### Charts / flowchart (3)
- `data-chart` (Data Chart) — Animated bar + line chart with staggered reveal, NYT-style typography, and value labels
- `flowchart` (Flowchart) — Animated decision tree with SVG connectors, sticky-note nodes, cursor interaction, and typing correction
- `flowchart-vertical` (Flowchart Vertical) — Portrait animated decision tree with SVG connectors, sticky-note nodes, cursor interaction, and typing correction
### Maps (6) — data-driven D3 map visualizations
- `spain-map` (Spain Map) — Animated Spain choropleth by autonomous community with staggered reveals and gradient legend — D3 conic conformal projection
- `us-map` (US Map) — Animated US choropleth map with staggered state reveals, value labels, and gradient legend — pure inline SVG with GSAP
- `us-map-bubble` (US Bubble Map) — Animated US bubble map with proportional city markers, value callouts, and connection lines — composable with us-map
- `us-map-flow` (US Flow Map) — Animated connection arcs between US cities over a base map — composable origin-destination flow visualization
- `us-map-hex` (US Hex Grid Map) — Animated hexagonal tile grid map — each state as an equal-weight hex with data fill and abbreviation label
- `world-map` (World Map) — Animated world choropleth with country-by-country reveal, tooltip labels, and rotating globe inset — D3 Natural Earth projection
### Liquid-glass / 3D-device blocks (8)
- `ios26-liquid-glass` (iOS 26 Liquid Glass Home Screen) — 3D iPhone with a normal iOS 26 home screen, liquid glass app icons, shader wallpaper, dock, and fluid glass notifications that drop from the status area onto a GLTF device model.
- `macos-tahoe-liquid-glass` (macOS Tahoe Liquid Glass Desktop) — 3D MacBook with a macOS Tahoe-style desktop, glass menu bar, Finder window, dock, and cinematic device camera move.
- `liquid-glass-context-menu` (Liquid Glass Context Menu) — Frosted glass context menu panel drifting over an aurora shader background
- `liquid-glass-media-controls` (Liquid Glass Media Controls) — Frosted glass media control panels spreading over an aurora shader background
- `liquid-glass-notification` (Liquid Glass Notification) — Frosted glass notification cards floating over an aurora shader background
- `liquid-glass-widgets` (Liquid Glass Widgets) — Frosted glass stat cards, showcase panel and pill chips over an aurora shader background
- `vfx-liquid-glass` (Liquid Glass) — VFX composition block
- `vfx-iphone-device` (iPhone & MacBook 3D Showcase) — Real GLTF iPhone 15 Pro Max and MacBook Pro models with live HTML-in-Canvas screen content, morphing glass lens, product review camera choreography, and 360° turntable.
### Lower-thirds (12)
- `lower-third-bild` (Lower Third — BILD Style) — News-style lower third with tight-fit text boxes: white headline bar with red drop-shadow, red sub-line with white drop-shadow.
- `lt-accent-underline` (Lower Third — Accent Underline) — Cardless lower third for footage overlay: name rises, an accent rule draws left-to-right, role fades in; text-shadowed for legibility
- `lt-bold-block` (Lower Third — Bold Block) — High-energy podcast lower third: solid dark block wipes in, uppercase name slams up, accent tag pops
- `lt-clean-bar` (Lower Third — Clean Bar) — Minimal white-card lower third for podcasts/interviews: accent tab, name + role, clip-wipe entrance
- `lt-color-block` (Lower Third — Color Block) — High-energy lower third: bold accent-color block slides in with overshoot, condensed name + mono role
- `lt-dark-card` (Lower Third — Dark Card) — Charcoal card lower third for bright footage: name, drawn accent underline, role; slide-up entrance
- `lt-kicker-name` (Lower Third — Kicker Name) — Cardless lower third with an accent eyebrow/kicker tag, heavy name, and a drawn baseline; for footage
- `lt-mask-reveal` (Lower Third — Mask Reveal) — Cardless lower third: an accent sweep crosses and clip-path-reveals a heavy name, role fades up; for footage
- `lt-side-rule` (Lower Third — Side Rule) — Cardless lower third with a vertical accent bar; condensed display name + mono role, text-shadowed for footage
- `lt-soft-pill` (Lower Third — Soft Pill) — Rounded white pill lower third for podcasts/interviews: status dot, name + role, scale-pop entrance
- `lt-stack-bars` (Lower Third — Stack Bars) — Two stacked bars: a dark name bar wipes from the left, an accent role bar wipes from the right
- `yt-lower-third` (YouTube Lower Third) — Animated YouTube subscribe lower third with avatar and channel info
### Social / device overlays (8)
- `instagram-follow` (Instagram Follow) — Animated Instagram follow overlay with profile card and follow button
- `tiktok-follow` (TikTok Follow) — Animated TikTok follow overlay with profile card and follow button
- `x-post` (X Post Card) — Animated X/Twitter post card overlay with engagement metrics
- `reddit-post` (Reddit Post Card) — Animated Reddit post card overlay with upvotes and comments
- `spotify-card` (Spotify Now Playing) — Animated Spotify now-playing card with album art and progress bar
- `macos-notification` (macOS Notification) — Animated macOS-style notification banner with app icon and message
- `news-ticker` (News Ticker) — Premium broadcast-style lower-third ticker with live label, headline ribbon, and scrolling news crawl.
- `ui-3d-reveal` (3D UI Reveal) — Perspective 3D reveal animation for UI elements
### VFX (5)
- `vfx-liquid-background` (Liquid Background) — Organic liquid simulation with vertex displacement on a subdivided plane. HTML content floats above rippling fluid surface with real-time wave dynamics.
- `vfx-magnetic` (Magnetic) — VFX composition block
- `vfx-portal` (Portal) — VFX composition block
- `vfx-shatter` (Shatter) — VFX composition block
- `vfx-text-cursor` (VFX Text Cursor) — Dramatic text reveal with cursor glow, chromatic shadow rays, and directional lighting on a black stage. Canvas-based shader post-processing with spectral color edges.
### Full demo compositions (7) — multi-beat narrative pieces, often with sound
- `app-showcase` (App Showcase) — Fitness app product showcase with three floating smartphone screens
- `apple-money-count` (Apple Money Count) — Apple-style finance counter that counts from $0 to $10,000, flashes green, and bursts money icons with sound.
- `blue-sweater-intro-video` (Blue Sweater Intro Video) — Warm AI creator intro sequence that resolves into an X follow card for @_blue_sweater_.
- `logo-outro` (Logo Outro) — Cinematic logo reveal with piece-by-piece assembly, glow bloom, tagline fade-in, and URL pill
- `north-korea-locked-down` (North Korea Locked Down) — Realistic map zoom into North Korea with a red scribble circle, locked-down pop-up label, and reddish editorial wash.
- `nyc-paris-flight` (NYC Paris Flight) — Apple-style realistic map animation with a plane flying from New York to Paris, marker circle, landing pop, and sound effects.
- `vpn-youtube-spot` (VPN YouTube Spot) — Snappy Apple-style YouTube insert showing a phone finding and installing a friendly VPN app with sound effects.
### Caption styles (16, components)
- `caption-blend-difference` (Blend Difference) — Auto-inverting text using mix-blend-mode: difference — flips between white and black per-pixel against the background
- `caption-clip-wipe` (Clip Wipe) — Left-to-right clip-path wipe reveal per word
- `caption-editorial-emphasis` (Editorial Emphasis) — Dual-font system with dramatic size contrast for emphasis words
- `caption-emoji-pop` (Emoji Pop) — Emoji integration with stroked text and horizontal squeeze entrance
- `caption-glitch-rgb` (Glitch RGB) — RGB chromatic aberration with CRT scanline overlay
- `caption-gradient-fill` (Gradient Fill) — Gradient-clipped text with elastic bounce entrance
- `caption-highlight` (Highlight) — Red background sweep behind each active word, TikTok-style
- `caption-kinetic-slam` (Kinetic Slam) — Full-screen single-word display with alternating entrance directions
- `caption-matrix-decode` (Matrix Decode) — Character scramble animation before text reveal
- `caption-neon-accent` (Neon Accent) — Multi-color neon glow accents with wiggle drift animation
- `caption-neon-glow` (Neon Glow) — Cyan and magenta neon glow with keyword accent colors
- `caption-parallax-layers` (Parallax Layers) — Behind-subject 3D text layering with vertical stretch effect
- `caption-particle-burst` (Particle Burst) — Keyword words trigger colored particle explosions
- `caption-pill-karaoke` (Pill Karaoke) — Pill-shaped container with per-word karaoke color highlight
- `caption-texture` (Texture) — Flowing texture mask over large uppercase text — ships with 6 textures (lava, marble, metal, wood, concrete, rock), configurable via the texture variable
- `caption-weight-shift` (Weight Shift) — Elegant font-weight transition between caption lines
### Text/overlay effect components (8)
- `grain-overlay` (Grain Overlay) — Animated film grain texture overlay using CSS keyframes — adds warmth and analog character to any composition
- `grid-pixelate-wipe` (Grid Pixelate Wipe) — Transition effect where the screen dissolves into a grid of squares that fade out with staggered timing — use between scenes
- `morph-text` (Morph Text) — Gooey text morph — cycles through an editable word list using SVG threshold + GSAP-driven blur for a fluid, satisfying transition effect
- `parallax-unzoom` (Parallax Unzoom) — Reveal transition — focus card scales down from full frame as siblings parallax in to form a grid (reverse of parallax-zoom)
- `parallax-zoom` (Parallax Zoom) — Center card scales up to fill the frame while siblings parallax outward — inspired by the eBay Playbook hero transition
- `shimmer-sweep` (Shimmer Sweep) — Animated light sweep across text or elements using a CSS gradient mask — ideal for AI accents and premium reveals
- `texture-mask-text` (Texture Mask Text) — Large display text filled with a swappable material mask (brick, rock, ground, wood, metal, lava); the general-purpose sibling of the caption-only Texture component.
- `vignette` (Vignette) — Cinematic radial vignette overlay using a pure-CSS gradient — darkens the edges to pull focus toward the center
## Coverage note
33 code + 14 shader transitions + 13 transition showcase groups + 3 charts/flowchart + 6 maps + 8 liquid-glass/3D-device + 12 lower-thirds + 8 social/device overlays + 5 VFX + 7 full demo compositions = 109 blocks. 16 caption styles + 8 text/overlay effect components = 24 components. 109 + 24 = 133, matching the verified catalog count. Category boundaries beyond the code/shader/transition/lower-third counts (which the upstream naming makes unambiguous) are this file's own judgment call, not an upstream taxonomy — re-derive from `https://hyperframes.heygen.com/llms.txt` if the catalog grows and this file goes stale.
+2
View File
@@ -7,6 +7,8 @@ name: hyperframes-creative description: Non-animation creative direction for Hyp
# HyperFrames Creative
<!-- RoboCo: house-style.md, video-composition.md, beat-direction.md, and motion-principles.md are vendored under motion/skills/references/ (see motion/README.md's Visual design bar section for the RoboCo-kit-specific reading of them). Every other `references/`, `palettes/`, `frame-presets/`, and `scripts/` path mentioned below is upstream-only and NOT vendored in this repo — treat this file's own row description as the guidance when a linked file doesn't exist here. -->
Brand, pacing, style, narration, and composition direction. Use after the technical contract from `hyperframes-core` is in place.
For motion patterns, scene blueprints, transitions, and CSS marker effects, use `hyperframes-animation` — this skill is intentionally non-animation.
+167
View File
@@ -0,0 +1,167 @@
<!-- Vendored from https://github.com/heygen-com/hyperframes (skills/hyperframes-creative/references/beat-direction.md @ 9d148d28, Apache-2.0).
Reference doc hyperframes-creative.md points at for non-trivial compositions. Re-vendor when bumping @hyperframes/producer, then run make reflow-docs (prose is reflowed to house style). -->
# Beat Direction
How to plan and direct individual scenes (beats) in a multi-scene composition. Read before writing any multi-scene video.
## Contents
- Per-beat direction
- Concept
- Mood direction
- Animation choreography
- Transition
- Depth layers
- SFX cues
- Rhythm planning
- Velocity-matched transitions
---
## Per-Beat Direction
Each beat is a WORLD, not a layout. Before writing CSS specs and GSAP instructions, describe what the viewer EXPERIENCES. The difference between a great storyboard and a mediocre one:
- **Mediocre:** "Dark navy background. '$1.9T' in white, 280px. Logo top-left. Wave image bottom-right."
- **Great:** "Camera is already mid-flight over a vast dark canvas. The gradient wave sweeps across the frame like aurora borealis — alive, shifting. '$1.9T' SLAMS into existence with such force the wave ripples in response. This isn't a slide — it's a moment."
The first describes pixels. The second describes an experience. Write the second, then figure out the pixels.
Each beat should have:
### Concept
The big idea for this beat in 2-3 sentences. What visual WORLD are we in? What metaphor drives it? What should the viewer FEEL? This is the most important part — everything else flows from it.
### Mood direction
Cultural and design references, not hex codes:
- "Geometric, rhythmic, precise. Think Josef Albers or Bauhaus color studies."
- "Warm workspace. Nice notebook energy, not technical blueprint."
- "Cinematic title sequence. The kind of opening where you lean forward."
### Animation choreography
Specific motion verbs per element — not "it animates in" but HOW. Verbs come from the beat's concept and content, not from an energy bucket. A wellness brand's "slow" beat might still have something that DROPS if the content is about letting go. A stats beat might FLOAT if the brand's identity is weightless.
The vocabulary of motion verbs (organized by physical character, not by energy level):
- **Impact / weight:** SLAMS, CRASHES, PUNCHES, STAMPS, SHATTERS, DROPS (with force)
- **Directional / deliberate:** SLIDES, PUSHES, PULLS, WIPES, CUTS
- **Reveals / builds:** DRAWS, FILLS, GROWS, EXPANDS, ASSEMBLES, COUNTS UP
- **Organic / ambient:** FLOATS, DRIFTS, BREATHES, PULSES, ORBITS, MORPHS
- **Mechanical / precise:** TYPES ON, CLICKS, LOCKS IN, SNAPS, STEPS
Every element gets a verb. If you can't name the verb, the element is not yet designed. The verb should follow from the beat's concept — not from a lookup of what "high energy" or "low energy" beats use.
For text elements specifically, you can name a deterministic, named effect by ID (e.g. `typewriter`, `kinetic-center-build`, `soft-blur-in`) instead of inventing timing from scratch — the 24-effect vocabulary and how to load it live in `skills/hyperframes-animation/adapters/animate-text.md`.
### Transition
How this beat hands off to the next. Specify the type and parameters.
**When to pick which:**
| Choose shader transition for | Choose CSS transition for | Choose hard cut for |
| ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Reveals, big reaction shots, product/logo unveils, energy shifts, "wow" moments | Continuous camera-motion beats where the scene feels like one move broken into cuts | Rapid-fire lists, percussive edits on the beat, comedic timing |
| Any moment the music/VO punctuates with a downbeat or SFX hit | Beats that ease from one composition into the next with shared motion vocabulary | Sequences of 3+ quick tempo-matched switches |
| Brand moments where the transition itself _is_ the visual | Minimal/editorial pacing | Anytime a 0.3-0.8s transition would feel too slow |
Rule of thumb: if the beat is the _centerpiece_ of the video, shader-transition into it. If the beat is connective tissue, a CSS crossfade is fine. A brand reel of 5-7 beats usually wants 1-2 shader transitions (the hero reveal + the CTA) — too many flatten their impact.
**Mixing shader and CSS crossfade transitions in one composition is supported.** Omit `shader` on any transition entry to get a smooth opacity crossfade — HyperShader manages all scene visibility regardless. Let HyperShader create the timeline (don't pass a pre-built `timeline:` option) and add all composition tweens to the returned `tl` after `init()`. Config snippet in `skills/hyperframes-animation/transitions/overview.md` → "CSS vs Shader".
**CSS transitions** — 30+ patterns across 13 categories. Full code in `skills/hyperframes-animation/transitions/` (route via `catalog.md`). Pick based on the energy and feel:
| Category | Patterns | Motion character |
| ------------------ | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
| **Push / slide** | Push slide, vertical push, elastic push, squeeze | Content moves through the frame as if on a continuous surface |
| **Scale / zoom** | Zoom through, zoom out | Perspective shifts — moving toward or away from content |
| **Radial / clip** | Circle iris, diamond iris, diagonal split | Geometric reveal — content emerges or is covered by a shape |
| **3D** | 3D card flip | Physical — content flips like a tangible object |
| **Dissolve** | Crossfade, blur crossfade, focus pull, color dip | Overlap and blend — both scenes exist simultaneously during the transition |
| **Cover / blinds** | Staggered color blocks, horizontal blinds (6/12 strips), vertical blinds | Structural — content is sliced, layered, or covered |
| **Light** | Light leak overlays, overexposure burn, film burn | Organic film — light bleeds across the frame |
| **Distortion** | Glitch (CSS RGB jitter), chromatic aberration, ripple, VHS tape | Instability — the image itself appears to malfunction |
| **Blur** | Blur through, directional blur | Soft defocus — content blurs in or out |
| **Mechanical** | Shutter (two-half), clock wipe (9-point wedge) | Precision — transitions with visible mechanical logic |
| **Grid** | Grid dissolve (12/120 cells) | Fragmentation — the frame breaks into pieces |
| **Destruction** | Page burn (SVG clip-path + canvas rim) | Dramatic decay — the previous scene is destroyed |
| **Other** | Gravity drop, morph circle | Physical or shape-based motion that doesn't fit other categories |
Common quick-picks:
- **Velocity-matched upward**: exit `y:-150, blur:30px, 0.33s power2.in` → entry `y:150→0, blur:30px→0, 1.0s power2.out`
- **Whip pan**: exit `x:-400, blur:24px, 0.3s power3.in` → entry `x:400→0, blur:24px→0, 0.3s power3.out`
- **Blur through**: exit `blur:20px, 0.3s` → entry `blur:20px→0, 0.25s power3.out`
- **Zoom through**: exit `scale:1→1.2, blur:20px, 0.2s power3.in` → entry `scale:0.75→1, blur:20px→0, 0.5s expo.out`
- **Hard cut / smash cut**: instant, for rapid-fire sequences
Timing presets: snappy (0.2s), smooth (0.4s), gentle (0.6s), dramatic (0.5s), instant (0.15s), luxe (0.7s).
**Shader transitions** — 14 built-in WebGL GPU effects. Install with `npx hyperframes add <name>` (block name ≠ shader name — see `skills/hyperframes-registry/references/discovery.md`); full API in `packages/shader-transitions/README.md`.
| Shader | Visual description | Duration range |
| ----------------------- | ---------------------------------------------------------------------------------------------- | -------------- |
| **domain-warp** | Organic FBM dissolve — both scenes warp toward each other with an accent flash at the midpoint | 0.50.8s |
| **ridged-burn** | Multifractal mask reveals the incoming scene through a burn ramp with sparks at the edge | 0.50.8s |
| **whip-pan** | 10-sample horizontal motion blur + lateral crossfade — reads like a camera pan between shots | 0.30.5s |
| **sdf-iris** | Circle SDF expands from center, with accent-tinted glow rings at the expanding edge | 0.50.7s |
| **ripple-waves** | Radial standing-wave UV displacement — content ripples outward as scenes cross | 0.61.0s |
| **gravitational-lens** | Pinch pull toward center + R/B chromatic separation — content bends inward then releases | 0.61.0s |
| **cinematic-zoom** | 12 RGB-offset radial zoom blur samples — motion streak radiating from center | 0.40.6s |
| **chromatic-split** | R/B radial channel shift outward, G fixed — channels separate then rejoin | 0.30.5s |
| **swirl-vortex** | CCW swirl with FBM noise — content spirals away and the new scene spirals in | 0.50.8s |
| **thermal-distortion** | Vertical sine + FBM horizontal displacement — heat-haze shimmer across the frame | 0.50.8s |
| **flash-through-white** | Fade through white midpoint — almost invisible at 0.01s, noticeable at 0.3s | 0.01s0.3s |
| **cross-warp-morph** | FBM vector field displaces both scenes; a third FBM biases the wipe direction | 0.50.8s |
| **light-leak** | Fixed off-frame light source with exponential falloff, warmth, and a ridge flare | 0.50.8s |
| **glitch** | Line displacement + RGB lateral split + scan modulation + posterization + flicker | 0.30.5s |
**You are not limited to what's listed here.** These are the built-in options, but you can and should:
- **Write custom GLSL shaders** from scratch for unique transition effects
- **Search online** for shader code (ShaderToy, GLSL Sandbox, GitHub) and adapt it
- **Build custom CSS transitions** that aren't in any category — combine clip-path, transforms, filters in new ways
- **Ask the user** to provide or find specific effects if you need something specialized
If the storyboard calls for an effect that doesn't exist yet — build it. The framework renders anything a browser can run.
### Depth layers
What's in foreground, midground, and background. Every beat should have at least 2 layers:
- "BG: dark navy fill + subtle radial glow. MG: stat cards with drop shadow. FG: brand logo bottom-right."
### SFX cues
What sounds at what moment:
- "On the capture pulse — a soft, warm analog shutter click."
- "Left side carries a faint low drone. On fold: drone cuts. Silence. Then a single clean chime."
---
## Rhythm Planning
Before writing HTML, declare your scene rhythm: which scenes are quick hits, which are holds, where do shaders land, where does energy peak. Name the pattern — fast-fast-SLOW-fast-SHADER-hold — before implementing.
**Derive the rhythm from the storyboard and the brand, not from a lookup.** A 15-second social ad for an architectural firm and a 15-second social ad for a gaming brand have different rhythms — both are 15 seconds, but one is slow-reveal-hold-CTA and the other is rapid-fire-SLAM-hook. Video type sets constraints (duration, approximate beat count); the brand and content determine whether those beats are slow or fast, sparse or dense, dramatic or controlled.
Questions that drive rhythm decisions:
- What emotional journey should the viewer take? Where is the peak moment?
- Where does the narration land its heaviest emphasis? That's usually where energy should peak.
- What does the brand's own visual pacing suggest — unhurried or urgent?
- How many beats can the duration actually support without feeling rushed or padded?
A social ad that tries to hook in 2s, showcase 3 features, and end with a CTA in 15s will feel like noise. Sometimes "hook-hold-CTA" with one strong feature is the right rhythm for 15 seconds. Name the rhythm you've planned before implementing.
---
## Velocity-Matched Transitions
Exit the outgoing beat with an accelerating ease (power2.in or power3.in) plus a blur ramp. Enter the incoming beat with a decelerating ease (power2.out or power3.out) plus blur clear. The fastest point of both easing curves meets at the cut — the viewer perceives continuous camera motion, not two discrete animations. Match exit velocity to entry velocity within ~5% tolerance.
+76
View File
@@ -0,0 +1,76 @@
<!-- Vendored from https://github.com/heygen-com/hyperframes (skills/hyperframes-creative/references/house-style.md @ 9d148d28, Apache-2.0).
Reference doc hyperframes-creative.md points at for non-trivial compositions. Re-vendor when bumping @hyperframes/producer, then run make reflow-docs (prose is reflowed to house style). -->
# House Style
Creative direction for compositions when no design spec (`frame.md` or `design.md`) is provided. These are starting points — override anything that doesn't serve the content. When a design spec exists, its brand values take precedence; house-style fills gaps.
## Before Writing HTML
1. **Interpret the prompt.** Generate real content. A recipe lists real ingredients. A HUD has real readouts.
2. **Pick a palette.** Light or dark? Declare bg, fg, accent before writing code.
3. **Pick typefaces.** Run the font discovery script in [references/typography.md](references/typography.md) — or pick a font you already know that fits the theme. The script broadens your options; it's not the only source.
## Lazy Defaults to Question
These patterns are AI design tells — the first thing every LLM reaches for. If you're about to use one, pause and ask: is this a deliberate choice for THIS content, or am I defaulting?
- Gradient text (`background-clip: text` + gradient)
- Left-edge accent stripes on cards/callouts
- Cyan-on-dark / purple-to-blue gradients / neon accents
- Pure `#000` or `#fff` (tint toward your accent hue instead)
- Identical card grids (same-size cards repeated)
- Everything centered with equal weight (lead the eye somewhere)
- Banned fonts (see [references/typography.md](references/typography.md) for full list)
If the content genuinely calls for one of these — centered layout for a solemn closing, cards for a real product UI mockup, a banned font because it's the perfect thematic match — use it. The goal is intentionality, not avoidance.
## Color
- Match light/dark to content: food, wellness, kids → light. Tech, cinema, finance → dark.
- One accent hue. Same background across all scenes.
- Tint neutrals toward your accent (even subtle warmth/coolness beats dead gray).
- **Contrast:** enforced by `hyperframes check` (WCAG AA). Text must be readable with decoratives removed.
- Declare palette up front. Don't invent colors per-element.
## Background Layer
Every scene needs visual depth — persistent decorative elements that stay visible while content animates in. Without these, scenes feel empty during entrance staggering.
Ideas (mix and match, 2-5 per scene):
- Radial glows (accent-tinted, low opacity, breathing scale)
- Ghost text (theme words at 3-8% opacity, very large, slow drift)
- Accent lines (hairline rules, subtle pulse)
- Grain/noise overlay, geometric shapes, grid patterns
- Thematic decoratives (orbit rings for space, vinyl grooves for music, grid lines for data)
All decoratives should have slow ambient GSAP animation — breathing, drift, pulse. Static decoratives feel dead.
**Decorative count vs motion count.** The "2-5 per scene" count refers to decorative _elements_. If a project's design spec says "single ambient motion per scene", it means one looping motion applied to these decoratives (a shared breath/drift/pulse) — not one element total. A scene with 4 decoratives sharing one breathing motion is correct; a scene with 1 decorative is under-dressed.
## Motion
See [references/motion-principles.md](references/motion-principles.md) for full rules. Quick: 0.30.6s, vary eases, combine transforms on entrances, overlap entries.
## Typography
See [references/typography.md](references/typography.md) for full rules. Quick: 700-900 headlines / 300-400 body, serif + sans (not two sans), 60px+ headlines / 20px+ body.
## Palettes
Declare one background, one foreground, one accent before writing HTML.
| Category | Use for | File |
| ----------------- | --------------------------------------------- | ---------------------------------------------------------- |
| Bold / Energetic | Product launches, social media, announcements | [palettes/bold-energetic.md](palettes/bold-energetic.md) |
| Warm / Editorial | Storytelling, documentaries, case studies | [palettes/warm-editorial.md](palettes/warm-editorial.md) |
| Dark / Premium | Tech, finance, luxury, cinematic | [palettes/dark-premium.md](palettes/dark-premium.md) |
| Clean / Corporate | Explainers, tutorials, presentations | [palettes/clean-corporate.md](palettes/clean-corporate.md) |
| Nature / Earth | Sustainability, outdoor, organic | [palettes/nature-earth.md](palettes/nature-earth.md) |
| Neon / Electric | Gaming, tech, nightlife | [palettes/neon-electric.md](palettes/neon-electric.md) |
| Pastel / Soft | Fashion, beauty, lifestyle, wellness | [palettes/pastel-soft.md](palettes/pastel-soft.md) |
| Jewel / Rich | Luxury, events, sophisticated | [palettes/jewel-rich.md](palettes/jewel-rich.md) |
| Monochrome | Dramatic, typography-focused | [palettes/monochrome.md](palettes/monochrome.md) |
Or derive from OKLCH — pick a hue, build bg/fg/accent at different lightnesses, tint everything toward that hue.
@@ -0,0 +1,153 @@
<!-- Vendored from https://github.com/heygen-com/hyperframes (skills/hyperframes-creative/references/motion-principles.md @ 9d148d28, Apache-2.0).
Reference doc hyperframes-creative.md points at for non-trivial compositions. Re-vendor when bumping @hyperframes/producer, then run make reflow-docs (prose is reflowed to house style). -->
# Motion Principles
## Contents
- Guardrails
- What you do not do without being told
- Visual composition
- Image motion treatment
- Load-bearing GSAP rules
## Guardrails
You know these rules but you violate them. Stop.
- **Don't use the same ease on every tween.** You default to `power2.out` on everything. Vary eases like you vary font weights — no more than 2 independent tweens with the same ease in a scene.
- **Don't use the same speed on everything.** You default to 0.4-0.5s for everything. The slowest scene should be 3× slower than the fastest. Vary duration deliberately.
- **Don't enter everything from the same direction.** You default to `y: 30, opacity: 0` on every element. Vary: from left, from right, from scale, opacity-only, letter-spacing.
- **Don't use the same stagger on every scene.** Each scene needs its own rhythm.
- **Don't use ambient zoom on every scene.** Pick different ambient motion per scene: slow pan, subtle rotation, scale push, color shift, or nothing. Stillness after motion is powerful.
- **Don't start at t=0.** Offset the first animation 0.1-0.3s. Zero-delay feels like a jump cut.
## What You Don't Do Without Being Told
### Easing is emotion, not technique
The transition is the verb. The easing is the adverb. A slide-in with `expo.out` = confident. With `sine.inOut` = dreamy. With `elastic.out` = playful. Same motion, different meaning. Choose the adverb deliberately.
**Direction rules — these are not optional:**
- `.out` for elements entering. Starts fast, decelerates. Feels responsive. This is your default.
- `.in` for elements leaving. Starts slow, accelerates away. Throws them off.
- `.inOut` for elements moving between positions.
You get this backwards constantly. Ease-in for entrances feels sluggish. Ease-out for exits feels reluctant.
### Speed communicates weight
- Fast (0.15-0.3s) — energy, urgency, confidence
- Medium (0.3-0.5s) — professional, most content
- Slow (0.5-0.8s) — gravity, luxury, contemplation
- Very slow (0.8-2.0s) — cinematic, emotional, atmospheric
### Scene structure: build / breathe / resolve
Every scene has three phases. You dump everything in the build and leave nothing for breathe or resolve.
- **Build (0-30%)** — elements enter, staggered. Don't dump everything at once.
- **Breathe (30-70%)** — content visible, alive with ONE ambient motion.
- **Resolve (70-100%)** — exit or decisive end. Exits are faster than entrances.
### Transitions are meaning
- **Crossfade** = "this continues"
- **Hard cut** = "wake up" / disruption
- **Slow dissolve** = "drift with me"
You crossfade everything. Use hard cuts for disruption and register shifts.
### Choreography is hierarchy
The element that moves first is perceived as most important. Stagger in order of importance, not DOM order. Don't wait for completion — overlap entries. Total stagger sequence under 500ms regardless of item count.
### Asymmetry
Entrances need longer than exits. A card takes 0.4s to appear but 0.25s to disappear.
## Visual Composition
You build for the web. Video frames are not pages.
- **Two focal points minimum per scene.** The eye needs somewhere to travel. Never a single text block floating in empty space.
- **Fill the frame.** Hero text: 60-80% of width. You will try to use web-sized elements. Don't.
- **Three layers minimum per scene.** Background treatment (glow, oversized faded type, color panel). Foreground content. Accent elements (dividers, labels, data bars).
- **Background is not empty.** Radial glows, oversized faded type bleeding off-frame, subtle border panels, hairline rules. Pure solid #000 reads as "nothing loaded."
- **Anchor to edges.** Pin content to left/top or right/bottom. Centered-and-floating is a web pattern.
- **Split frames.** Data panel on the left, content on the right. Top bar with metadata, full-width below. Zone-based layouts, not centered stacks.
- **Use structural elements.** Rules, dividers, border panels. They create paths for the eye and animate well (scaleX from 0).
## Image Motion Treatment
Never embed a raw flat image. Every image must have motion treatment:
- **Perspective tilt**: use `gsap.set(el, { transformPerspective: 1200, rotationY: -8 })` + `box-shadow` — creates depth. Do NOT use CSS `transform: perspective(...)` as GSAP will overwrite it.
- **Slow zoom (Ken Burns)**: GSAP `scale: 1``1.04` over beat duration — makes photos cinematic
- **Device frame**: Wrap in a laptop/phone shape using CSS `border-radius` and `box-shadow`
- **Floating UI**: Extract a key element and animate it at a different z-depth for parallax
- **Scroll reveal**: Clip the image to a viewport window and animate `y` position
## Load-Bearing GSAP Rules
Rules below came out of two independent website capture builds (2026-04-20) where compositions lint-clean and still ship broken — elements that never appear, ambient motion that doesn't scrub, entrance tweens that silently kill their target. The linter cannot catch these; the rules must be followed by the author.
- **No iframes for captured content.** Iframes do not seek deterministically with the timeline — the capture engine cannot scrub inside them, so they appear frozen (or blank) in the rendered output. If the source you're stylizing is a live web app, use the screenshots from `capture/` as stacked panels or layered images, not live embeds.
- **Never overlap conflicting transform tweens on the same element.** Sequential, non-overlapping transform phases are valid. The dangerous case is concurrent tweens or `from()` tweens whose `immediateRender` states overwrite one another: for example, a `y` entrance plus a simultaneous `scale` Ken Burns tween on the same `<img>`. The element can remain invisible or offscreen with no lint warning. Fix the overlap in one of two ways:
```html
<!-- BAD: two transforms on one element -->
<img class="hero" src="..." />
<script>
tl.from(".hero", { y: 50, opacity: 0, duration: 0.6 }, 0);
tl.to(".hero", { scale: 1.04, duration: beat }, 0); // kills the entrance
</script>
<!-- GOOD option A: combine into one tween -->
<script>
tl.fromTo(
".hero",
{ y: 50, opacity: 0, scale: 1.0 },
{ y: 0, opacity: 1, scale: 1.04, duration: beat, ease: "none" },
0,
);
</script>
<!-- GOOD option B: split across parent + child -->
<div class="hero-wrap"><img class="hero" src="..." /></div>
<script>
tl.fromTo(".hero-wrap", { y: 50, opacity: 0 }, { y: 0, opacity: 1, duration: 0.6 }, 0); // entrance on parent
tl.to(".hero", { scale: 1.04, duration: beat }, 0); // Ken Burns on child
</script>
```
- **Prefer `tl.fromTo()` over `tl.from()` inside `.clip` scenes.** `gsap.from()` sets `immediateRender: true` by default, which writes the "from" state at timeline construction — before the `.clip` scene's `data-start` is active. Elements can flash visible, start from the wrong position, or skip their entrance entirely when the scene is seeked non-linearly (which the capture engine does). Explicit `fromTo` makes the state at every timeline position deterministic:
```js
// BRITTLE: immediateRender interacts badly with scene boundaries
tl.from(el, { opacity: 0, y: 50, duration: 0.6 }, t);
// DETERMINISTIC: state is defined at both ends, no immediateRender surprise
tl.fromTo(el, { opacity: 0, y: 50 }, { opacity: 1, y: 0, duration: 0.6 }, t);
```
- **Ambient pulses must attach to the seekable `tl`, never bare `gsap.to()`.** Auras, shimmers, gentle float loops, logo breathing — all of these must be added to the scene's timeline, not fired standalone. Standalone tweens run on wallclock time and do not scrub with the capture engine, so the effect is absent in the rendered video even though it looks correct in the studio preview:
```js
// BAD: lives outside the timeline, never renders in capture
gsap.to(".aura", { scale: 1.08, yoyo: true, repeat: 5, duration: 1.2 });
// GOOD: seekable, deterministic, renders
tl.to(".aura", { scale: 1.08, yoyo: true, repeat: 5, duration: 1.2 }, 0);
```
- **Hard-kill exiting inner elements at a scene boundary, not the `.clip` itself.** A non-clip element or wrapper whose visibility changes at a beat boundary may need a deterministic zero-duration `tl.set()` kill after its fade, because a later tween or sibling `immediateRender` can resurrect it. This is the explicit-boundary exception to the ban on raw `visibility` tweens. HyperFrames alone controls `.clip` lifecycle; never apply this pattern to the clip container.
```js
tl.to(innerEl, { opacity: 0, duration: 0.3 }, beatEnd);
tl.set(innerEl, { opacity: 0, visibility: "hidden" }, beatEnd + 0.3); // non-clip kill
```
These are the exact rules with the exact code examples — don't summarize or shorten them. They exist because compositions that lint clean still ship broken without them.
@@ -0,0 +1,66 @@
<!-- Vendored from https://github.com/heygen-com/hyperframes (skills/hyperframes-creative/references/video-composition.md @ 9d148d28, Apache-2.0).
Reference doc hyperframes-creative.md points at for non-trivial compositions. Re-vendor when bumping @hyperframes/producer, then run make reflow-docs (prose is reflowed to house style). -->
# Video Composition
Video frames are not web pages. Use these rules for design-led compositions while respecting the requested format, brand, and scope. Minimal technical compositions and intentionally sparse formats may need less detail.
## The Design Spec Is Brand, Not Layout
The design spec (`frame.md` or `design.md`) defines what the brand looks like: colors, fonts, personality, constraints. It does NOT define how to compose a video frame. Use brand colors at video-appropriate intensity — not at web-UI opacity.
**Strict from the design spec:** hex values (including background color), font families, weight relationships, Do's and Don'ts. If the user chose a light canvas, use a light canvas. If they chose dark, use dark. Do not override their palette.
**Adapt for video:** type sizes, spacing, decorative opacity, border weight, component treatments. A web UI card at `border: 1px solid #e2e3e6` with `box-shadow: 0 2px 4px rgba(0,0,0,0.06)` is invisible on video. The brand color is sacred; the application is yours.
## Density
Choose density from the message and format. A brand or sizzle frame often needs several visual roles to feel produced; a lower-third, logo sting, or static title may need only a few.
For a scene that should feel layered, plan these roles:
- **Background treatment** — radial glow, oversized ghost type, color panel, grain, grid, or an intentionally flat field justified by the concept.
- **Midground content** — the actual message. Cards, stats, code blocks, images.
- **Foreground accents** — dividers, labels, data bars, registration marks, monospace metadata. The details that make it feel produced, not generated.
For produced marketing frames, roughly 610 visual roles can be a useful starting point, not a contract. Add decoration only when it reinforces hierarchy, motion, or the concept. Decorative treatment must not become new user-facing content, new scenes, or unrequested claims.
## Color Presence
Muted is fine. Flat is not. Every scene should have at least one color that pulls the eye.
- Brand accent should be VISIBLE — not a 5% opacity glow lost in compression. 15-25% for atmospheric, full saturation for focal elements.
- **Light canvases work differently than dark.** On dark: accent glows pop naturally. On light: use bolder borders (2px+ solid), stronger structural elements (rules, dividers), and full-saturation accent hits. Light backgrounds need texture (subtle grain, patterns) to avoid the "blank slide" feel. Don't switch to dark — make light cinematic.
- **No full-screen linear gradients on dark backgrounds.** They band visibly under H.264 compression. Use a radial gradient, a solid fill, or solid + localized glow instead.
- Tint neutrals toward the brand hue. Dead gray reads as undesigned.
## Scale
Web sizes are invisible on video. Everything scales up.
| Element | Web | Video |
| ------------------ | ------- | -------- |
| Headlines | 32-48px | 64-120px |
| Body text | 14-16px | 28-42px |
| Labels | 12px | 18-24px |
| Decorative opacity | 3-8% | 12-25% |
| Borders | 1px | 2-4px |
| Padding | 16-32px | 60-140px |
If you're writing a font-size under 24px in a video composition, justify it. If you're writing decorative opacity under 10%, it's invisible.
## Motion Intensity
Subtle reads as static at 30fps. Err toward more movement than feels safe.
- Every decorative element should have ambient motion: breathe, drift, pulse, orbit. Static decoratives feel dead.
- Vary motion per scene — don't repeat the same ambient pattern.
- Scene entrances should use 3+ different eases and directions. If every element enters from `y: 30, opacity: 0`, the scene has no choreography.
## Frame Composition
- **Two focal points minimum.** The eye needs somewhere to travel.
- **Fill the frame.** Hero text: 60-80% of frame width.
- **Anchor to edges.** Pin content to left/top or right/bottom. Centered-and-floating is a web layout pattern.
- **Split frames.** Data panel left, content right. Top bar with metadata, full-width below. Zone-based layouts over centered stacks.
- **Structural elements.** Rules, dividers, border panels. They create visual paths and animate well (`scaleX: 0``1`).