@prestyj/cli 5.28.0 → 5.29.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/README.md +2 -2
- package/assets/motion/THIRD-PARTY.md +14 -19
- package/assets/motion/bin/contact-sheet.mjs +9 -3
- package/assets/motion/bin/cues.mjs +337 -0
- package/assets/motion/bin/flash-check.mjs +314 -0
- package/assets/motion/bin/fonts.mjs +17 -13
- package/assets/motion/bin/library.mjs +61 -18
- package/assets/motion/bin/motion-blur.mjs +943 -0
- package/assets/motion/bin/motion-check.mjs +366 -9
- package/assets/motion/bin/music-fit.mjs +436 -0
- package/assets/motion/bin/pdf-extract.mjs +22 -10
- package/assets/motion/bin/reference-study.mjs +346 -0
- package/assets/motion/bin/score-synth.mjs +1052 -93
- package/assets/motion/fonts/finger-paint/OFL.txt +93 -0
- package/assets/motion/fonts/finger-paint/finger-paint-normal.woff2 +0 -0
- package/assets/motion/fonts/fonts.json +56 -0
- package/assets/motion/fonts/short-stack/OFL.txt +94 -0
- package/assets/motion/fonts/short-stack/short-stack-normal.woff2 +0 -0
- package/assets/motion/fonts/sora/OFL.txt +93 -0
- package/assets/motion/fonts/sora/sora-normal.woff2 +0 -0
- package/assets/motion/fonts/specimen.jpg +0 -0
- package/assets/motion/fonts/unbounded/OFL.txt +93 -0
- package/assets/motion/fonts/unbounded/unbounded-normal.woff2 +0 -0
- package/assets/motion/library/README.md +52 -14
- package/assets/motion/library/kit/moves.js +1981 -0
- package/assets/motion/library/library.json +232 -0
- package/assets/motion/library/pieces/camera-rig/meta.json +13 -0
- package/assets/motion/library/pieces/camera-rig/piece.html +153 -0
- package/assets/motion/library/pieces/camera-rig/preview.jpg +0 -0
- package/assets/motion/library/pieces/chain-knock/meta.json +13 -0
- package/assets/motion/library/pieces/chain-knock/piece.html +195 -0
- package/assets/motion/library/pieces/chain-knock/preview.jpg +0 -0
- package/assets/motion/library/pieces/gather-to-logo/meta.json +13 -0
- package/assets/motion/library/pieces/gather-to-logo/piece.html +159 -0
- package/assets/motion/library/pieces/gather-to-logo/preview.jpg +0 -0
- package/assets/motion/library/pieces/morph-carry/meta.json +13 -0
- package/assets/motion/library/pieces/morph-carry/piece.html +173 -0
- package/assets/motion/library/pieces/morph-carry/preview.jpg +0 -0
- package/assets/motion/library/pieces/one-shape-journey/meta.json +13 -0
- package/assets/motion/library/pieces/one-shape-journey/piece.html +195 -0
- package/assets/motion/library/pieces/one-shape-journey/preview.jpg +0 -0
- package/assets/motion/library/pieces/open-from-subject/meta.json +13 -0
- package/assets/motion/library/pieces/open-from-subject/piece.html +168 -0
- package/assets/motion/library/pieces/open-from-subject/preview.jpg +0 -0
- package/assets/motion/library/pieces/request-to-result/meta.json +13 -0
- package/assets/motion/library/pieces/request-to-result/piece.html +212 -0
- package/assets/motion/library/pieces/request-to-result/preview.jpg +0 -0
- package/assets/motion/library/pieces/scale-dive/meta.json +13 -0
- package/assets/motion/library/pieces/scale-dive/piece.html +321 -0
- package/assets/motion/library/pieces/scale-dive/preview.jpg +0 -0
- package/assets/motion/library/pieces/screen-replica-steps/meta.json +13 -0
- package/assets/motion/library/pieces/screen-replica-steps/piece.html +366 -0
- package/assets/motion/library/pieces/screen-replica-steps/preview.jpg +0 -0
- package/assets/motion/library/pieces/zoom-into-card/meta.json +13 -0
- package/assets/motion/library/pieces/zoom-into-card/piece.html +179 -0
- package/assets/motion/library/pieces/zoom-into-card/preview.jpg +0 -0
- package/assets/motion/library/sheets/diagram.jpg +0 -0
- package/assets/motion/library/sheets/frame.jpg +0 -0
- package/assets/motion/library/sheets/transition.jpg +0 -0
- package/assets/motion/library/sheets/ui.jpg +0 -0
- package/assets/motion/plugin.json +1 -1
- package/assets/motion/references/build-sheet.md +206 -0
- package/assets/motion/references/runtime/determinism-rules.md +3 -3
- package/assets/motion/references/runtime/gsap-easing-and-stagger.md +28 -28
- package/assets/motion/references/runtime/gsap.md +3 -3
- package/assets/motion/references/runtime/inputs-and-assets.md +21 -16
- package/assets/motion/references/runtime/lint-validate-inspect.md +3 -3
- package/assets/motion/references/runtime/minimal-composition.md +6 -0
- package/assets/motion/references/runtime/preview-render.md +3 -3
- package/assets/motion/skills/app-walkthrough/SKILL.md +66 -0
- package/assets/motion/skills/before-after/SKILL.md +53 -0
- package/assets/motion/skills/brand-kit/SKILL.md +17 -16
- package/assets/motion/skills/dev-tool-video/SKILL.md +57 -0
- package/assets/motion/skills/launch-video/SKILL.md +62 -0
- package/assets/motion/skills/match-reference/SKILL.md +58 -0
- package/assets/motion/skills/motion/SKILL.md +167 -98
- package/assets/motion/skills/source-ingest/SKILL.md +23 -15
- package/assets/motion/skills/website-video/SKILL.md +59 -0
- package/assets/skills/bulletproof/SKILL.md +36 -11
- package/assets/skills/bulletproof/references/agent-surface.md +19 -9
- package/assets/skills/bulletproof/references/audit-protocol.md +20 -5
- package/assets/skills/bulletproof/references/platform-playbooks.md +5 -4
- package/assets/skills/bulletproof/references/provenance.md +26 -1
- package/assets/skills/bulletproof/references/secure-defaults.md +6 -5
- package/assets/skills/bulletproof/references/supply-chain.md +21 -17
- package/assets/skills/bulletproof/references/threat-landscape.md +28 -26
- package/assets/skills/bulletproof/references/verification.md +2 -0
- package/assets/skills/clarify/SKILL.md +25 -16
- package/assets/skills/code-review/SKILL.md +71 -13
- package/assets/skills/code-review/references/agent-diffs.md +27 -0
- package/assets/skills/code-review/references/tests.md +19 -0
- package/assets/skills/compliance-guard/SKILL.md +20 -5
- package/assets/skills/compliance-guard/references/artifacts.md +1 -1
- package/assets/skills/compliance-guard/references/eu-uk.md +16 -16
- package/assets/skills/compliance-guard/references/lawsuit-vectors.md +5 -5
- package/assets/skills/compliance-guard/references/provenance.md +41 -2
- package/assets/skills/compliance-guard/references/sector-gates.md +3 -3
- package/assets/skills/compliance-guard/references/security-baseline.md +2 -2
- package/assets/skills/compliance-guard/references/trigger-map.md +5 -5
- package/assets/skills/compliance-guard/references/us.md +27 -21
- package/assets/skills/durable/SKILL.md +87 -79
- package/assets/skills/durable/references/agent-db-safety.md +69 -0
- package/assets/skills/durable/references/backups-and-runtime.md +19 -12
- package/assets/skills/durable/references/migrations-and-schema.md +13 -6
- package/assets/skills/evidence-led-ui/SKILL.md +69 -127
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +107 -208
- package/assets/skills/evidence-led-ui/references/direction.md +124 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +8 -0
- package/assets/skills/evidence-led-ui/references/provenance.md +24 -1
- package/assets/skills/lean/SKILL.md +90 -71
- package/assets/skills/lean/references/memory-and-processes.md +3 -2
- package/assets/skills/lean/references/playbooks.md +37 -12
- package/assets/skills/refactoring/SKILL.md +24 -3
- package/assets/skills/refactoring/references/agent-pitfalls.md +4 -1
- package/assets/skills/refactoring/references/legacy.md +21 -0
- package/assets/skills/root-cause/SKILL.md +20 -10
- package/assets/skills/shared-language/SKILL.md +16 -14
- package/assets/skills/tdd/SKILL.md +27 -15
- package/dist/app-sidecar.js +203 -47
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +20 -28
- package/dist/cli.js.map +1 -1
- package/dist/core/acceptance-checks.d.ts +48 -0
- package/dist/core/acceptance-checks.js +144 -0
- package/dist/core/acceptance-checks.js.map +1 -0
- package/dist/core/agent-session.d.ts +119 -75
- package/dist/core/agent-session.js +561 -395
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +6 -5
- package/dist/core/agents.js +12 -3
- package/dist/core/agents.js.map +1 -1
- package/dist/core/ask-user.d.ts +90 -8
- package/dist/core/ask-user.js +124 -13
- package/dist/core/ask-user.js.map +1 -1
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/autopilot-verdict.d.ts +5 -1
- package/dist/core/autopilot-verdict.js +30 -13
- package/dist/core/autopilot-verdict.js.map +1 -1
- package/dist/core/bundled-agents.js +1 -3
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/cache-diagnostics.d.ts +68 -0
- package/dist/core/cache-diagnostics.js +196 -0
- package/dist/core/cache-diagnostics.js.map +1 -0
- package/dist/core/cache-expiry.d.ts +87 -0
- package/dist/core/cache-expiry.js +111 -0
- package/dist/core/cache-expiry.js.map +1 -0
- package/dist/core/compaction/compactor.js +78 -48
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/plan-step-policy.d.ts +46 -0
- package/dist/core/compaction/plan-step-policy.js +57 -0
- package/dist/core/compaction/plan-step-policy.js.map +1 -0
- package/dist/core/destructive-git-guard.d.ts +90 -0
- package/dist/core/destructive-git-guard.js +871 -0
- package/dist/core/destructive-git-guard.js.map +1 -0
- package/dist/core/event-bus.d.ts +3 -0
- package/dist/core/event-bus.js +5 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/fast-apply-benchmark.d.ts +1 -1
- package/dist/core/fast-apply-benchmark.js +2 -2
- package/dist/core/fast-apply-benchmark.js.map +1 -1
- package/dist/core/injection-detect.d.ts +38 -0
- package/dist/core/injection-detect.js +232 -0
- package/dist/core/injection-detect.js.map +1 -0
- package/dist/core/keep-awake.d.ts +88 -0
- package/dist/core/keep-awake.js +251 -0
- package/dist/core/keep-awake.js.map +1 -0
- package/dist/core/mcp/client.d.ts +72 -0
- package/dist/core/mcp/client.js +264 -41
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/content.js +6 -2
- package/dist/core/mcp/content.js.map +1 -1
- package/dist/core/mcp/store.d.ts +6 -1
- package/dist/core/mcp/store.js +12 -1
- package/dist/core/mcp/store.js.map +1 -1
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/model-unavailable.d.ts +14 -0
- package/dist/core/model-unavailable.js +23 -0
- package/dist/core/model-unavailable.js.map +1 -0
- package/dist/core/node-debugger.d.ts +148 -0
- package/dist/core/node-debugger.js +642 -0
- package/dist/core/node-debugger.js.map +1 -0
- package/dist/core/nolan-context.d.ts +7 -5
- package/dist/core/nolan-context.js +106 -16
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-prompt.js +24 -21
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/package-threats.d.ts +18 -0
- package/dist/core/package-threats.js +168 -0
- package/dist/core/package-threats.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +58 -6
- package/dist/core/persistent-shell.js +331 -49
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager.d.ts +14 -0
- package/dist/core/process-manager.js +61 -0
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/progress/git-xp.js +8 -14
- package/dist/core/progress/git-xp.js.map +1 -1
- package/dist/core/project-discovery.js +77 -26
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/semantic-search-benchmark.d.ts +1 -1
- package/dist/core/semantic-search-benchmark.js +2 -2
- package/dist/core/semantic-search-benchmark.js.map +1 -1
- package/dist/core/session-history.d.ts +12 -0
- package/dist/core/session-history.js +27 -0
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.js +38 -18
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-summary-index.d.ts +37 -0
- package/dist/core/session-summary-index.js +172 -0
- package/dist/core/session-summary-index.js.map +1 -0
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.js +10 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/shell-threats-popular-packages.d.ts +11 -0
- package/dist/core/shell-threats-popular-packages.js +675 -0
- package/dist/core/shell-threats-popular-packages.js.map +1 -0
- package/dist/core/shell-threats.d.ts +8 -0
- package/dist/core/shell-threats.js +186 -0
- package/dist/core/shell-threats.js.map +1 -0
- package/dist/core/skills.js +16 -4
- package/dist/core/skills.js.map +1 -1
- package/dist/core/stream-rules.d.ts +30 -0
- package/dist/core/stream-rules.js +151 -0
- package/dist/core/stream-rules.js.map +1 -0
- package/dist/core/subagent-manager.d.ts +23 -6
- package/dist/core/subagent-manager.js +25 -9
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-policy.js +1 -1
- package/dist/core/subagent-policy.js.map +1 -1
- package/dist/core/subagent-receipt.d.ts +54 -0
- package/dist/core/subagent-receipt.js +276 -0
- package/dist/core/subagent-receipt.js.map +1 -0
- package/dist/core/subagent-turn-record.d.ts +2 -0
- package/dist/core/subagent-turn-record.js.map +1 -1
- package/dist/core/test-impact.d.ts +73 -0
- package/dist/core/test-impact.js +467 -0
- package/dist/core/test-impact.js.map +1 -0
- package/dist/core/thinking-level.d.ts +1 -1
- package/dist/core/thinking-level.js +1 -1
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/verification-gate.d.ts +2 -0
- package/dist/core/verification-gate.js +4 -0
- package/dist/core/verification-gate.js.map +1 -1
- package/dist/core/verification-snapshot.js +3 -5
- package/dist/core/verification-snapshot.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +18 -7
- package/dist/core/workspace-guard.js +227 -60
- package/dist/core/workspace-guard.js.map +1 -1
- package/dist/core/worktree-setup.d.ts +23 -0
- package/dist/core/worktree-setup.js +128 -9
- package/dist/core/worktree-setup.js.map +1 -1
- package/dist/core/worktree.d.ts +20 -2
- package/dist/core/worktree.js +74 -31
- package/dist/core/worktree.js.map +1 -1
- package/dist/interactive.js +2 -1
- package/dist/interactive.js.map +1 -1
- package/dist/modes/json-mode.js +11 -2
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +36 -1
- package/dist/modes/subagent-worker-mode.js +100 -42
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/motion-agent/motion-agent.d.ts +7 -3
- package/dist/motion-agent/motion-agent.js +6 -8
- package/dist/motion-agent/motion-agent.js.map +1 -1
- package/dist/motion-agent/motion-prompt.d.ts +1 -1
- package/dist/motion-agent/motion-prompt.js +16 -25
- package/dist/motion-agent/motion-prompt.js.map +1 -1
- package/dist/motion-agent/motion-review-session.js +1 -1
- package/dist/motion-agent/motion-review-session.js.map +1 -1
- package/dist/motion-agent/motion-review.d.ts +10 -3
- package/dist/motion-agent/motion-review.js +15 -7
- package/dist/motion-agent/motion-review.js.map +1 -1
- package/dist/motion-agent/motion-studio-context.js +1 -1
- package/dist/motion-agent/motion-studio-context.js.map +1 -1
- package/dist/system-prompt.d.ts +2 -1
- package/dist/system-prompt.js +15 -4
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/keep-alive.d.ts +14 -0
- package/dist/test-support/keep-alive.js +17 -0
- package/dist/test-support/keep-alive.js.map +1 -0
- package/dist/tools/ask-user.js +3 -3
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash-read-evidence.d.ts +10 -0
- package/dist/tools/bash-read-evidence.js +133 -0
- package/dist/tools/bash-read-evidence.js.map +1 -0
- package/dist/tools/bash.d.ts +10 -1
- package/dist/tools/bash.js +179 -7
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/debug.d.ts +54 -0
- package/dist/tools/debug.js +233 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/edit.js +13 -5
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/goals.d.ts +1 -1
- package/dist/tools/index.d.ts +25 -2
- package/dist/tools/index.js +48 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.js +2 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-tracker.d.ts +35 -2
- package/dist/tools/read-tracker.js +108 -11
- package/dist/tools/read-tracker.js.map +1 -1
- package/dist/tools/read.js +39 -7
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/skill.js +5 -0
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +44 -8
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +48 -8
- package/dist/tools/subagent-shared.js +75 -14
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +8 -2
- package/dist/tools/subagent.js +28 -10
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +3 -2
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.d.ts +1 -1
- package/dist/tools/task-send.js +15 -1
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +2 -2
- package/dist/tools/tool-tiers.js +3 -2
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/truncate.d.ts +21 -0
- package/dist/tools/truncate.js +187 -0
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/ui-adopt.js +2 -0
- package/dist/tools/ui-adopt.js.map +1 -1
- package/dist/tools/write.js +4 -3
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.d.ts +0 -4
- package/dist/ui/App.js +5 -28
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/Footer.js +1 -1
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +1 -8
- package/dist/ui/hooks/useAgentLoop.js +1 -119
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/render.d.ts +2 -4
- package/dist/ui/render.js +3 -2
- package/dist/ui/render.js.map +1 -1
- package/dist/utils/git.d.ts +77 -0
- package/dist/utils/git.js +285 -21
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/github-ci.js +2 -1
- package/dist/utils/github-ci.js.map +1 -1
- package/dist/utils/github.js +11 -9
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +16 -0
- package/dist/utils/image.js.map +1 -1
- package/dist/utils/process.d.ts +20 -0
- package/dist/utils/process.js +98 -0
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.js +11 -0
- package/dist/utils/text.js.map +1 -1
- package/package.json +6 -6
- package/assets/motion/skills/mixkit-split-text-617/SKILL.md +0 -115
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-480.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-494.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-5.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-508.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6525.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6539.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6647.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6663.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6677.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6691.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6706.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6722.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6736.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6750.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6764.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6780.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6794.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6810.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6823.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6872.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-6936.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/compositions/comp-76.json +0 -1
- package/assets/motion/skills/mixkit-split-text-617/data/manifest.json +0 -495
- package/assets/motion/skills/mixkit-split-text-617/references/RECONSTRUCTION.md +0 -201
- package/assets/motion/skills/mixkit-split-text-617/references/VERIFICATION.md +0 -107
- package/assets/motion/skills/mixkit-split-text-617/tools/inspect_motion.py +0 -130
- package/assets/motion/skills/video-qa/SKILL.md +0 -66
- package/dist/core/ideal-review-subagent.d.ts +0 -42
- package/dist/core/ideal-review-subagent.js +0 -95
- package/dist/core/ideal-review-subagent.js.map +0 -1
- package/dist/core/ideal-review.d.ts +0 -82
- package/dist/core/ideal-review.js +0 -242
- package/dist/core/ideal-review.js.map +0 -1
- package/dist/motion-agent/motion-check-tool.d.ts +0 -21
- package/dist/motion-agent/motion-check-tool.js +0 -206
- package/dist/motion-agent/motion-check-tool.js.map +0 -1
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Build sheet
|
|
2
|
+
|
|
3
|
+
Everything needed to write a composition with the move kit and to score it,
|
|
4
|
+
in one place. It is the complete public surface: you do not need to open
|
|
5
|
+
`moves.js`, `score-synth.mjs` or any helper's `--help` to use them.
|
|
6
|
+
|
|
7
|
+
## Move kit (`window.GGMotionKit`)
|
|
8
|
+
|
|
9
|
+
Install with `<node> "<motion bin>/library.mjs" kit <project>`, load
|
|
10
|
+
`assets/kit/moves.js` after GSAP, then `const kit = window.GGMotionKit;`.
|
|
11
|
+
Every move adds tweens to `tl` from time `at` and returns the time of its key
|
|
12
|
+
moment, so the next move can start from it. Options are all optional; the
|
|
13
|
+
value after `=` is the default.
|
|
14
|
+
|
|
15
|
+
### Arrivals
|
|
16
|
+
|
|
17
|
+
| Call | Options | Returns |
|
|
18
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
19
|
+
| `liftWords(tl, el, at, o)` | `stagger=0.07`, `spring="snappy"`, `duration`, `from=115` (start yPercent) | when the last word has mostly risen |
|
|
20
|
+
| `dropLetters(tl, el, at, o)` | `height=260`, `fall=0.38`, `stagger=0.05`, `squash=0.24`, `spring="bouncy"` | the last landing |
|
|
21
|
+
| `reveal(tl, el, at, o)` | `from="bottom"` (top, bottom, left, right), `duration=0.8`, `ease="snap"` | end |
|
|
22
|
+
| `typewrite(tl, el, at, o)` | `text` (default the element's text), `cps=22`, `jitter=0.4`, `seed=11`, `caret="▍"` or `false`, `caretHold=0` | when typing ends |
|
|
23
|
+
| `tick(tl, path, at, o)` | `duration=0.34`, `ease="snap"` (an SVG path) | end |
|
|
24
|
+
| `pop(tl, el, at, o)` | `from=0.3` (start scale), `spring="bouncy"` | when it reads as arrived |
|
|
25
|
+
| `stamp(tl, el, at, o)` | `duration=0.2`, `rotate=-4`, `from=2.4` | the contact |
|
|
26
|
+
|
|
27
|
+
### Handoffs
|
|
28
|
+
|
|
29
|
+
| Call | Options | Returns |
|
|
30
|
+
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
|
31
|
+
| `reshape(tl, el, at, to, o)` | `to` is `{ x, y, w, h, r }` or an element; `duration=0.85`, `ease="travel"`, or `spring` | when the change reads |
|
|
32
|
+
| `openFrom(tl, stage, at, o)` | `x`, `y` (default the centre), `width=1920`, `height=1080`, `from=0`, `duration=0.9`, `ease="travel"` | end |
|
|
33
|
+
| `diveThrough(tl, layer, at, o)` | `x=960`, `y=540`, `zoom=16`, `duration=1`, `ease="drop"`, `next` (element shown at the end) | end |
|
|
34
|
+
| `converge(tl, els, at, target, o)` | `target` is `{ x, y }`; `duration=0.85`, `stagger=0.05`, `bow=0.28`, `shrink=0.12`, `seed=5`, `ease="drop"`, `space` | the last arrival |
|
|
35
|
+
|
|
36
|
+
`converge` and `hop` own the element's transform: wrap an element to also
|
|
37
|
+
pop or move it.
|
|
38
|
+
|
|
39
|
+
**What each move animates**, so two moves on one element never fight:
|
|
40
|
+
`liftWords` yPercent of its word spans; `dropLetters` y, scaleX, scaleY and
|
|
41
|
+
opacity of its letters; `reveal` and `openFrom` clip-path; `tick`
|
|
42
|
+
stroke-dashoffset; `pop` scale and opacity; `stamp` scale, rotation and
|
|
43
|
+
opacity; `reshape` left, top, width, height and border-radius (position the
|
|
44
|
+
element absolutely); `diveThrough` the layer's scale and the `next`
|
|
45
|
+
element's visibility; `knock` rotation; `impact` the shake layer's x and
|
|
46
|
+
rotation; `converge`, `hop` and `cursorPath` write `style.transform`
|
|
47
|
+
directly. `typewrite` changes only the text.
|
|
48
|
+
|
|
49
|
+
### Contact
|
|
50
|
+
|
|
51
|
+
| Call | Options | Returns |
|
|
52
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------- |
|
|
53
|
+
| `hop(tl, el, at, o)` | `height=140`, `duration=0.5` (air time), `squash=0.2` | the landing |
|
|
54
|
+
| `impact(tl, at, o)` | `shake` (a layer, not the camera world), `amount=16`, `duration=0.6`, `split: [left, right]`, `spread=140` | `at` |
|
|
55
|
+
| `knock(tl, els, at, o)` | `push=48`, `gap=0.11`, `tilt=7`, `axis="x"` or `"y"` | the last contact |
|
|
56
|
+
|
|
57
|
+
### Camera
|
|
58
|
+
|
|
59
|
+
`const cam = kit.camera(tl, world, keys, o)` drives `world`, a layer holding
|
|
60
|
+
the whole scene in world pixels. It returns `{ plan, at(t), toScreen(t, x, y) }`.
|
|
61
|
+
Make `world` an absolutely positioned element at left 0, top 0 (any size;
|
|
62
|
+
place scenes inside it at their world coordinates). The camera owns its
|
|
63
|
+
transform and sets its transform-origin to 0 0: never animate `world`
|
|
64
|
+
yourself; move things inside it. A key's `x, y` is the world point shown at
|
|
65
|
+
the centre of the frame, so `{ x: 960, y: 540, zoom: 1 }` shows the first
|
|
66
|
+
1920 × 1080 of the world unchanged.
|
|
67
|
+
|
|
68
|
+
- **Keys**: `[{ x, y, zoom=1, rotate=0 }, { at, x, y, zoom, rotate, move, duration }, ...]`.
|
|
69
|
+
The first key is the start. `move` is a curve name (`whip` by default,
|
|
70
|
+
`glide` for slow pushes, `cut` for a jump); `duration=0.9`.
|
|
71
|
+
- **Options**: `width=1920`, `height=1080`, `duration` (default the last move),
|
|
72
|
+
`lead` (seconds each move starts early), `handheld: { amp=6, rotate=0.2, rate=0.5, seed=7 }`,
|
|
73
|
+
`rests: [[from, to], ...]` (exactly still there), `shakes: [{ at, amount=14, decay=9 }]`,
|
|
74
|
+
`layers: [{ el, depth }]` (0 pinned, 0.5 far, 1 the world, above 1 near).
|
|
75
|
+
- Pure helpers: `cameraAt(plan, t, o)`, `atDepth(cam, depth)`, `toScreen(cam, x, y)`.
|
|
76
|
+
|
|
77
|
+
### Deep zoom, light, texture
|
|
78
|
+
|
|
79
|
+
| Call | Options | Returns |
|
|
80
|
+
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
|
81
|
+
| `deepZoom(tl, world, at, o)` | `anchor={x,y}` (world point, default the centre), `from=1`, `to=100` (any factor, up to about 1000), `screenFrom`, `screenTo` (where the anchor sits on screen; default the centre), `duration=3`, `ease="glide"`, `width`, `height` | end |
|
|
82
|
+
| `lightGround(tl, el, at, o)` | `rise=0.9`, `hold=0.6`, `drain=0.9`, `x`, `y` (default below the frame), `reach=1.15`, `color` (an `r, g, b` string), `ease="glide"`; on a canvas it paints, on other elements it sets `--light`, `--light-r`, `--light-x`, `--light-y` (with units) | the flood |
|
|
83
|
+
| `rings(tl, el, at, o)` | `count=4`, `duration=1.2`, `stagger=0.14`, `x`, `y` (default the centre), `ease="snap"`; reveals `el` (the next scene) through expanding rings | fully shown |
|
|
84
|
+
| `silk(tl, canvas, at, duration, o)` | `colors` (two or more hex), `seed=1`, `speed=0.08`, `scale=2.2`, `warp=1.2`, `cols=64`, `rows` | end |
|
|
85
|
+
| `belt(tl, items, at, o)` | `speed=240` (px/s), `stop` (timeline time it comes to rest), `spacing=360`, `axis="x"`, `direction=-1`, `rampIn=0.6`, `rampOut=0.9`, `origin`, `wrap` | `{ stop, at(t), clock(t) }` |
|
|
86
|
+
| `brushStroke(tl, canvas, at, o)` | `path` (SVG path) or `points`, `width=28`, `bristles=48`, `dryness=0.65`, `color`, `duration=0.8`, `seed=3`, `ease` | when the brush lifts |
|
|
87
|
+
| `grain(el, o)` | `amount=0.05`, `seed=9`, `size=128`; a fixed overlay so dark gradients do not band; identical on every frame | the tile's data URL |
|
|
88
|
+
|
|
89
|
+
### Print look (riso, screen print)
|
|
90
|
+
|
|
91
|
+
| Call | Options | Returns |
|
|
92
|
+
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
93
|
+
| `printInk(el, o)` | `offset={x:0,y:0}` (fixed misregistration), `cell=7` (halftone spacing px), `angle=15`, `amount=0.86` (ink coverage), `rough=0.18`, `seed=3`; sets multiply blending and a halftone mask, so overlapping inks overprint | the tile's data URL |
|
|
94
|
+
| `misregister(tl, layers, at, o)` | `distance=26` px (or `from: [{x,y}, ...]`, one per layer), `seed=11`, `spring="soft"` or `ease` with `duration=0.8`, `apart=false` (true drifts apart instead of settling) | when the inks settle |
|
|
95
|
+
| `paperTexture(el, o)` | `size=256`, `amount=0.06`, `tint="#fdf8ee"`, `fibres=160`, `seed=5`; identical on every frame | the tile's data URL |
|
|
96
|
+
|
|
97
|
+
Give each ink its own layer (one flat colour per layer, e.g. fluorescent pink
|
|
98
|
+
and blue), lay them over paper, and let them settle into register on the beat.
|
|
99
|
+
`printInk` uses the element's `mask-image` and `translate`. Pure helpers:
|
|
100
|
+
`halftoneTile`, `misregisterAt`, `paperTile`.
|
|
101
|
+
|
|
102
|
+
`deepZoom` owns `world`'s transform like the camera does: a dive or pull-out
|
|
103
|
+
keeps its anchor exactly where it is keyed on screen at any depth. Pure
|
|
104
|
+
helpers: `deepZoomAt`, `lightLevel`, `ringsAt`, `silkField`, `beltAt`,
|
|
105
|
+
`grainTile`.
|
|
106
|
+
|
|
107
|
+
### Cursor
|
|
108
|
+
|
|
109
|
+
`const { end, presses } = kit.cursorPath(tl, cursor, at, stops, o)`. Stops are
|
|
110
|
+
`{ x, y }` or `{ el }`, each with optional `click: true`, `hold=0.15` and
|
|
111
|
+
`duration`. Options: `speed=1500` (px/s), `press=0.09`, `release=0.26`,
|
|
112
|
+
`bow=0.12`, `tip=[6, 4]` (the hotspot), `space`. Script each pressed state and
|
|
113
|
+
its sound from `presses`.
|
|
114
|
+
|
|
115
|
+
### Sound
|
|
116
|
+
|
|
117
|
+
`kit.cue(tl, at, sfx, { gain=1, x, pan, send, name })` marks a sound where the
|
|
118
|
+
event happens. `x` is the object's screen x and pans with it; `pan` (-1..1)
|
|
119
|
+
overrides it; `send` (0..1) is its distance. Then run
|
|
120
|
+
`<node> "<motion bin>/cues.mjs" <project>`.
|
|
121
|
+
|
|
122
|
+
### Timing and helpers
|
|
123
|
+
|
|
124
|
+
- **Springs** (`spring` options): `snappy`, `bouncy`, `soft`, `heavy`, `whip`.
|
|
125
|
+
`kit.springEase(name)` gives a GSAP ease; `kit.settleTime(name)` gives its length.
|
|
126
|
+
- **Curves** (`ease` and `move`): `snap`, `drop`, `glide`, `travel`, `whip`,
|
|
127
|
+
`settle`, `bounce`, `firm`, `cut`.
|
|
128
|
+
- `drive(tl, at, duration, draw)`: calls `draw(localTime)` every frame, seeks
|
|
129
|
+
included; draw anything (counters, canvas, SVG) as a pure function of time.
|
|
130
|
+
- `split(el, "words" | "chars", { mask })` returns spans; `centerOf(el, space)`
|
|
131
|
+
and `rectOf(el, space)` measure layout without transforms; `rng(seed)` and
|
|
132
|
+
`noise(seed, t)` are seeded.
|
|
133
|
+
|
|
134
|
+
## Score (`score.json` for `score-synth.mjs`)
|
|
135
|
+
|
|
136
|
+
Run `<node> "<motion bin>/score-synth.mjs" score.json assets/audio`. It writes
|
|
137
|
+
`music.wav`, `sfx.wav` and `tempo-map.json` (beats, bars, hits, merges,
|
|
138
|
+
balance) in under a second.
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"bpm": 84,
|
|
143
|
+
"duration": 24,
|
|
144
|
+
"seed": 3,
|
|
145
|
+
"style": "lofi",
|
|
146
|
+
"key": "F",
|
|
147
|
+
"scale": "major",
|
|
148
|
+
"chords": ["Fmaj7", "Em7", "Dm7", "Cmaj7"],
|
|
149
|
+
"sections": [
|
|
150
|
+
{ "name": "intro", "from": 0, "energy": 0.3 },
|
|
151
|
+
{ "name": "groove", "from": 2.9, "energy": 0.7 }
|
|
152
|
+
],
|
|
153
|
+
"hits": [
|
|
154
|
+
{ "t": 3.0, "sfx": "tap" },
|
|
155
|
+
{ "beat": 8, "sfx": "chime" },
|
|
156
|
+
{ "bar": 4, "sfx": "impact" }
|
|
157
|
+
],
|
|
158
|
+
"cues": "cues.json",
|
|
159
|
+
"room": "room",
|
|
160
|
+
"duck": 0.55,
|
|
161
|
+
"ending": "resolve",
|
|
162
|
+
"air": true,
|
|
163
|
+
"music": true
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- **bpm** 40–220; **duration** in seconds; **seed** any integer.
|
|
168
|
+
- **style**: `pulse` (four on the floor), `cinematic` (swells and low hits),
|
|
169
|
+
`minimal` (sparse keys), `lofi` (swung eighths, dusty keys, round bass,
|
|
170
|
+
soft kit, vinyl and tape wobble).
|
|
171
|
+
- **key** and **scale** (`major` or `minor`) pick default chords; `chords`
|
|
172
|
+
overrides them.
|
|
173
|
+
- **sections**: energy 0–1 brings parts in. In `lofi`: keys and vinyl alone
|
|
174
|
+
below 0.25, kick and snare from 0.25, hats from 0.4, the full kit from 0.5.
|
|
175
|
+
- **hits**: `t` (seconds), `beat` or `bar`, `sfx`, optional `gain` (0–2),
|
|
176
|
+
`pan`, `send`, `name`. Sounds: `tap`, `press`, `knock`, `chime`, `thud`,
|
|
177
|
+
`plip`, `paper`, `breath`, `click`, `tick`, `snap`, `pop`, `glitch`,
|
|
178
|
+
`whoosh`, `whoosh-short`, `riser`, `swell`, `impact`, `sub-drop`, `sting`,
|
|
179
|
+
`shimmer`, `typing`.
|
|
180
|
+
- **cues**: the file `cues.mjs` exported; its hits and camera air join these.
|
|
181
|
+
- **room**: `none`, `booth`, `room`, `hall`. **duck**: music level under the
|
|
182
|
+
heaviest hit (1 = none). **ending**: `resolve` or `cut`. **air**: camera air
|
|
183
|
+
on or off. **music**: false for effects only.
|
|
184
|
+
|
|
185
|
+
## Licensed or supplied music
|
|
186
|
+
|
|
187
|
+
To cut a track the user supplies to the picture instead of synthesising one:
|
|
188
|
+
`<node> "<motion bin>/music-fit.mjs" <track> --duration <s> [--land <trackTime>@<filmTime>] [--out assets/audio]`.
|
|
189
|
+
It finds the tempo and downbeats, cuts whole bars on downbeats with short
|
|
190
|
+
crossfades so the length is exact, lands the chosen downbeat (`--land`, snapped
|
|
191
|
+
to the nearest one) on a film time, and writes `music.wav` plus
|
|
192
|
+
`music-fit.json` with the downbeats in film time. Put hits on those downbeats.
|
|
193
|
+
Constant tempo and 4/4 only.
|
|
194
|
+
|
|
195
|
+
## Tall frame (1080 × 1920)
|
|
196
|
+
|
|
197
|
+
Fill the frame and go big. The feeds cover only a bar over the top 138 px, a
|
|
198
|
+
caption over the bottom 422 px and buttons over the right 179 px from y 840
|
|
199
|
+
down; keep words out from under those.
|
|
200
|
+
|
|
201
|
+
## Render
|
|
202
|
+
|
|
203
|
+
| Step | Command |
|
|
204
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
205
|
+
| Final with blur | `<node> "<motion bin>/motion-blur.mjs" <project> renders/<name>-v1.mp4` (the one render, at feed loudness; run it in the background) |
|
|
206
|
+
| Stills | `<node> "<motion bin>/hyperframes.mjs" snapshot <project> --at 1,4,8,12 --describe false` (several at once) |
|
|
@@ -15,7 +15,7 @@ For GSAP:
|
|
|
15
15
|
- **Do not** call `tl.play()` for render-critical motion.
|
|
16
16
|
- **Do not** create empty tweens only to set duration; use `data-duration` on the clip instead.
|
|
17
17
|
|
|
18
|
-
Use the adjacent `gsap.md`, `gsap-timeline-and-labels.md` and `gsap-easing-and-stagger.md` for GSAP mechanics. These technical references do not
|
|
18
|
+
Use the adjacent `gsap.md`, `gsap-timeline-and-labels.md` and `gsap-easing-and-stagger.md` for GSAP mechanics. These technical references do not choose the design.
|
|
19
19
|
|
|
20
20
|
## Determinism Rules
|
|
21
21
|
|
|
@@ -41,9 +41,9 @@ Build the visible end-state in static HTML and CSS first, then animate from/to t
|
|
|
41
41
|
- **The root composition's total duration (render length / frame count) is fixed at compile time**, read once from the static root `data-duration` before scripts run, like `data-width` / `data-height`. A script or `--variables` value that rewrites the root `data-duration` afterward is ignored. To vary render length per output, author the root `data-duration` directly. (A _clip's_ own `data-duration` is re-read from the live DOM, so scripts/variables can still drive clip lengths. Only when the root omits `data-duration` does the renderer probe the live DOM / timeline for total length.)
|
|
42
42
|
- Scene containers should fill the scene with `width: 100%; height: 100%; box-sizing: border-box`.
|
|
43
43
|
- Use padding, flex, grid, and `max-width` for layout. Avoid positioning main content with hardcoded `top`/`left` offsets when a layout container can do it.
|
|
44
|
-
-
|
|
44
|
+
- Absolute layers are appropriate for deliberately placed design elements; keep one positioning model per scene.
|
|
45
45
|
- Prefer transforms and opacity for animation.
|
|
46
|
-
- Keep text inside its intended container.
|
|
46
|
+
- Keep text inside its intended container. Wrap, resize or use `window.__hyperframes.fitTextFontSize(text, { maxWidth, fontFamily, fontWeight })` deliberately; never let text clip silently.
|
|
47
47
|
- For text measurement without DOM reflow, use `window.__hyperframes.pretext`. Measure off a canvas instead of writing into the page and reading it back, so nothing reflows: `pretext.prepare(text, font)` then `pretext.layout(prepared, maxWidth, lineHeight)` → `{ lineCount, height }`. `prepare` does the font measurement; everything downstream of a prepared string is arithmetic and cheap enough to run per frame. `fitTextFontSize` is built on it.
|
|
48
48
|
- `layout` gives you height, not width. To size a container to its text (shrinkwrap), use `pretext.prepareWithSegments(text, font)` and then `pretext.measureNaturalWidth(prepared)` for the single-line width, or `pretext.measureLineStats(prepared, maxWidth)` for `{ lineCount, maxLineWidth }`.
|
|
49
49
|
- `font` is a CSS font shorthand string, e.g. `"700 90px Inter"`.
|
|
@@ -11,14 +11,14 @@ Each has `.in`, `.out`, `.inOut` variants.
|
|
|
11
11
|
| `power1.out`, `power2.out` | Gentle motion for secondary elements (a caption fade, a small shift). NOT the entrance default. |
|
|
12
12
|
| `power3.out` (house default), `power4.out` | The standard long-tail settle. Entrances, title cards, hero reveals. |
|
|
13
13
|
| `sine.inOut` | Long, slow, calm motion. Crossfades, ambient drift. |
|
|
14
|
-
| `back.out(1.7)` | Overshoot then settle.
|
|
15
|
-
| `elastic.out(1, 0.3)` | Springy bounce. Same
|
|
14
|
+
| `back.out(1.7)` | Overshoot then settle. A chosen register (playful, physical), never a default. |
|
|
15
|
+
| `elastic.out(1, 0.3)` | Springy bounce. Same register rule; prefer a baked spring (see Spring Eases below). |
|
|
16
16
|
| `expo.inOut` | Snappy, dramatic. Quick transitions between hero scenes. |
|
|
17
17
|
| `none` (linear) | Camera moves with timed counterpoint, mechanical motion. |
|
|
18
18
|
|
|
19
19
|
Pick `.out` for entrances, `.in` for exits, `.inOut` for symmetric moves and continuous motion.
|
|
20
20
|
|
|
21
|
-
**Smooth
|
|
21
|
+
**Smooth by default, bounce by choice**: entrances default to `power3.out` or the baked critically-damped spring (see Spring Eases below); overshoot eases (`back` / `elastic` / `bounce`, or an underdamped spring) are a register the brief chooses for playful or physical work, never the house style.
|
|
22
22
|
|
|
23
23
|
## Easing Vocabulary (character & mood)
|
|
24
24
|
|
|
@@ -26,18 +26,18 @@ Easings are tone of voice: a video that only whispers is boring; one that varies
|
|
|
26
26
|
|
|
27
27
|
The full palette by character (each family has `.in`, `.out`, `.inOut` variants):
|
|
28
28
|
|
|
29
|
-
| Family | Character | Typical use
|
|
30
|
-
| -------------------- | ---------------------------------------------------------------------------- |
|
|
31
|
-
| `power1`–`power4` | Gentle (1) to aggressive (4) acceleration curves | General purpose. **power3 is the house workhorse**; power2 for gentle secondary motion, power4 for dramatic snaps
|
|
32
|
-
| `back(N)` | Overshoot then settle. N controls how far past the target (1=subtle, 4=wild) |
|
|
33
|
-
| `elastic(amp, freq)` | Spring bounce. amp=magnitude, freq=oscillation speed |
|
|
34
|
-
| `bounce` | Ball-drop bouncing |
|
|
35
|
-
| `expo` | Extreme acceleration curve (much steeper than power4) | Premium/luxury reveals, dramatic entrances
|
|
36
|
-
| `sine` | Smooth, organic, no hard edges | Ambient float, breathing,
|
|
37
|
-
| `circ` | Circular acceleration (starts very fast, ends very gentle or vice versa) | Camera moves, scene transitions, orbital motion
|
|
38
|
-
| `steps(N)` | Discrete N-step jumps, no interpolation | Typing effects, cursor blink, counter ticks, retro/digital aesthetics
|
|
29
|
+
| Family | Character | Typical use |
|
|
30
|
+
| -------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `power1`–`power4` | Gentle (1) to aggressive (4) acceleration curves | General purpose. **power3 is the house workhorse**; power2 for gentle secondary motion, power4 for dramatic snaps |
|
|
32
|
+
| `back(N)` | Overshoot then settle. N controls how far past the target (1=subtle, 4=wild) | Chosen register only (playful, physical), never a default. Keep N ≤ 2; prefer a baked spring at ζ 0.6–0.7 (physical settle, see Spring Eases) |
|
|
33
|
+
| `elastic(amp, freq)` | Spring bounce. amp=magnitude, freq=oscillation speed | Same register rule; the baked spring (below) is the physical version |
|
|
34
|
+
| `bounce` | Ball-drop bouncing | Physical-comedy register only (something literally dropping) |
|
|
35
|
+
| `expo` | Extreme acceleration curve (much steeper than power4) | Premium/luxury reveals, dramatic entrances |
|
|
36
|
+
| `sine` | Smooth, organic, no hard edges | Ambient float, breathing, Nolan Burns, anything that loops. `.inOut` for yoyo motion |
|
|
37
|
+
| `circ` | Circular acceleration (starts very fast, ends very gentle or vice versa) | Camera moves, scene transitions, orbital motion |
|
|
38
|
+
| `steps(N)` | Discrete N-step jumps, no interpolation | Typing effects, cursor blink, counter ticks, retro/digital aesthetics |
|
|
39
39
|
|
|
40
|
-
**Mood mapping:** Match easing character to the beat's emotional content. Smooth/organic easings (`sine`, `power1`) feel contemplative and drifting. Aggressive deceleration (`power4.out`, `expo.out`) feels snappy and confident. Spring overshoot (`back.out`) feels bouncy and physical — but bouncy is a register, not an emphasis tool; reach for it only
|
|
40
|
+
**Mood mapping:** Match easing character to the beat's emotional content. Smooth/organic easings (`sine`, `power1`) feel contemplative and drifting. Aggressive deceleration (`power4.out`, `expo.out`) feels snappy and confident. Spring overshoot (`back.out`) feels bouncy and physical — but bouncy is a register, not an emphasis tool; reach for it only when the brief's register is playful or physical. The video's register should guide which character fits — not a formula.
|
|
41
41
|
|
|
42
42
|
## Defaults
|
|
43
43
|
|
|
@@ -58,7 +58,7 @@ Setting defaults at timeline scope is preferred — it documents the motion lang
|
|
|
58
58
|
|
|
59
59
|
## Spring Eases (baked physics, seek-safe)
|
|
60
60
|
|
|
61
|
-
The "iOS feel" is a **damped spring's velocity curve**, not a bounce: a fast launch into a long asymptotic settle. Well-made system animations are critically damped or close to it — they barely overshoot, or don't at all. `power3.out` / `expo.out` approximate that curve; when you want the exact one — or a _physical_ overshoot for
|
|
61
|
+
The "iOS feel" is a **damped spring's velocity curve**, not a bounce: a fast launch into a long asymptotic settle. Well-made system animations are critically damped or close to it — they barely overshoot, or don't at all. `power3.out` / `expo.out` approximate that curve; when you want the exact one — or a _physical_ overshoot for a playful register — bake the spring's closed-form solution into a function ease.
|
|
62
62
|
|
|
63
63
|
Why not a real-time spring library: an interactive spring is a stateful integrator (velocity accumulates frame to frame), which cannot be seeked deterministically — you'd have to simulate frames 0…N−1 to render frame N. The closed form below is a **pure function of progress** — no state, nothing to desync, seek-safe by construction. This is also why interaction-lib spring solvers are banned in compositions.
|
|
64
64
|
|
|
@@ -67,7 +67,7 @@ Why not a real-time spring library: an interactive spring is a stateful integrat
|
|
|
67
67
|
// response ≈ seconds one oscillation would take (0.3–0.6 for entrances)
|
|
68
68
|
// dampingFraction 1.0 = critically damped — smooth settle, NO overshoot (house default)
|
|
69
69
|
// 0.80–0.85 ≈ the iOS system register — ~1–1.5% overshoot, felt not seen
|
|
70
|
-
// 0.60–0.70 =
|
|
70
|
+
// 0.60–0.70 = playful register — ~5–10% overshoot (by choice; replaces back.out)
|
|
71
71
|
function springEase({ response = 0.5, dampingFraction = 1 } = {}) {
|
|
72
72
|
const w = (2 * Math.PI) / response; // undamped natural frequency
|
|
73
73
|
const z = dampingFraction;
|
|
@@ -116,24 +116,24 @@ tl.fromTo(
|
|
|
116
116
|
);
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
| dampingFraction | overshoot | register
|
|
120
|
-
| ----------------- | --------------- |
|
|
121
|
-
| **1.0 (default)** | none (monotone) | The house settle — the exact curve `power3.out` approximates. Product / enterprise / serious tone.
|
|
122
|
-
| 0.80–0.85 | ~1–1.5% | "Alive, not bouncy" — the iOS system default register. The overshoot is felt, not seen.
|
|
123
|
-
| 0.60–0.70 | ~5–10% |
|
|
124
|
-
| < 0.55 | > 12% | Don't. Cartoon-wobble territory.
|
|
119
|
+
| dampingFraction | overshoot | register |
|
|
120
|
+
| ----------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
121
|
+
| **1.0 (default)** | none (monotone) | The house settle — the exact curve `power3.out` approximates. Product / enterprise / serious tone. |
|
|
122
|
+
| 0.80–0.85 | ~1–1.5% | "Alive, not bouncy" — the iOS system default register. The overshoot is felt, not seen. |
|
|
123
|
+
| 0.60–0.70 | ~5–10% | Playful register, by choice (same rule as `back.out`, which this replaces — a spring's second-order settle reads physical where `back` reads cartoon). |
|
|
124
|
+
| < 0.55 | > 12% | Don't. Cartoon-wobble territory. |
|
|
125
125
|
|
|
126
|
-
| response | duration (ζ=1) | feel
|
|
127
|
-
| --------- | -------------- |
|
|
128
|
-
| 0.25–0.35 | 0.37–0.51s | tight snap — chips, small UI
|
|
129
|
-
| 0.35–0.50 | 0.51–0.74s | standard entrance
|
|
130
|
-
| 0.50–0.70 | 0.74–1.03s | weighted hero landing —
|
|
126
|
+
| response | duration (ζ=1) | feel |
|
|
127
|
+
| --------- | -------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| 0.25–0.35 | 0.37–0.51s | tight snap — chips, small UI |
|
|
129
|
+
| 0.35–0.50 | 0.51–0.74s | standard entrance |
|
|
130
|
+
| 0.50–0.70 | 0.74–1.03s | weighted hero landing — when the shot opens on it, start it early so the subject is seen within about half a second |
|
|
131
131
|
|
|
132
132
|
Craft notes:
|
|
133
133
|
|
|
134
134
|
- **ζ=1 vs `power3.out`**: the true spring front-loads harder (~67% vs ~58% travelled at quarter-time) and settles on a longer asymptotic tail; max shape difference ~11%. That long tail is the "premium" read — use it when the settle IS the shot (a wordmark landing, a final lockup).
|
|
135
135
|
- **At ζ<1, overshooting curves go on transforms only** — never on `opacity` (it would push past 1) or color. Split opacity onto its own `power2.out` tween at the same timeline position.
|
|
136
|
-
- **
|
|
136
|
+
- **Default unchanged**: ζ below ~0.8 is a register the brief chooses, never a default. The default of this section is ζ=1 — real spring physics is not a license for bounce.
|
|
137
137
|
|
|
138
138
|
## Stagger
|
|
139
139
|
|
|
@@ -56,13 +56,13 @@ For transforms, autoAlpha, clearProps, and SVG specifics see `./gsap-transforms-
|
|
|
56
56
|
|
|
57
57
|
## Animated properties
|
|
58
58
|
|
|
59
|
-
Prefer these efficient targets when they
|
|
59
|
+
Prefer these efficient targets when they achieve the intended motion:
|
|
60
60
|
|
|
61
61
|
- **Compositor-cheap**: `opacity`, `x`, `y`, `scale`, `scaleX`, `scaleY`, `rotation`, `rotationX`, `rotationY`, `skewX`, `skewY`, `transformOrigin`
|
|
62
62
|
- **Visual fills**: `color`, `backgroundColor`, `borderColor`, `borderRadius`
|
|
63
63
|
- **CSS variables**: `"--hue": 180` etc.
|
|
64
64
|
- **Media `volume`** (on `<audio>` / `<video>`): do not tween it for fades or ducking; use the `data-automation` volume lane (see `data-attributes.md`). A lane wins over a tween on the same element.
|
|
65
|
-
- **DOM text `innerText`** (for numeric counters): tween it directly, e.g. `tl.to(el, { innerText: 100, snap: { innerText: 1 } })` — `snap` keeps it integer; the GSAP inspector recognizes it as a counter. Use a deterministic proxy value with `onUpdate` for locale formatting or suffix logic when the
|
|
65
|
+
- **DOM text `innerText`** (for numeric counters): tween it directly, e.g. `tl.to(el, { innerText: 100, snap: { innerText: 1 } })` — `snap` keeps it integer; the GSAP inspector recognizes it as a counter. Use a deterministic proxy value with `onUpdate` for locale formatting or suffix logic when the design needs it.
|
|
66
66
|
|
|
67
67
|
**Avoid** (use the transform alias instead):
|
|
68
68
|
|
|
@@ -80,7 +80,7 @@ Prefer these efficient targets when they preserve the recipe's behaviour:
|
|
|
80
80
|
- `./gsap-timeline-and-labels.md` — timeline creation, position parameter (`+=`, `<`, `>`), labels, nesting, sub-comp `fromTo` preference, playback control.
|
|
81
81
|
- `./gsap-easing-and-stagger.md` — easing families, stagger objects, function-based values, `gsap.matchMedia()`, `gsap.defaults()`.
|
|
82
82
|
- `./gsap-transforms-and-perf.md` — transform aliases, autoAlpha, `quickTo`, `will-change`, performance rules.
|
|
83
|
-
- The
|
|
83
|
+
- The video's plan defines effects and motion; these API examples are not additional creative instructions.
|
|
84
84
|
|
|
85
85
|
## Best Practices
|
|
86
86
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# GG runtime inputs and assets
|
|
2
2
|
|
|
3
|
-
This is implementation support, not a creative workflow.
|
|
4
|
-
|
|
5
|
-
colours, logos and media without adding a second look-selection process.
|
|
3
|
+
This is implementation support, not a creative workflow. Bind approved text,
|
|
4
|
+
fonts, colours, logos and media without adding a second look-selection process.
|
|
6
5
|
|
|
7
6
|
`hf` in these references is shorthand for the exact bundled launcher command
|
|
8
7
|
in the system prompt; expand it, never run bare `hf` or `npx hyperframes`.
|
|
@@ -14,13 +13,13 @@ package installs, cloud rendering or publishing without explicit permission.
|
|
|
14
13
|
- Keep original captures/uploads in `sources/`; use local `assets/` for the
|
|
15
14
|
files consumed by the composition. Never overwrite originals or finished renders.
|
|
16
15
|
- A reusable kit lives at `brand-kits/<slug>/Motion.md` in the Motion workspace.
|
|
17
|
-
Keep it read-only for ordinary video work
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
- Root output duration is a static composition contract. If
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
Keep it read-only for ordinary video work; preserve legacy briefs rather than
|
|
17
|
+
duplicating plans.
|
|
18
|
+
- A longer title or a different aspect ratio calls for a deliberate layout adjustment, not a silent
|
|
19
|
+
crop.
|
|
20
|
+
- Root output duration is a static composition contract. If an input changes
|
|
21
|
+
the duration, update the authored root explicitly; a runtime variable cannot
|
|
22
|
+
silently change the compiled video length.
|
|
24
23
|
|
|
25
24
|
## Existing helpers (only when needed)
|
|
26
25
|
|
|
@@ -37,16 +36,22 @@ Inspect helper help for less common operations; do not guess options. Fonts,
|
|
|
37
36
|
Three.js and library assets remain available offline, but their existence does
|
|
38
37
|
not require using them. Respect actual licenses and required brand typography.
|
|
39
38
|
|
|
39
|
+
`fonts.mjs add` returns `head`: a `<style>` block of `@font-face` rules with
|
|
40
|
+
paths from the project folder. Paste it into the composition `<head>`.
|
|
41
|
+
`hf check` only recognises fonts declared in the page, so linking
|
|
42
|
+
`assets/fonts/fonts.css` instead renders fine but is reported as missing fonts.
|
|
43
|
+
|
|
44
|
+
GSAP loads from the pinned CDN script in
|
|
45
|
+
[minimal-composition](minimal-composition.md). There is no local copy in the
|
|
46
|
+
bundle; do not search for one or copy one from another project.
|
|
47
|
+
|
|
40
48
|
Shared music and SFX are at `../../assets/music/` and `../../assets/sfx/` relative
|
|
41
49
|
to this document. Upstream metadata can retain historical `skills/brag/` paths;
|
|
42
50
|
resolve its filenames under these shared asset roots, not the removed skill.
|
|
43
51
|
Those provenance notes are not instructions to invoke an old workflow.
|
|
44
52
|
Preserve credits, cue maps and SFX analysis. Copy only used
|
|
45
|
-
assets into the video project. The
|
|
53
|
+
assets into the video project. The plan or user determines whether
|
|
46
54
|
sound belongs in the video; do not automatically add music or hits.
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
repeat its checks as a separate checklist. Request permission before
|
|
51
|
-
installing missing FFmpeg/browser software; a detector setup failure does not
|
|
52
|
-
justify skipping validation. Never upload user files to resolve a local blocker.
|
|
56
|
+
Request permission before installing missing FFmpeg/browser software. Never
|
|
57
|
+
upload user files to resolve a local blocker.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# lint, check, snapshot
|
|
2
2
|
|
|
3
|
-
Motion
|
|
3
|
+
Motion does not run these as delivery gates. Use them only for targeted debugging of a concrete failure. `snapshot` captures still frames and zoomed crops; `validate`, `inspect` and `layout` are deprecated because `check` covers them.
|
|
4
4
|
|
|
5
5
|
## Discipline (motion-heavy work)
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ For a concrete problem during authoring or editing:
|
|
|
9
9
|
- Use `lint` for a static-code failure or `check --snapshots` for runtime/layout evidence, not both by default.
|
|
10
10
|
- Look at the returned images before changing the animation: a diagnostic must not become an alternative art direction.
|
|
11
11
|
- Treat layout errors as defects unless a snapshot proves the layering is intentional, in which case mark it with `data-layout-allow-overflow` / `data-layout-allow-overlap` / `data-layout-allow-occlusion` / `data-layout-allow-caption-zone` (caption band only).
|
|
12
|
-
- Existing meaningful motion assertions may remain, but
|
|
12
|
+
- Existing meaningful motion assertions may remain, but EZ does not require a new `*.motion.json` sidecar for every video. Use stills of the render for liveness, especially for canvas/WebGL. No detector or screenshot proves playback was watched.
|
|
13
13
|
|
|
14
14
|
## lint
|
|
15
15
|
|
|
@@ -68,7 +68,7 @@ hf check --frame-check # media (img/svg/video/canvas) out-of-frame detection
|
|
|
68
68
|
|
|
69
69
|
`--caption-zone` takes fractional band geometry (`x0/y0/x1/y1` required, 0-1 fractions of the composition's own canvas, portrait included) with optional `severity` and comma-separated `seek` fractions; it flags a text element's DOM box (`getBoundingClientRect`) that overlaps the band. Waive intentional lower-third copy with `data-layout-allow-caption-zone` on the element or its nearest wrapper (see Escape hatches). `--frame-check` reports media elements breaching the canvas beyond `max(120px, 6% of the min canvas dimension)`.
|
|
70
70
|
|
|
71
|
-
**Fixing contrast errors** — thresholds are 4.5:1 for normal text, 3:1 for large text (24px+, or 19px+ bold). The finding's `suggestedColor` already picks the nearest compliant color in the right direction (brighten on dark backgrounds, darken on light); apply an allowed correction, or resolve a conflict with locked source/brand colours before changing them.
|
|
71
|
+
**Fixing contrast errors** — thresholds are 4.5:1 for normal text, 3:1 for large text (24px+, or 19px+ bold). The finding's `suggestedColor` already picks the nearest compliant color in the right direction (brighten on dark backgrounds, darken on light); apply an allowed correction, or resolve a conflict with locked source/brand colours before changing them. Look at a still of the changed moment; do not run the full diagnostic checklist.
|
|
72
72
|
|
|
73
73
|
## Motion verification (`*.motion.json` sidecar)
|
|
74
74
|
|
|
@@ -67,3 +67,9 @@ What the runtime actually requires:
|
|
|
67
67
|
Everything else in the skeleton is ordinary HTML and CSS: the `#root` box, `.clip` positioning, and fonts are yours to choose.
|
|
68
68
|
|
|
69
69
|
This pattern is **standalone** (top-level `index.html`) — no `<template>` wrapper around the root. For sub-compositions (files loaded by `data-composition-src`), see `sub-compositions.md`.
|
|
70
|
+
|
|
71
|
+
## Vertical (9:16)
|
|
72
|
+
|
|
73
|
+
For phone-first video, set the viewport meta to `width=1080, height=1920`, give the root `data-width="1080"` and `data-height="1920"`, and render with the matching size (`--resolution portrait`). Everything else stays the same.
|
|
74
|
+
|
|
75
|
+
Size type against the frame's width, not its height: a 96 px headline that suits a 1920 px-wide frame takes over half the width of a 1080 px one, so check that the longest word fits. When the video will play in a feed (Instagram, TikTok, YouTube Shorts), keep words out from under the apps' own bar, caption and buttons: on 1080×1920, the top 138 px, the bottom 422 px and the right 179 px from y 840 down.
|
|
@@ -57,7 +57,7 @@ Failure modes:
|
|
|
57
57
|
|
|
58
58
|
| Code | Meaning |
|
|
59
59
|
| -------------------------- | -------------------------------------------------------------------------- |
|
|
60
|
-
| `preview-not-running` | Start Studio first with `hf preview --background`.
|
|
60
|
+
| `preview-not-running` | Start Studio first with `hf preview --background`. |
|
|
61
61
|
| `ambiguous-preview-server` | Multiple matching Studio servers are open; rerun with one listed `--port`. |
|
|
62
62
|
| `preview-port-mismatch` | The requested `--port` is not one of the matching Studio servers. |
|
|
63
63
|
| `no-selection` | Studio is open, but the user has not selected an element yet. |
|
|
@@ -99,7 +99,7 @@ Validation runs before any server boots, so an invalid value exits cleanly witho
|
|
|
99
99
|
|
|
100
100
|
## render
|
|
101
101
|
|
|
102
|
-
> A clear video request authorizes a new, versioned local render. Preview is available when useful, not a mandatory approval checkpoint. Ask only for unresolved inputs, material choices or permission to overwrite an existing export
|
|
102
|
+
> A clear video request authorizes a new, versioned local render. Preview is available when useful, not a mandatory approval checkpoint. Ask only for unresolved inputs, material choices or permission to overwrite an existing export. The final render screens itself for harmful flashing.
|
|
103
103
|
|
|
104
104
|
```bash
|
|
105
105
|
hf render # standard MP4 from cwd
|
|
@@ -153,4 +153,4 @@ hf render --docker # byte-identical
|
|
|
153
153
|
Keep renders and diagnostics local. Feedback submission, issue filing, publishing
|
|
154
154
|
and cloud rendering are not automatic completion steps. They require explicit
|
|
155
155
|
user authorization; do not send source files, private assets or logs upstream.
|
|
156
|
-
Use
|
|
156
|
+
Use EZ's `reveal.mjs` to select the delivered local file.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: app-walkthrough
|
|
3
|
+
description: Job skill for showing how an app or product is used, step by step, on rebuilt real screens. Adds walkthrough questions, the screen-rebuild method, moves and pitfalls. Load once, before asking.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# App walkthrough
|
|
7
|
+
|
|
8
|
+
A walkthrough is the product in use: open it, do the task, get the
|
|
9
|
+
result. Build it as the `motion` skill describes; this page adds what is
|
|
10
|
+
specific to walkthroughs.
|
|
11
|
+
|
|
12
|
+
## Ask (on the motion skill's single card)
|
|
13
|
+
|
|
14
|
+
- "Which task should the video walk through?" Offer the two or three tasks the
|
|
15
|
+
prompt or screenshots suggest, plus "Let EZ Motion choose".
|
|
16
|
+
- "Where will people mostly watch this?" (from the `motion` skill).
|
|
17
|
+
- "Should it have music?" (from the `motion` skill).
|
|
18
|
+
- "Which idea should we go with?" Pitches below, recommended marked, plus "Let
|
|
19
|
+
EZ Motion choose".
|
|
20
|
+
|
|
21
|
+
Without screenshots, end with one plain line: "Send me a screenshot of each
|
|
22
|
+
step of that task, in order. Phone photos of the screen are fine." Do not ask
|
|
23
|
+
for a shot list.
|
|
24
|
+
|
|
25
|
+
## Rebuild the screens
|
|
26
|
+
|
|
27
|
+
Rebuild each screen as HTML at the screenshot's own size, with its states
|
|
28
|
+
scripted, its text big enough to read, one close-up per step and a cursor that
|
|
29
|
+
presses. Start from the `screen-replica-steps` piece. Hide account names,
|
|
30
|
+
emails and anything private. Data on screen comes from
|
|
31
|
+
their screenshots or files, never invented.
|
|
32
|
+
|
|
33
|
+
## Ideas that suit walkthroughs
|
|
34
|
+
|
|
35
|
+
- **Follow the hand.** One continuous camera that rides the cursor from step to
|
|
36
|
+
step; each click opens the next framing.
|
|
37
|
+
- **The request becomes the result.** The thing the user types or picks grows
|
|
38
|
+
into what the app gives back.
|
|
39
|
+
- **The app's own transition.** Use the app's real sheet, drawer or page
|
|
40
|
+
animation as the handoff between steps.
|
|
41
|
+
- **Before the tap, after the tap.** Each step is a held "before" frame, one
|
|
42
|
+
press, and the change it causes.
|
|
43
|
+
|
|
44
|
+
## Beats that work
|
|
45
|
+
|
|
46
|
+
- Open on the moment that matters most (the result), then rewind to how it is
|
|
47
|
+
done, or open straight on the first step with the cursor already moving.
|
|
48
|
+
- One step per beat, with a close-up on the control being used.
|
|
49
|
+
- Hold still on the result long enough to read it. That is the rest.
|
|
50
|
+
- End on the app's name or icon and where to get it.
|
|
51
|
+
|
|
52
|
+
## Moves
|
|
53
|
+
|
|
54
|
+
`kit.cursorPath` with press and release; `kit.camera` following the cursor;
|
|
55
|
+
`kit.typewrite` for typed input; `kit.tick` for completed steps;
|
|
56
|
+
`kit.reshape` from the pressed control into the result. Pieces:
|
|
57
|
+
`screen-replica-steps`, `request-to-result`, `cursor-click`, `phone-frame`,
|
|
58
|
+
`browser-window`, `camera-rig`.
|
|
59
|
+
|
|
60
|
+
## Pitfalls
|
|
61
|
+
|
|
62
|
+
- Screenshots placed flat and slid around. Rebuild them.
|
|
63
|
+
- Whole screens shown small: text unreadable at phone size.
|
|
64
|
+
- The cursor teleporting, or changes happening without a click.
|
|
65
|
+
- Steps of equal length with no rest on the result.
|
|
66
|
+
- Made-up names, numbers or results.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: before-after
|
|
3
|
+
description: Job skill for a before-and-after video, showing life without the product, then with it. Adds before/after questions, idea patterns, moves and pitfalls. Load once, before asking.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Before and after
|
|
7
|
+
|
|
8
|
+
The viewer should feel the difference, not read it. Build it as the `motion`
|
|
9
|
+
skill describes; this page adds what is specific to comparisons.
|
|
10
|
+
|
|
11
|
+
## Ask (on the motion skill's single card)
|
|
12
|
+
|
|
13
|
+
- "What's the annoying part of life without it?" Offer two or three guesses
|
|
14
|
+
from the prompt, plus "Let EZ Motion choose".
|
|
15
|
+
- "Where will people mostly watch this?" (from the `motion` skill).
|
|
16
|
+
- "Should it have music?" (from the `motion` skill).
|
|
17
|
+
- "Which idea should we go with?" Pitches below, plus "Let EZ Motion choose".
|
|
18
|
+
|
|
19
|
+
## Ideas that suit comparisons
|
|
20
|
+
|
|
21
|
+
- **The same task, twice, side by side.** Both halves start together; the
|
|
22
|
+
"before" side keeps getting interrupted while the "after" side simply
|
|
23
|
+
finishes. Then the losing half falls away.
|
|
24
|
+
- **One drawing, broken and whole.** A shape or line is drawn twice: broken up
|
|
25
|
+
by the problem on one side, unbroken on the other. The whole one becomes the
|
|
26
|
+
logo.
|
|
27
|
+
- **Rewind.** Play the messy version, rewind it in one motion, and play it
|
|
28
|
+
again with the product.
|
|
29
|
+
|
|
30
|
+
The comparison must use one measure the viewer can see (time, steps, mess),
|
|
31
|
+
shown on both sides in the same way.
|
|
32
|
+
|
|
33
|
+
## Beats that work
|
|
34
|
+
|
|
35
|
+
- Set up both sides in one frame so the comparison is fair.
|
|
36
|
+
- Let the problem build, quickening, on the "before" side.
|
|
37
|
+
- A held breath when the "after" side finishes: a real, still rest.
|
|
38
|
+
- The winning side's result carries into the name.
|
|
39
|
+
|
|
40
|
+
## Moves
|
|
41
|
+
|
|
42
|
+
`kit.impact` for interruptions; `kit.camera` with a local shake on one side
|
|
43
|
+
only; `kit.openFrom` from the finished result; `kit.converge` into the logo.
|
|
44
|
+
Pieces: `before-after-split`, `open-from-subject`, `gather-to-logo`,
|
|
45
|
+
`camera-rig`.
|
|
46
|
+
|
|
47
|
+
## Pitfalls
|
|
48
|
+
|
|
49
|
+
- Two separate scenes, before then after, with a cut between. Show them
|
|
50
|
+
together, or carry one into the other.
|
|
51
|
+
- An unfair comparison: different tasks or different measures on each side.
|
|
52
|
+
- Captions that state the difference instead of showing it.
|
|
53
|
+
- Invented statistics about the improvement.
|