@mevdragon/vidfarm-devcli 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/embedded-captions/CATALOG.md +93 -0
- package/.agents/skills/embedded-captions/SKILL.md +286 -0
- package/.agents/skills/embedded-captions/assets/brand/CDPR-fankit-terms.txt +35 -0
- package/.agents/skills/embedded-captions/assets/brand/cyberpunk-widths.json +115 -0
- package/.agents/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
- package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
- package/.agents/skills/embedded-captions/dna/README.md +148 -0
- package/.agents/skills/embedded-captions/dna/chrome.json +68 -0
- package/.agents/skills/embedded-captions/dna/cream.json +69 -0
- package/.agents/skills/embedded-captions/dna/documentary.json +62 -0
- package/.agents/skills/embedded-captions/dna/editorial.json +70 -0
- package/.agents/skills/embedded-captions/dna/glitch.json +82 -0
- package/.agents/skills/embedded-captions/dna/ink.json +65 -0
- package/.agents/skills/embedded-captions/dna/keynote.json +62 -0
- package/.agents/skills/embedded-captions/dna/loud.json +75 -0
- package/.agents/skills/embedded-captions/dna/neon.json +58 -0
- package/.agents/skills/embedded-captions/dna/velocity.json +89 -0
- package/.agents/skills/embedded-captions/modes/cinematic/README.md +48 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
- package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
- package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
- package/.agents/skills/embedded-captions/modes/cinematic/engine.html +355 -0
- package/.agents/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
- package/.agents/skills/embedded-captions/modes/standard/_motion.md +192 -0
- package/.agents/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
- package/.agents/skills/embedded-captions/references/aesthetic-principles.md +168 -0
- package/.agents/skills/embedded-captions/references/anti-patterns.md +188 -0
- package/.agents/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
- package/.agents/skills/embedded-captions/references/caption-grouping.md +130 -0
- package/.agents/skills/embedded-captions/references/composition-craft.md +522 -0
- package/.agents/skills/embedded-captions/references/direction-catalog.md +138 -0
- package/.agents/skills/embedded-captions/references/example-renders/champion.html +371 -0
- package/.agents/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
- package/.agents/skills/embedded-captions/references/failure-modes.md +145 -0
- package/.agents/skills/embedded-captions/references/layout-heuristics.md +238 -0
- package/.agents/skills/embedded-captions/references/motion-vocabulary.md +148 -0
- package/.agents/skills/embedded-captions/references/rail.md +68 -0
- package/.agents/skills/embedded-captions/references/reference-bar.md +47 -0
- package/.agents/skills/embedded-captions/references/scene-types.md +94 -0
- package/.agents/skills/embedded-captions/references/test-set.md +66 -0
- package/.agents/skills/embedded-captions/references/typographic-moves.md +266 -0
- package/.agents/skills/embedded-captions/references/typography-presets.md +63 -0
- package/.agents/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
- package/.agents/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
- package/.agents/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
- package/.agents/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
- package/.agents/skills/embedded-captions/scripts/check-timing.cjs +173 -0
- package/.agents/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
- package/.agents/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
- package/.agents/skills/embedded-captions/scripts/gen-stroke-path.py +46 -0
- package/.agents/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
- package/.agents/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
- package/.agents/skills/embedded-captions/scripts/make-cinematic.cjs +1205 -0
- package/.agents/skills/embedded-captions/scripts/make-composition.cjs +404 -0
- package/.agents/skills/embedded-captions/scripts/make-theme.cjs +8781 -0
- package/.agents/skills/embedded-captions/scripts/matte.cjs +294 -0
- package/.agents/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
- package/.agents/skills/embedded-captions/scripts/prepare.sh +39 -0
- package/.agents/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
- package/.agents/skills/embedded-captions/scripts/render-and-composite.sh +509 -0
- package/.agents/skills/embedded-captions/scripts/render-theme.sh +34 -0
- package/.agents/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
- package/.agents/skills/embedded-captions/scripts/transcribe.cjs +349 -0
- package/.agents/skills/embedded-captions/themes/PORTING.md +49 -0
- package/.agents/skills/embedded-captions/themes/README.md +244 -0
- package/.agents/skills/embedded-captions/themes/anchor.json +27 -0
- package/.agents/skills/embedded-captions/themes/arcade.json +51 -0
- package/.agents/skills/embedded-captions/themes/aurora.json +41 -0
- package/.agents/skills/embedded-captions/themes/biolume.json +35 -0
- package/.agents/skills/embedded-captions/themes/brush.json +74 -0
- package/.agents/skills/embedded-captions/themes/chalkboard.json +52 -0
- package/.agents/skills/embedded-captions/themes/dossier.json +56 -0
- package/.agents/skills/embedded-captions/themes/graffiti.json +62 -0
- package/.agents/skills/embedded-captions/themes/hologram.json +41 -0
- package/.agents/skills/embedded-captions/themes/inkwater.json +43 -0
- package/.agents/skills/embedded-captions/themes/laser.json +46 -0
- package/.agents/skills/embedded-captions/themes/lastpage.json +33 -0
- package/.agents/skills/embedded-captions/themes/neonsign.json +53 -0
- package/.agents/skills/embedded-captions/themes/nightcity.json +56 -0
- package/.agents/skills/embedded-captions/themes/ordnance.json +54 -0
- package/.agents/skills/embedded-captions/themes/papercut.json +37 -0
- package/.agents/skills/embedded-captions/themes/popup.json +46 -0
- package/.agents/skills/embedded-captions/themes/ransom.json +62 -0
- package/.agents/skills/embedded-captions/themes/scoreboard.json +54 -0
- package/.agents/skills/embedded-captions/themes/spectrum.json +46 -0
- package/.agents/skills/embedded-captions/themes/stardust.json +29 -0
- package/.agents/skills/embedded-captions/themes/stomp.json +43 -0
- package/.agents/skills/embedded-captions/themes/terminal.json +49 -0
- package/.agents/skills/embedded-captions/themes/thunder.json +44 -0
- package/.agents/skills/embedded-captions/themes/transit.json +44 -0
- package/.agents/skills/embedded-captions/themes/vhs.json +47 -0
- package/.agents/skills/faceless-explainer/SKILL.md +209 -0
- package/.agents/skills/faceless-explainer/references/cut-catalog.md +215 -0
- package/.agents/skills/faceless-explainer/references/motion-language.md +156 -0
- package/.agents/skills/faceless-explainer/references/story-design.md +248 -0
- package/.agents/skills/faceless-explainer/references/visual-design.md +146 -0
- package/.agents/skills/faceless-explainer/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/faceless-explainer/scripts/audio.mjs +260 -0
- package/.agents/skills/faceless-explainer/scripts/build-frame.mjs +536 -0
- package/.agents/skills/faceless-explainer/scripts/captions.mjs +508 -0
- package/.agents/skills/faceless-explainer/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/faceless-explainer/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
- package/.agents/skills/faceless-explainer/scripts/transitions.mjs +320 -0
- package/.agents/skills/faceless-explainer/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/flockposter/LICENSE +17 -0
- package/.agents/skills/flockposter/README.md +72 -0
- package/.agents/skills/flockposter/SKILL.md +562 -0
- package/.agents/skills/flockposter/examples/cli-instagram-reel.sh +21 -0
- package/.agents/skills/flockposter/examples/cli-multi-platform.json +69 -0
- package/.agents/skills/flockposter/examples/cli-tiktok-upload-only.sh +22 -0
- package/.agents/skills/flockposter/examples/cli-x-thread.sh +17 -0
- package/.agents/skills/flockposter/examples/cli-youtube-short.sh +21 -0
- package/.agents/skills/flockposter/examples/public-api-instagram-reel.json +28 -0
- package/.agents/skills/general-video/SKILL.md +143 -0
- package/.agents/skills/hyperframes/SKILL.md +160 -0
- package/.agents/skills/hyperframes-animation/SKILL.md +84 -0
- package/.agents/skills/hyperframes-animation/adapters/animate-text.md +64 -0
- package/.agents/skills/hyperframes-animation/adapters/animejs.md +114 -0
- package/.agents/skills/hyperframes-animation/adapters/css-animations.md +143 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +118 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +96 -0
- package/.agents/skills/hyperframes-animation/adapters/gsap.md +105 -0
- package/.agents/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
- package/.agents/skills/hyperframes-animation/adapters/lottie.md +117 -0
- package/.agents/skills/hyperframes-animation/adapters/three.md +131 -0
- package/.agents/skills/hyperframes-animation/adapters/typegpu.md +178 -0
- package/.agents/skills/hyperframes-animation/adapters/waapi.md +101 -0
- package/.agents/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
- package/.agents/skills/hyperframes-animation/blueprints/constellation-hub.md +44 -0
- package/.agents/skills/hyperframes-animation/blueprints/cta-morph-press.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +57 -0
- package/.agents/skills/hyperframes-animation/blueprints/dataviz-countup.md +46 -0
- package/.agents/skills/hyperframes-animation/blueprints/device-surface-showcase.md +53 -0
- package/.agents/skills/hyperframes-animation/blueprints/grid-card-assemble.md +66 -0
- package/.agents/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +78 -0
- package/.agents/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +69 -0
- package/.agents/skills/hyperframes-animation/blueprints/overwhelm-surround.md +28 -0
- package/.agents/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
- package/.agents/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
- package/.agents/skills/hyperframes-animation/blueprints/titlecard-reveal.md +42 -0
- package/.agents/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
- package/.agents/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
- package/.agents/skills/hyperframes-animation/blueprints-index.md +146 -0
- package/.agents/skills/hyperframes-animation/examples/assets/avatars/02.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/github.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/nvidia.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/visa.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/assets/brands/zoominfo.avif +0 -0
- package/.agents/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
- package/.agents/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
- package/.agents/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
- package/.agents/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
- package/.agents/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
- package/.agents/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
- package/.agents/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
- package/.agents/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
- package/.agents/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
- package/.agents/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
- package/.agents/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
- package/.agents/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
- package/.agents/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
- package/.agents/skills/hyperframes-animation/rules/3d-page-scroll.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/3d-text-depth-layers.md +297 -0
- package/.agents/skills/hyperframes-animation/rules/ai-tracking-box.md +382 -0
- package/.agents/skills/hyperframes-animation/rules/ambient-glow-bloom.md +305 -0
- package/.agents/skills/hyperframes-animation/rules/asr-keyword-glow.md +286 -0
- package/.agents/skills/hyperframes-animation/rules/avatar-cloud-network.md +371 -0
- package/.agents/skills/hyperframes-animation/rules/camera-cursor-tracking.md +246 -0
- package/.agents/skills/hyperframes-animation/rules/card-morph-anchor.md +267 -0
- package/.agents/skills/hyperframes-animation/rules/center-outward-expansion.md +227 -0
- package/.agents/skills/hyperframes-animation/rules/context-sensitive-cursor.md +257 -0
- package/.agents/skills/hyperframes-animation/rules/coordinate-target-zoom.md +332 -0
- package/.agents/skills/hyperframes-animation/rules/counting-dynamic-scale.md +283 -0
- package/.agents/skills/hyperframes-animation/rules/css-marker-patterns.md +373 -0
- package/.agents/skills/hyperframes-animation/rules/cursor-click-ripple.md +262 -0
- package/.agents/skills/hyperframes-animation/rules/depth-of-field-blur.md +313 -0
- package/.agents/skills/hyperframes-animation/rules/depth-scatter-assemble.md +303 -0
- package/.agents/skills/hyperframes-animation/rules/discrete-text-sequence.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +307 -0
- package/.agents/skills/hyperframes-animation/rules/gsap-effects.md +299 -0
- package/.agents/skills/hyperframes-animation/rules/hacker-flip-3d.md +223 -0
- package/.agents/skills/hyperframes-animation/rules/kinetic-beat-slam.md +183 -0
- package/.agents/skills/hyperframes-animation/rules/motion-blur-streak.md +328 -0
- package/.agents/skills/hyperframes-animation/rules/multi-phase-camera.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/orbit-3d-entry.md +301 -0
- package/.agents/skills/hyperframes-animation/rules/physics-press-reaction.md +350 -0
- package/.agents/skills/hyperframes-animation/rules/press-release-spring.md +296 -0
- package/.agents/skills/hyperframes-animation/rules/reactive-displacement.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/scale-swap-transition.md +298 -0
- package/.agents/skills/hyperframes-animation/rules/sine-wave-loop.md +278 -0
- package/.agents/skills/hyperframes-animation/rules/split-tilt-cards.md +277 -0
- package/.agents/skills/hyperframes-animation/rules/spring-pop-entrance.md +273 -0
- package/.agents/skills/hyperframes-animation/rules/stat-bars-and-fills.md +156 -0
- package/.agents/skills/hyperframes-animation/rules/svg-icon-enrichment.md +329 -0
- package/.agents/skills/hyperframes-animation/rules/svg-path-draw.md +274 -0
- package/.agents/skills/hyperframes-animation/rules/vertical-spring-ticker.md +239 -0
- package/.agents/skills/hyperframes-animation/rules/viewport-change.md +349 -0
- package/.agents/skills/hyperframes-animation/rules-index.md +86 -0
- package/.agents/skills/hyperframes-animation/scripts/animation-map.mjs +606 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-animation/techniques.md +507 -0
- package/.agents/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +167 -0
- package/.agents/skills/hyperframes-animation/transitions/catalog.md +127 -0
- package/.agents/skills/hyperframes-animation/transitions/css-3d.md +12 -0
- package/.agents/skills/hyperframes-animation/transitions/css-blur.md +51 -0
- package/.agents/skills/hyperframes-animation/transitions/css-cover.md +43 -0
- package/.agents/skills/hyperframes-animation/transitions/css-destruction.md +95 -0
- package/.agents/skills/hyperframes-animation/transitions/css-dissolve.md +66 -0
- package/.agents/skills/hyperframes-animation/transitions/css-distortion.md +45 -0
- package/.agents/skills/hyperframes-animation/transitions/css-grid.md +10 -0
- package/.agents/skills/hyperframes-animation/transitions/css-light.md +49 -0
- package/.agents/skills/hyperframes-animation/transitions/css-mechanical.md +30 -0
- package/.agents/skills/hyperframes-animation/transitions/css-other.md +25 -0
- package/.agents/skills/hyperframes-animation/transitions/css-push.md +41 -0
- package/.agents/skills/hyperframes-animation/transitions/css-radial.md +37 -0
- package/.agents/skills/hyperframes-animation/transitions/css-scale.md +24 -0
- package/.agents/skills/hyperframes-animation/transitions/overview.md +153 -0
- package/.agents/skills/hyperframes-cli/SKILL.md +113 -0
- package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
- package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +55 -0
- package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
- package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
- package/.agents/skills/hyperframes-cli/references/preview-render.md +149 -0
- package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
- package/.agents/skills/hyperframes-core/SKILL.md +78 -0
- package/.agents/skills/hyperframes-core/references/composition-patterns.md +263 -0
- package/.agents/skills/hyperframes-core/references/data-attributes.md +70 -0
- package/.agents/skills/hyperframes-core/references/determinism-rules.md +68 -0
- package/.agents/skills/hyperframes-core/references/full-screen-motion.md +62 -0
- package/.agents/skills/hyperframes-core/references/minimal-composition.md +66 -0
- package/.agents/skills/hyperframes-core/references/script-format.md +49 -0
- package/.agents/skills/hyperframes-core/references/storyboard-format.md +95 -0
- package/.agents/skills/hyperframes-core/references/sub-compositions.md +237 -0
- package/.agents/skills/hyperframes-core/references/subagent-dispatch.md +41 -0
- package/.agents/skills/hyperframes-core/references/tailwind.md +125 -0
- package/.agents/skills/hyperframes-core/references/tracks-and-clips.md +76 -0
- package/.agents/skills/hyperframes-core/references/variables-and-media.md +90 -0
- package/.agents/skills/hyperframes-creative/SKILL.md +70 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
- package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
- package/.agents/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/FRAME.md +277 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/caption-skin.html +224 -0
- package/.agents/skills/hyperframes-creative/frame-presets/claude/frame-showcase.html +1439 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
- package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
- package/.agents/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
- package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
- package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
- package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/.agents/skills/hyperframes-creative/palettes/bold-energetic.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/clean-corporate.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/dark-premium.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/jewel-rich.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/monochrome.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/nature-earth.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/neon-electric.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/pastel-soft.md +14 -0
- package/.agents/skills/hyperframes-creative/palettes/warm-editorial.md +14 -0
- package/.agents/skills/hyperframes-creative/references/audio-reactive.md +76 -0
- package/.agents/skills/hyperframes-creative/references/beat-direction.md +164 -0
- package/.agents/skills/hyperframes-creative/references/composition-patterns.md +199 -0
- package/.agents/skills/hyperframes-creative/references/data-in-motion.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-adherence.md +19 -0
- package/.agents/skills/hyperframes-creative/references/design-picker.md +123 -0
- package/.agents/skills/hyperframes-creative/references/design-spec.md +55 -0
- package/.agents/skills/hyperframes-creative/references/house-style.md +73 -0
- package/.agents/skills/hyperframes-creative/references/motion-principles.md +150 -0
- package/.agents/skills/hyperframes-creative/references/narration.md +92 -0
- package/.agents/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
- package/.agents/skills/hyperframes-creative/references/typography.md +218 -0
- package/.agents/skills/hyperframes-creative/references/video-composition.md +63 -0
- package/.agents/skills/hyperframes-creative/references/visual-styles.md +457 -0
- package/.agents/skills/hyperframes-creative/scripts/contrast-report.mjs +353 -0
- package/.agents/skills/hyperframes-creative/scripts/extract-audio-data.py +188 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.mjs +288 -0
- package/.agents/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
- package/.agents/skills/hyperframes-creative/templates/design-picker.html +1432 -0
- package/.agents/skills/hyperframes-keyframes/SKILL.md +237 -0
- package/.agents/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
- package/.agents/skills/hyperframes-keyframes/references/keyframe-patterns.md +106 -0
- package/.agents/skills/motion-graphics/SKILL.md +172 -0
- package/.agents/skills/motion-graphics/agents/builder.md +40 -0
- package/.agents/skills/motion-graphics/agents/director.md +53 -0
- package/.agents/skills/motion-graphics/agents/finalize.md +17 -0
- package/.agents/skills/motion-graphics/catalog-map.md +40 -0
- package/.agents/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
- package/.agents/skills/motion-graphics/categories/charts/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
- package/.agents/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
- package/.agents/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
- package/.agents/skills/motion-graphics/categories/maps/module.md +61 -0
- package/.agents/skills/motion-graphics/categories/news/module.md +56 -0
- package/.agents/skills/motion-graphics/categories/stat/module.md +21 -0
- package/.agents/skills/motion-graphics/categories/tweet/module.md +16 -0
- package/.agents/skills/motion-graphics/categories/webpage/module.md +21 -0
- package/.agents/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
- package/.agents/skills/motion-graphics/grounding/locate.mjs +227 -0
- package/.agents/skills/motion-graphics/phases/source/guide.md +21 -0
- package/.agents/skills/motion-graphics/references/builder-contract.md +38 -0
- package/.agents/skills/motion-graphics/references/motion-vocabulary.md +43 -0
- package/.agents/skills/motion-graphics/references/shot-plan-ir.md +54 -0
- package/.agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
- package/.agents/skills/product-launch-video/SKILL.md +208 -0
- package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
- package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
- package/.agents/skills/product-launch-video/references/story-design.md +373 -0
- package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
- package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/product-launch-video/scripts/audio.mjs +260 -0
- package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
- package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
- package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
- package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
- package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
- package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
- package/.agents/skills/product-launch-video/scripts/transitions.mjs +327 -0
- package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +75 -0
- package/.agents/skills/slideshow/SKILL.md +550 -0
- package/.agents/skills/slideshow/references/standalone-harness.md +1020 -0
- package/.agents/skills/talking-head-recut/NOTICE.md +39 -0
- package/.agents/skills/talking-head-recut/SKILL.md +1195 -0
- package/.agents/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
- package/.agents/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
- package/.agents/skills/talking-head-recut/references/frames/clean.html +92 -0
- package/.agents/skills/talking-head-recut/references/frames/hairline.html +171 -0
- package/.agents/skills/talking-head-recut/references/frames/polaroid.html +131 -0
- package/.agents/skills/talking-head-recut/references/layouts/overlay.html +164 -0
- package/.agents/skills/talking-head-recut/references/layouts/pip.html +143 -0
- package/.agents/skills/talking-head-recut/references/layouts/split.html +121 -0
- package/.agents/skills/talking-head-recut/references/layouts/stack.html +109 -0
- package/.agents/skills/talking-head-recut/references/styles/academic.html +172 -0
- package/.agents/skills/talking-head-recut/references/styles/audit.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/editorial.html +189 -0
- package/.agents/skills/talking-head-recut/references/styles/geom.html +181 -0
- package/.agents/skills/talking-head-recut/references/styles/minimal.html +130 -0
- package/.agents/skills/talking-head-recut/references/styles/spotlight.html +142 -0
- package/.agents/skills/talking-head-recut/references/styles/swiss.html +188 -0
- package/.agents/skills/talking-head-recut/references/styles/terminal.html +196 -0
- package/.agents/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
- package/.agents/skills/talking-head-recut/references/styles/xhs.html +206 -0
- package/.agents/skills/vidfarm-media/SKILL.md +85 -0
- package/.agents/skills/vidfarm-media/references/tts.md +54 -0
- package/.agents/skills/vidfarm-media/scripts/audio.mjs +628 -0
- package/.agents/skills/vidfarm-media/scripts/wait-bgm.mjs +31 -0
- package/.agents/skills/website-to-video/SKILL.md +145 -0
- package/.agents/skills/website-to-video/assets/sfx/CREDITS.md +35 -0
- package/.agents/skills/website-to-video/assets/sfx/manifest.json +97 -0
- package/.agents/skills/website-to-video/references/beat-builder-guide.md +263 -0
- package/.agents/skills/website-to-video/references/capabilities.md +713 -0
- package/.agents/skills/website-to-video/references/step-0-capture.md +55 -0
- package/.agents/skills/website-to-video/references/step-1-design.md +333 -0
- package/.agents/skills/website-to-video/references/step-2-brief.md +178 -0
- package/.agents/skills/website-to-video/references/step-3-storyboard.md +572 -0
- package/.agents/skills/website-to-video/references/step-4-vo.md +225 -0
- package/.agents/skills/website-to-video/references/step-5-build.md +483 -0
- package/.agents/skills/website-to-video/references/step-6-validate.md +341 -0
- package/.agents/skills/website-to-video/scripts/w2h-verify.mjs +759 -0
- package/SKILL.director.md +37 -0
- package/SKILL.platform.md +6 -1
- package/demo/dist/app.js +295 -11
- package/dist/src/app.js +317 -133
- package/dist/src/cli.js +529 -12
- package/dist/src/composition-runtime.js +262 -3
- package/dist/src/devcli/doctor.js +192 -0
- package/dist/src/devcli/hyperframes-cli.js +118 -0
- package/dist/src/devcli/skills.js +476 -0
- package/dist/src/devcli/stills.js +249 -0
- package/dist/src/editor-chat.js +255 -0
- package/dist/src/hyperframes/composition.js +5 -5
- package/dist/src/services/composition-lint.js +199 -0
- package/dist/src/services/hyperframes.js +67 -13
- package/package.json +2 -1
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vertical-spring-ticker
|
|
3
|
+
description: Slot-machine style vertical scrolling using additive spring physics within a masked container — each spring contributes one "step" of scroll.
|
|
4
|
+
metadata:
|
|
5
|
+
tags: text, ticker, spring, scroll, vertical, slot-machine, sequence
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Vertical Spring Ticker (Slot Machine)
|
|
9
|
+
|
|
10
|
+
Multiple spring tweens are ADDED TOGETHER to produce total Y translation. Each spring contributes one discrete "step." The combined motion has snappy distinct moves with natural settling — instead of a single linear scroll, you get the slot-machine "click click click" rhythm.
|
|
11
|
+
|
|
12
|
+
## How It Works
|
|
13
|
+
|
|
14
|
+
Container has fixed height `ITEM_HEIGHT`, `overflow: hidden`. Inside is a vertical stack of items, each also `ITEM_HEIGHT` tall. The translate of the inner stack is computed as:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
translateY = -ITEM_HEIGHT * sum(spring_i.progress for each spring)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Each spring fires at a different time, settles, then the next fires. When summed, the stack snaps forward step-by-step. The "spring" easing gives each step a tiny overshoot/settle that distinguishes it from a linear marquee.
|
|
21
|
+
|
|
22
|
+
## HTML
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<div
|
|
26
|
+
class="scene"
|
|
27
|
+
id="ticker-scene"
|
|
28
|
+
data-composition-id="ticker-scene"
|
|
29
|
+
data-start="0"
|
|
30
|
+
data-duration="5"
|
|
31
|
+
data-track-index="0"
|
|
32
|
+
>
|
|
33
|
+
<div class="stack">
|
|
34
|
+
<div class="eyebrow">{eyebrow}</div>
|
|
35
|
+
<div class="ticker" id="ticker">
|
|
36
|
+
<div class="stack-inner" id="stack-inner">
|
|
37
|
+
<!-- One .item per state the ticker rolls through.
|
|
38
|
+
The example file lists concrete labels; for the rule, treat
|
|
39
|
+
these as positional slots ({item0} … {itemN}). -->
|
|
40
|
+
<div class="item">{item0}</div>
|
|
41
|
+
<div class="item">{item1}</div>
|
|
42
|
+
<div class="item">{item2}</div>
|
|
43
|
+
<div class="item">{item3}</div>
|
|
44
|
+
<div class="item">{itemN}</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="brand">{footerLine}</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## CSS
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
.scene {
|
|
56
|
+
position: relative;
|
|
57
|
+
width: 100%;
|
|
58
|
+
height: 100%;
|
|
59
|
+
display: grid;
|
|
60
|
+
place-items: center;
|
|
61
|
+
background: {bgColor};
|
|
62
|
+
font-family: {font};
|
|
63
|
+
}
|
|
64
|
+
.stack {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
align-items: center;
|
|
68
|
+
gap: STACK_GAP;
|
|
69
|
+
}
|
|
70
|
+
.eyebrow {
|
|
71
|
+
font-size: EYEBROW_FONT_SIZE;
|
|
72
|
+
font-weight: 800;
|
|
73
|
+
letter-spacing: 14px;
|
|
74
|
+
text-transform: uppercase;
|
|
75
|
+
color: {accentColor};
|
|
76
|
+
}
|
|
77
|
+
/* MANDATORY: container height matches the per-item height exactly */
|
|
78
|
+
.ticker {
|
|
79
|
+
width: TICKER_WIDTH;
|
|
80
|
+
height: ITEM_HEIGHT; /* MUST match .item height */
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
border-top: 2px solid {dividerColor};
|
|
83
|
+
border-bottom: 2px solid {dividerColor};
|
|
84
|
+
position: relative;
|
|
85
|
+
}
|
|
86
|
+
.stack-inner {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column; /* MANDATORY for vertical ticker */
|
|
89
|
+
will-change: transform;
|
|
90
|
+
}
|
|
91
|
+
.item {
|
|
92
|
+
height: ITEM_HEIGHT; /* MUST equal .ticker height */
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
font-size: ITEM_FONT_SIZE;
|
|
97
|
+
font-weight: 900;
|
|
98
|
+
letter-spacing: 8px;
|
|
99
|
+
text-transform: uppercase;
|
|
100
|
+
color: {textColor};
|
|
101
|
+
/* font-variant-numeric: tabular-nums; — for numeric tickers */
|
|
102
|
+
}
|
|
103
|
+
.brand {
|
|
104
|
+
font-size: BRAND_FONT_SIZE;
|
|
105
|
+
font-weight: 800;
|
|
106
|
+
letter-spacing: 10px;
|
|
107
|
+
color: {accentColor};
|
|
108
|
+
text-transform: uppercase;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## GSAP Timeline
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
|
116
|
+
<script>
|
|
117
|
+
window.__timelines = window.__timelines || {};
|
|
118
|
+
const tl = gsap.timeline({ paused: true });
|
|
119
|
+
|
|
120
|
+
const innerEl = document.getElementById("stack-inner");
|
|
121
|
+
|
|
122
|
+
// Each spring object holds a 0→1 progress; they accumulate to a step-counter.
|
|
123
|
+
// Sum * -ITEM_HEIGHT becomes translateY.
|
|
124
|
+
const springs = Array.from({ length: STEPS }, () => ({ p: 0 }));
|
|
125
|
+
|
|
126
|
+
function applyTransform() {
|
|
127
|
+
const sumP = springs.reduce((acc, s) => acc + s.p, 0);
|
|
128
|
+
innerEl.style.transform = `translateY(${-sumP * ITEM_HEIGHT}px)`;
|
|
129
|
+
}
|
|
130
|
+
applyTransform(); // initial state
|
|
131
|
+
|
|
132
|
+
// Fire each spring sequentially with overlap — each one snaps in one step
|
|
133
|
+
springs.forEach((spring, i) => {
|
|
134
|
+
tl.to(
|
|
135
|
+
spring,
|
|
136
|
+
{
|
|
137
|
+
p: 1,
|
|
138
|
+
duration: STEP_DUR,
|
|
139
|
+
ease: `back.out(${BOUNCE_FACTOR})`,
|
|
140
|
+
onUpdate: applyTransform,
|
|
141
|
+
},
|
|
142
|
+
STEP_START + i * STEP_SPACING,
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Footer reveals after the ticker settles on the final item.
|
|
147
|
+
tl.from(
|
|
148
|
+
".brand",
|
|
149
|
+
{ opacity: 0, y: BRAND_Y, duration: BRAND_FADE_DUR, ease: "power3.out" },
|
|
150
|
+
STEP_START + STEPS * STEP_SPACING + BRAND_DELAY,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
window.__timelines["ticker-scene"] = tl;
|
|
154
|
+
</script>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## How to Choose Values
|
|
158
|
+
|
|
159
|
+
- **ITEM_HEIGHT** — px height of each ticker slot AND the masked window.
|
|
160
|
+
- Range: ~`ITEM_FONT_SIZE × 1.25`; the line must hold capital descenders without clipping
|
|
161
|
+
- Constraints: **`.ticker` height MUST equal `.item` height** exactly — mismatched values cause partial items to peek above/below the mask
|
|
162
|
+
- Reference: ../../examples/proof-logo-chain.html uses `204px`
|
|
163
|
+
- **TICKER_WIDTH** — px width of the masked window.
|
|
164
|
+
- Range: wide enough to hold the longest item without ellipsis; typically 30-60% of viewport width
|
|
165
|
+
- **STEPS** — number of additive springs (number of state transitions, not number of items).
|
|
166
|
+
- Range: typically 1-4; each step = one "click" in the slot-machine cadence
|
|
167
|
+
- Constraints: `STEPS ≤ itemCount − 1` (you can only roll as far as there are items below the visible one)
|
|
168
|
+
- Reference: ../../examples/proof-logo-chain.html uses `1` (single roll between two states)
|
|
169
|
+
- **STEP_DUR** — duration of each spring tween.
|
|
170
|
+
- Range: 0.3-0.7s; under 0.3 the overshoot is invisible, over 0.7 the click reads as a slide
|
|
171
|
+
- Reference: ../../examples/proof-logo-chain.html uses `0.45s`
|
|
172
|
+
- **STEP_SPACING** — seconds between consecutive springs' start times.
|
|
173
|
+
- Range: 0.3-0.5s; closer and the steps blur together (looks like linear scroll), further and the ticker feels lazy
|
|
174
|
+
- Constraints: `STEP_SPACING ≤ STEP_DUR` so the previous step is still settling when the next fires (this is what makes them "additive")
|
|
175
|
+
- **STEP_START** — when the first spring fires.
|
|
176
|
+
- Range: 0+; gate behind any preceding beat
|
|
177
|
+
- **BOUNCE_FACTOR** — `back.out(BOUNCE_FACTOR)` overshoot strength per step.
|
|
178
|
+
- Range: 1.4 (gentle click) → 2.0 (firm click) → 2.5+ (cartoony spin-and-land for a climax step)
|
|
179
|
+
- Effects: low end reads as polished UI, high end reads as casino / game show
|
|
180
|
+
- **BRAND_DELAY** — gap after the final step before the footer line reveals, in seconds.
|
|
181
|
+
- Range: 0.2-0.5s; lets the final overshoot settle before the next element competes for attention
|
|
182
|
+
- **BRAND_FADE_DUR** — footer fade-in duration.
|
|
183
|
+
- Range: 0.4-0.7s
|
|
184
|
+
- **BRAND_Y** — initial vertical offset of the footer before fade-up (in px).
|
|
185
|
+
- Range: 8-24 px; bigger feels "punched in," smaller feels gentle
|
|
186
|
+
- **EYEBROW_FONT_SIZE / ITEM_FONT_SIZE / BRAND_FONT_SIZE / STACK_GAP** — typographic + layout scaling.
|
|
187
|
+
- Constraints: items are the focal beat, sized 4-8× larger than eyebrow/footer
|
|
188
|
+
- **{bgColor} / {accentColor} / {textColor} / {dividerColor}** — semantic color tokens; accent reserved for the eyebrow and footer so the ticker items stay neutral.
|
|
189
|
+
- **{font}** — base typography stack. For numeric tickers add `font-variant-numeric: tabular-nums` so digit widths stay constant.
|
|
190
|
+
|
|
191
|
+
## Variations
|
|
192
|
+
|
|
193
|
+
### Numeric ticker (price / counter rolling)
|
|
194
|
+
|
|
195
|
+
Replace text items with the digit sequence and use the same spring-step pattern per decimal position (units, tens, hundreds...). Add `font-variant-numeric: tabular-nums` for digit-width stability.
|
|
196
|
+
|
|
197
|
+
### Reverse direction (counting down)
|
|
198
|
+
|
|
199
|
+
Swap the sign on the translate: `transform: translateY(${sumP * ITEM_HEIGHT}px)` and arrange items in reverse order. Reads as a countdown.
|
|
200
|
+
|
|
201
|
+
### Continuous infinite ticker (no settling)
|
|
202
|
+
|
|
203
|
+
Loop forever (e.g. news ticker) — use linear ease on a single long tween, duplicate the items list, reset when translation exceeds total height. NOT this rule — see [sine-wave-loop](sine-wave-loop.md) pattern for continuous motion vs this rule's discrete-step semantics.
|
|
204
|
+
|
|
205
|
+
### Pause between groups
|
|
206
|
+
|
|
207
|
+
For dramatic "spin then land" feel, group several fast spring steps (`STEP_SPACING` small) + a long `BRAND_DELAY`-style pause + a final dramatic step with bigger `BOUNCE_FACTOR`. The pause is where the eye locks in.
|
|
208
|
+
|
|
209
|
+
## Key Principles
|
|
210
|
+
|
|
211
|
+
- **Container height MUST equal item height** — otherwise items don't snap cleanly into the visible window. If container is 200px and items are 220px, every step shows a partial item edge above/below.
|
|
212
|
+
- **`overflow: hidden` on container, NOT on inner stack** — the mask is the window; the stack inside is free to extend below.
|
|
213
|
+
- **`flex-direction: column` on inner stack** — required for vertical stacking; row would make items horizontal.
|
|
214
|
+
- **Step spacing tighter than step duration** — overlap is what makes the springs additive and gives the "click click" cadence; non-overlapping steps read as a linear scroll.
|
|
215
|
+
- **`back.out` per step** — the overshoot is what makes each step feel like a "click." Linear ease or out-only ease loses the slot-machine feel.
|
|
216
|
+
- **Sum the springs in onUpdate, don't tween the final position directly** — this is the "additive" trick; each spring contributes its OWN snap, which is the slot-machine pacing.
|
|
217
|
+
- **❗ Don't update items via `innerHTML` between steps** — the ticker moves the SAME items via translate; replacing content makes the previous item visible AS the new one (broken illusion).
|
|
218
|
+
- **❗ Climax dwell ≥1s after final step** — see SKILL universal constraints.
|
|
219
|
+
|
|
220
|
+
## Critical Constraints
|
|
221
|
+
|
|
222
|
+
- **Timeline must be paused**: `gsap.timeline({ paused: true })`
|
|
223
|
+
- **Registry key = `data-composition-id`**
|
|
224
|
+
- **No CSS `transition`** on stack-inner — competes with the additive transform
|
|
225
|
+
- **`will-change: transform`** on stack-inner — many small transform updates per second
|
|
226
|
+
- **All items same height (pixel-exact)** — mismatched heights cause cumulative drift
|
|
227
|
+
- **For numeric: `font-variant-numeric: tabular-nums`** — variable digit widths break alignment
|
|
228
|
+
|
|
229
|
+
## Combinations
|
|
230
|
+
|
|
231
|
+
- [reactive-displacement.md](reactive-displacement.md) — ticker is "pushed" by an incoming element
|
|
232
|
+
- [scale-swap-transition.md](scale-swap-transition.md) — ticker scales out after settling on final state, scaled-in subtitle replaces it
|
|
233
|
+
- [press-release-spring.md](press-release-spring.md) — button press TRIGGERS the ticker spin
|
|
234
|
+
|
|
235
|
+
## Pairs with HF skills
|
|
236
|
+
|
|
237
|
+
- `/hyperframes-animation` — additive spring tweens via shared onUpdate
|
|
238
|
+
- `/hyperframes-core` — composition wiring
|
|
239
|
+
- `/hyperframes-cli` — `hyperframes lint`
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: viewport-change
|
|
3
|
+
description: Virtual camera — simulate zoom / pan / focus-lock by transforming a wrapper around all scene content. Camera moves right → world translates left.
|
|
4
|
+
metadata:
|
|
5
|
+
tags: viewport, camera, zoom, pan, focus-lock, virtual-camera
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Viewport Change (Virtual Camera)
|
|
9
|
+
|
|
10
|
+
Simulates camera effects (zoom / pan / focus-lock on a moving element) by transforming a wrapper around ALL scene content. The "world" moves opposite to the perceived camera. Distinct from [multi-phase-camera](multi-phase-camera.md) (which is 2-3 discrete phases + drift) — viewport-change is a single continuous zoom/pan, often used for focus-lock following a moving element.
|
|
11
|
+
|
|
12
|
+
## How It Works
|
|
13
|
+
|
|
14
|
+
Camera intent → world transform:
|
|
15
|
+
|
|
16
|
+
- Camera **pans right** → world `translateX(-distance)`
|
|
17
|
+
- Camera **zooms in** → world `scale(>1)`
|
|
18
|
+
- Camera **follows element X** → world `translateX(viewportCenter - elementWorldX)` updated per-frame
|
|
19
|
+
|
|
20
|
+
The wrapper holds the camera transform; the elements inside are positioned in "world space" unchanged.
|
|
21
|
+
|
|
22
|
+
**Single-element composite transform (this rule's form).** Both scale and translate live on ONE wrapper as `translate(x, y) scale(S)`. CSS applies scale FIRST, then translate (right-to-left matrix composition), so a point at world offset `(ox, oy)` lands on screen at `(S × ox + x, S × oy + y)`. To map the target to viewport center:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
T = -offset × S
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This is **different from [coordinate-target-zoom](coordinate-target-zoom.md)**, which uses two nested wrappers (outer scales, inner translates) and derives `T = -offset` (independent of S). Use this rule's single-wrapper form when you want one source of truth for camera state (`cam.scale`, `cam.x`, `cam.y`) updated via `onUpdate`; use nested wrappers when scale and translate can tween independently with shared ease.
|
|
29
|
+
|
|
30
|
+
## HTML
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<div
|
|
34
|
+
class="scene"
|
|
35
|
+
id="viewport-scene"
|
|
36
|
+
data-composition-id="viewport-scene"
|
|
37
|
+
data-start="0"
|
|
38
|
+
data-duration="5"
|
|
39
|
+
data-track-index="0"
|
|
40
|
+
>
|
|
41
|
+
<div class="world" id="world">
|
|
42
|
+
<div class="content">
|
|
43
|
+
<div class="hero" id="hero">{Brand}</div>
|
|
44
|
+
<div class="tagline">{tagline}</div>
|
|
45
|
+
<div class="cta-row">
|
|
46
|
+
<div class="cta" id="cta">{ctaUrl}</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## CSS
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
.scene {
|
|
57
|
+
position: relative;
|
|
58
|
+
width: 100%;
|
|
59
|
+
height: 100%;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
background: {bgGradient};
|
|
62
|
+
font-family: {font};
|
|
63
|
+
}
|
|
64
|
+
.world {
|
|
65
|
+
position: absolute;
|
|
66
|
+
inset: 0;
|
|
67
|
+
display: grid;
|
|
68
|
+
place-items: center;
|
|
69
|
+
transform-origin: 50% 50%;
|
|
70
|
+
will-change: transform;
|
|
71
|
+
}
|
|
72
|
+
.content {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
align-items: center;
|
|
76
|
+
gap: CONTENT_GAP;
|
|
77
|
+
text-align: center;
|
|
78
|
+
}
|
|
79
|
+
.hero {
|
|
80
|
+
font-size: HERO_FONT_SIZE;
|
|
81
|
+
font-weight: 900;
|
|
82
|
+
letter-spacing: HERO_LETTER_SPACING;
|
|
83
|
+
text-transform: uppercase;
|
|
84
|
+
color: {textColor};
|
|
85
|
+
}
|
|
86
|
+
.tagline {
|
|
87
|
+
font-size: TAGLINE_FONT_SIZE;
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
color: {labelColor};
|
|
90
|
+
}
|
|
91
|
+
.cta {
|
|
92
|
+
display: inline-block;
|
|
93
|
+
padding: CTA_PADDING_Y CTA_PADDING_X;
|
|
94
|
+
font-family: {monoFont};
|
|
95
|
+
font-size: CTA_FONT_SIZE;
|
|
96
|
+
font-weight: 700;
|
|
97
|
+
letter-spacing: CTA_LETTER_SPACING;
|
|
98
|
+
color: {accentColor};
|
|
99
|
+
text-transform: uppercase;
|
|
100
|
+
background: {ctaBg};
|
|
101
|
+
border: 1px solid {ctaBorder};
|
|
102
|
+
border-radius: CTA_BORDER_RADIUS;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## GSAP Timeline
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
|
110
|
+
<script>
|
|
111
|
+
window.__timelines = window.__timelines || {};
|
|
112
|
+
const tl = gsap.timeline({ paused: true });
|
|
113
|
+
|
|
114
|
+
const world = document.getElementById("world");
|
|
115
|
+
|
|
116
|
+
// Camera state — single source of truth. World transform is composed from
|
|
117
|
+
// this object inside applyCamera() so the transform string order is stable.
|
|
118
|
+
const cam = { scale: 1, x: 0, y: 0 };
|
|
119
|
+
|
|
120
|
+
function applyCamera() {
|
|
121
|
+
world.style.transform = `translate(${cam.x}px, ${cam.y}px) scale(${cam.scale})`;
|
|
122
|
+
}
|
|
123
|
+
applyCamera();
|
|
124
|
+
|
|
125
|
+
// Phase 1 — content reveal at neutral camera
|
|
126
|
+
tl.from(".hero", { opacity: 0, y: HERO_Y, duration: HERO_DUR, ease: "power3.out" }, HERO_START);
|
|
127
|
+
tl.from(
|
|
128
|
+
".tagline",
|
|
129
|
+
{ opacity: 0, y: TAGLINE_Y, duration: TAGLINE_DUR, ease: "power3.out" },
|
|
130
|
+
TAGLINE_START,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Phase 2 — zoom in on CTA (single-element composite transform)
|
|
134
|
+
// CSS applies scale FIRST then translate: world point (ox, oy) lands at
|
|
135
|
+
// (S × ox + x, S × oy + y). Solve S × offset + T = 0 → T = -offset × S.
|
|
136
|
+
// This is DIFFERENT from coordinate-target-zoom (nested wrappers, T = -offset).
|
|
137
|
+
const counterY = -TARGET_OFFSET_Y * TARGET_SCALE;
|
|
138
|
+
|
|
139
|
+
tl.to(
|
|
140
|
+
cam,
|
|
141
|
+
{
|
|
142
|
+
scale: TARGET_SCALE,
|
|
143
|
+
y: counterY,
|
|
144
|
+
duration: ZOOM_DUR,
|
|
145
|
+
ease: "power3.inOut",
|
|
146
|
+
onUpdate: applyCamera,
|
|
147
|
+
},
|
|
148
|
+
ZOOM_START,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// Phase 3 — CTA reveals/dwells after zoom settles
|
|
152
|
+
tl.from(
|
|
153
|
+
"#cta",
|
|
154
|
+
{
|
|
155
|
+
opacity: 0,
|
|
156
|
+
scale: CTA_REVEAL_SCALE,
|
|
157
|
+
duration: CTA_REVEAL_DUR,
|
|
158
|
+
ease: `back.out(${BOUNCE_FACTOR})`,
|
|
159
|
+
},
|
|
160
|
+
CTA_REVEAL_START,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
window.__timelines["viewport-scene"] = tl;
|
|
164
|
+
</script>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Scale Value Guide
|
|
168
|
+
|
|
169
|
+
| Effect | Scale | Feel |
|
|
170
|
+
| ----------- | ----------- | ----------------------------------- |
|
|
171
|
+
| Subtle | 1.02 - 1.05 | Barely perceptible — "professional" |
|
|
172
|
+
| Medium | 1.05 - 1.15 | "Ta-da" emphasis |
|
|
173
|
+
| Noticeable | 1.15 - 1.30 | Focus on region |
|
|
174
|
+
| Dramatic | 1.5 - 2.5 | Element fills screen |
|
|
175
|
+
| Full-screen | 3.0+ | Element covers viewport |
|
|
176
|
+
|
|
177
|
+
| Perception threshold | Result |
|
|
178
|
+
| -------------------- | -------------------- |
|
|
179
|
+
| < 5% | Imperceptible |
|
|
180
|
+
| 10-15% | Comfortable emphasis |
|
|
181
|
+
| > 30% | Cinematic / dramatic |
|
|
182
|
+
|
|
183
|
+
## Variations
|
|
184
|
+
|
|
185
|
+
### Focus-lock (camera follows moving cursor/character)
|
|
186
|
+
|
|
187
|
+
For an element moving across the world, keep it at fixed screen X. Compute world offset per-frame:
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
const focusEl = document.querySelector(".moving-cursor");
|
|
191
|
+
const targetScreenX = VIEWPORT_WIDTH * FOCUS_SCREEN_X_FRAC;
|
|
192
|
+
const focusUpdate = { p: 0 };
|
|
193
|
+
tl.to(
|
|
194
|
+
focusUpdate,
|
|
195
|
+
{
|
|
196
|
+
p: 1,
|
|
197
|
+
duration: FOLLOW_DUR,
|
|
198
|
+
ease: "power2.inOut",
|
|
199
|
+
onUpdate: () => {
|
|
200
|
+
const rect = focusEl.getBoundingClientRect();
|
|
201
|
+
const focusWorldX = rect.left + rect.width / 2;
|
|
202
|
+
cam.x = targetScreenX - focusWorldX;
|
|
203
|
+
applyCamera();
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
FOLLOW_START,
|
|
207
|
+
);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Composite scale (multi-phase)
|
|
211
|
+
|
|
212
|
+
Multiply two scale tweens for compound effects:
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
const scaleUp = { v: 1 };
|
|
216
|
+
const scaleDown = { v: 1 };
|
|
217
|
+
function applyCompositeCamera() {
|
|
218
|
+
cam.scale = scaleUp.v * scaleDown.v;
|
|
219
|
+
applyCamera();
|
|
220
|
+
}
|
|
221
|
+
tl.to(
|
|
222
|
+
scaleUp,
|
|
223
|
+
{ v: SCALE_UP_TARGET, duration: SCALE_UP_DUR, onUpdate: applyCompositeCamera },
|
|
224
|
+
SCALE_UP_START,
|
|
225
|
+
);
|
|
226
|
+
tl.to(
|
|
227
|
+
scaleDown,
|
|
228
|
+
{ v: SCALE_DOWN_TARGET, duration: SCALE_DOWN_DUR, onUpdate: applyCompositeCamera },
|
|
229
|
+
SCALE_DOWN_START,
|
|
230
|
+
);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Camera mode transition (centered → follow)
|
|
234
|
+
|
|
235
|
+
Crossfade between two camera modes via a 0→1 weight tween. At weight 0, mode A; at weight 1, mode B; intermediate is interpolated.
|
|
236
|
+
|
|
237
|
+
## How to Choose Values
|
|
238
|
+
|
|
239
|
+
### Layout (CSS)
|
|
240
|
+
|
|
241
|
+
- **CONTENT_GAP** — vertical gap between hero, tagline, and CTA.
|
|
242
|
+
- Range: 16-48 px
|
|
243
|
+
- Effects: small → tightly stacked (logo-lockup feel); large → airy, editorial
|
|
244
|
+
- **HERO_FONT_SIZE / TAGLINE_FONT_SIZE / CTA_FONT_SIZE** — typographic hierarchy.
|
|
245
|
+
- Range: hero >> tagline > CTA (hero is the brand mark, CTA is the actionable footer)
|
|
246
|
+
- Constraints: hero must remain readable when scaled DOWN at neutral camera AND when scaled UP during the zoom — pick the size at neutral camera, the zoom only enlarges it
|
|
247
|
+
- **HERO_LETTER_SPACING / CTA_LETTER_SPACING** — uppercase tracking.
|
|
248
|
+
- Range: 4-10 px for uppercase display type; 0 for sentence case
|
|
249
|
+
- **CTA_PADDING_X / CTA_PADDING_Y / CTA_BORDER_RADIUS** — pill geometry around the CTA text.
|
|
250
|
+
- Constraints: `CTA_BORDER_RADIUS ≥ CTA_FONT_SIZE` to keep the pill ends fully rounded
|
|
251
|
+
|
|
252
|
+
### Phase 1 — Content reveal
|
|
253
|
+
|
|
254
|
+
- **HERO_START** — when the hero begins fading in.
|
|
255
|
+
- Range: 0.2-0.5s (small offset for a beat of black before content appears)
|
|
256
|
+
- **HERO_DUR** — hero fade-up duration.
|
|
257
|
+
- Range: 0.6-1.2s
|
|
258
|
+
- **HERO_Y** — initial Y offset of hero before fade-up (in px).
|
|
259
|
+
- Range: 16-48 px
|
|
260
|
+
- **TAGLINE_START** — when the tagline begins fading in.
|
|
261
|
+
- Constraints: `≥ HERO_START + 0.3` (let the hero land first so the eye reads top-down)
|
|
262
|
+
- **TAGLINE_DUR / TAGLINE_Y** — same shape as hero, typically smaller (`TAGLINE_Y` half of `HERO_Y`).
|
|
263
|
+
|
|
264
|
+
### Phase 2 — Zoom
|
|
265
|
+
|
|
266
|
+
- **TARGET_OFFSET_Y** — measured Y offset (in px) of the CTA from viewport center at neutral camera.
|
|
267
|
+
- Constraints: derived from layout, NOT a free parameter. Measure via `getBoundingClientRect()` OR compute from `CONTENT_GAP + (HERO_HEIGHT + TAGLINE_HEIGHT) / 2`. Sign matters — positive = below center.
|
|
268
|
+
- **TARGET_SCALE** — final magnification of the world.
|
|
269
|
+
- Range: 1.3× (modest) → 1.6-2.0× (typical CTA zoom) → 3×+ (cinematic)
|
|
270
|
+
- Constraints: raster source media needs `sourceResolution ≥ rendered × TARGET_SCALE`; text remains crisp at any scale
|
|
271
|
+
- **ZOOM_START** — when the zoom begins.
|
|
272
|
+
- Constraints: `≥ TAGLINE_START + TAGLINE_DUR + viewer-scan-time` (give viewer ~0.5s after content lands before camera moves)
|
|
273
|
+
- **ZOOM_DUR** — duration of the zoom tween.
|
|
274
|
+
- Range: 1.0-2.0s; under 0.8s feels like a teleport, over 2.5s drags
|
|
275
|
+
|
|
276
|
+
### Phase 3 — CTA reveal + dwell
|
|
277
|
+
|
|
278
|
+
- **CTA_REVEAL_START** — when the CTA pops in.
|
|
279
|
+
- Constraints: `≥ ZOOM_START + ZOOM_DUR × 0.9` (start near the end of the zoom so the CTA "lands" with the camera)
|
|
280
|
+
- **CTA_REVEAL_DUR** — CTA fade-in / pop duration.
|
|
281
|
+
- Range: 0.4-0.8s
|
|
282
|
+
- **CTA_REVEAL_SCALE** — initial scale of the CTA before pop.
|
|
283
|
+
- Range: 0.85-0.95 (sub-1 → grows into place); >1.0 inverts to a shrink-into-place feel
|
|
284
|
+
- **BOUNCE_FACTOR** — overshoot coefficient for `back.out(${BOUNCE_FACTOR})`.
|
|
285
|
+
- Range: 1.2-2.5; lower = subtle settle, higher = pronounced overshoot. The ease family (`back.out`) is the choice; this number tunes its intensity.
|
|
286
|
+
- Reference: ease family options: `back.out` (overshoot then settle), `elastic.out` (oscillation), `power3.out` (clean decel, no overshoot)
|
|
287
|
+
- **DWELL_DUR** — implicit hold after `CTA_REVEAL_START + CTA_REVEAL_DUR` until `data-duration` ends.
|
|
288
|
+
- Range: ≥ 1.0s (see "Climax dwell" in Key Principles)
|
|
289
|
+
|
|
290
|
+
### Focus-lock variation
|
|
291
|
+
|
|
292
|
+
- **VIEWPORT_WIDTH** — composition width in px. Real value (`data-width` on the root); not abstract.
|
|
293
|
+
- **FOCUS_SCREEN_X_FRAC** — where on screen to lock the focused element.
|
|
294
|
+
- Range: 0.4-0.7 (rule of thirds positions); 0.5 is dead center
|
|
295
|
+
- **FOLLOW_START / FOLLOW_DUR** — when the follow-cam engages and for how long.
|
|
296
|
+
- Constraints: `FOLLOW_DUR` matches the duration the focused element is in motion
|
|
297
|
+
|
|
298
|
+
### Composite-scale variation
|
|
299
|
+
|
|
300
|
+
- **SCALE_UP_TARGET / SCALE_DOWN_TARGET** — multiplicative factors composed via `cam.scale = scaleUp.v * scaleDown.v`.
|
|
301
|
+
- Effects: combine a slow push-in (`SCALE_UP_TARGET` ~1.15) with a brief release (`SCALE_DOWN_TARGET` ~0.9) for a breath/punch shape
|
|
302
|
+
- **SCALE_UP_START / SCALE_UP_DUR / SCALE_DOWN_START / SCALE_DOWN_DUR** — phase timing for each multiplicand.
|
|
303
|
+
|
|
304
|
+
### Color tokens
|
|
305
|
+
|
|
306
|
+
- **{bgGradient}** — scene background (typically a dark radial vignette so edges fall off as zoom reveals them)
|
|
307
|
+
- **{textColor}** — hero text; highest contrast against `{bgGradient}`
|
|
308
|
+
- **{labelColor}** — tagline / secondary copy; one step softer than `{textColor}`
|
|
309
|
+
- **{accentColor}** — CTA text + border; reserved hue that pops on reveal
|
|
310
|
+
- **{ctaBg} / {ctaBorder}** — semi-transparent fills derived from `{accentColor}` (typical `rgba` at 10-15% / 35-45% alpha)
|
|
311
|
+
|
|
312
|
+
### Font tokens
|
|
313
|
+
|
|
314
|
+
- **{font}** — sans-serif body / hero stack (e.g. `"Inter", sans-serif`)
|
|
315
|
+
- **{monoFont}** — monospace CTA stack (e.g. `"JetBrains Mono", monospace`); reserved for the URL/code-like CTA so it reads as actionable
|
|
316
|
+
|
|
317
|
+
## Key Principles
|
|
318
|
+
|
|
319
|
+
- **World moves opposite to perceived camera** — pan camera right = `translateX(-x)` on the world wrapper. Get this sign right, otherwise everything moves the wrong way.
|
|
320
|
+
- **Single-wrapper transform order matters** — `translate(x, y) scale(S)` applies scale first; counter-translate is `T = -offset × S`. Mixing this up with the nested-wrapper form (`T = -offset`) drifts the target off-center as scale changes.
|
|
321
|
+
- **`overflow: hidden` on `.scene` REQUIRED** — at any non-1.0 scale the world transform reveals edges or pushes content off-frame.
|
|
322
|
+
- **`transform-origin: 50% 50%`** on the world wrapper — centered scaling is what the math assumes.
|
|
323
|
+
- **Background on `.scene`, NOT on `.world`** — if background is on the world, transforming the world warps/translates the background.
|
|
324
|
+
- **Single source of truth via `cam` object + `applyCamera()`** — when scale and translate both change, write them in ONE place. Otherwise the transform string composition order is unpredictable.
|
|
325
|
+
- **Subtle continuous motion > big sudden zoom** — for a feel-natural product video, use 1.05-1.15× zoom over 2-3s. Big > 1.3× zooms read as dramatic narrative moments, save them.
|
|
326
|
+
- **Climax dwell >=1s** — after the zoom settles, the comp must continue for >=1s so the viewer can read the focal point.
|
|
327
|
+
|
|
328
|
+
## Critical Constraints
|
|
329
|
+
|
|
330
|
+
- **Timeline must be paused**: `gsap.timeline({ paused: true })`
|
|
331
|
+
- **Registry key = `data-composition-id`**
|
|
332
|
+
- **No CSS `transition` on `.world`** — competes with GSAP
|
|
333
|
+
- **`will-change: transform`** on `.world`
|
|
334
|
+
- **`overflow: hidden` on `.scene`**
|
|
335
|
+
- **`transform-origin: 50% 50%` on `.world`**
|
|
336
|
+
- **Background on `.scene`** — never on `.world`
|
|
337
|
+
- **Scale and translate share one `onUpdate`** — both read from `cam` and write the composite transform string together; never split them across tweens that touch `world.style.transform` directly
|
|
338
|
+
|
|
339
|
+
## Combinations
|
|
340
|
+
|
|
341
|
+
- [multi-phase-camera.md](multi-phase-camera.md) — viewport-change inside one phase of a multi-phase camera
|
|
342
|
+
- [coordinate-target-zoom.md](coordinate-target-zoom.md) — alternative for off-center zoom (nested wrappers, `T = -offset` form)
|
|
343
|
+
- [sine-wave-loop.md](sine-wave-loop.md) — idle micro-drift after viewport settles
|
|
344
|
+
|
|
345
|
+
## Pairs with HF skills
|
|
346
|
+
|
|
347
|
+
- `/hyperframes-animation` — single tween writing composite transform
|
|
348
|
+
- `/hyperframes-core` — composition wiring
|
|
349
|
+
- `/hyperframes-cli` — `hyperframes lint`
|