wizz-method 2.21.0 → 2.23.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.
Files changed (179) hide show
  1. package/THIRD-PARTY-NOTICES.md +24 -0
  2. package/package.json +4 -2
  3. package/removals.txt +3 -0
  4. package/skills-registry.yaml +133 -4
  5. package/src/bmm-skills/1-analysis/research/wizz-market-research/steps/step-06-research-completion.md +27 -0
  6. package/src/bmm-skills/1-analysis/wizz-set-feature/SKILL.md +1 -1
  7. package/src/bmm-skills/4-implementation/wizz-code-review/SKILL.md +1 -1
  8. package/src/bmm-skills/4-implementation/wizz-create-story/SKILL.md +1 -1
  9. package/src/bmm-skills/4-implementation/wizz-dev-story/SKILL.md +8 -1
  10. package/src/bmm-skills/4-implementation/wizz-quick-dev/SKILL.md +2 -2
  11. package/src/bmm-skills/4-implementation/wizz-quick-dev/step-03-implement.md +2 -0
  12. package/src/bmm-skills/4-implementation/wizz-sprint-status/SKILL.md +1 -1
  13. package/src/core-skills/wizz-party-mode/customize.toml +3 -3
  14. package/src/modules/lowticket/README.md +2 -1
  15. package/src/modules/lowticket/module.yaml +1 -1
  16. package/src/modules/lowticket/skills/wizz-clone-do-expert/SKILL.md +86 -0
  17. package/src/modules/lowticket/skills/wizz-clone-do-expert/references/clone-prompt-template.md +21 -0
  18. package/src/modules/lowticket/skills/wizz-lowticket-trafego/references/reguas.md +2 -0
  19. package/src/modules/wizz/_shared/cerebro.md +1 -1
  20. package/src/modules/wizz/_shared/organizacao.md +2 -2
  21. package/src/modules/wizz/_shared/video-pipeline.md +2 -0
  22. package/src/modules/wizz/agents/wizz-copy/SKILL.md +1 -0
  23. package/src/modules/wizz/agents/wizz-copy/customize.toml +5 -0
  24. package/src/modules/wizz/agents/wizz-copy/knowledge/playbook.md +3 -2
  25. package/src/modules/wizz/agents/wizz-growth/customize.toml +7 -2
  26. package/src/modules/wizz/agents/wizz-growth/knowledge/playbook.md +3 -2
  27. package/src/modules/wizz/agents/wizz-social/knowledge/blueprint-roteiro-viral.md +14 -0
  28. package/src/modules/wizz/agents/wizz-social/knowledge/legenda-instagram.md +12 -0
  29. package/src/skills-lib/wizz-cerebro/SKILL.md +18 -5
  30. package/src/skills-lib/wizz-design-needs/SKILL.md +7 -0
  31. package/src/skills-lib/wizz-design-needs/references/design-state.md +34 -2
  32. package/src/skills-lib/wizz-design-needs/references/gap-analysis.md +1 -1
  33. package/src/skills-lib/wizz-design-needs/scripts/design_state.py +305 -0
  34. package/src/skills-lib/wizz-design-needs/scripts/tests/test_design_state.py +143 -0
  35. package/src/skills-lib/wizz-impeccable/references/design-rules.md +18 -0
  36. package/src/skills-lib/wizz-ios-build/SKILL.md +61 -0
  37. package/src/skills-lib/wizz-motion-3d-director/references/motion-paths.md +2 -0
  38. package/src/skills-lib/wizz-offer-forge/SKILL.md +2 -2
  39. package/src/skills-lib/wizz-paid-ads/SKILL.md +2 -1
  40. package/src/skills-lib/wizz-paywall-upgrade-cro/SKILL.md +1 -0
  41. package/src/skills-lib/{wizz-pesquisa-de-publico-do-piva → wizz-pesquisa-de-publico}/README.md +13 -13
  42. package/src/skills-lib/{wizz-pesquisa-de-publico-do-piva → wizz-pesquisa-de-publico}/SKILL.md +11 -7
  43. package/src/skills-lib/{wizz-pesquisa-de-publico-do-piva → wizz-pesquisa-de-publico}/assets/template.html +8 -21
  44. package/src/skills-lib/wizz-pesquisa-de-publico/references/interview-mode.md +69 -0
  45. package/src/skills-lib/wizz-premium-landing-ui-researcher/SKILL.md +6 -2
  46. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/audit-protocol.md +7 -34
  47. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/component-sources.md +25 -0
  48. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/design-sources.yaml +325 -0
  49. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/mandatory-process.md +1 -1
  50. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/mining-rubric.md +123 -0
  51. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/source-first-protocol.md +10 -4
  52. package/src/skills-lib/wizz-premium-landing-ui-researcher/references/web-access-and-evidence.md +1 -1
  53. package/src/skills-lib/wizz-premium-landing-ui-researcher/scripts/design_sources.py +221 -0
  54. package/src/skills-lib/wizz-premium-landing-ui-researcher/scripts/tests/test_design_sources.py +130 -0
  55. package/src/skills-lib/wizz-router/references/routing-table-flat.md +7 -1
  56. package/src/skills-lib/wizz-seo-audit/SKILL.md +4 -0
  57. package/src/skills-lib/wizz-seo-audit/references/gsc-regex-perguntas.md +64 -0
  58. package/src/skills-lib/wizz-signup-flow-cro/SKILL.md +1 -0
  59. package/src/skills-lib/wizz-signup-flow-cro/references/trial-abuse.md +40 -0
  60. package/src/skills-lib/wizz-taste-skill/references/anti-slop-tells.md +8 -0
  61. package/src/skills-lib/wizz-ui-component-curator/SKILL.md +8 -7
  62. package/src/skills-lib/wizz-ui-ux-pro-max/SKILL.md +1 -1
  63. package/src/skills-lib/wizz-ui-ux-pro-max/references/common-rules-checklist.md +11 -0
  64. package/src/skills-lib/wizz-video-effects/LICENSE-motionmaxxing.txt +202 -0
  65. package/src/skills-lib/wizz-video-effects/SKILL.md +7 -2
  66. package/src/skills-lib/wizz-video-effects/assets/chrome/collect_layout.js +113 -0
  67. package/src/skills-lib/wizz-video-effects/assets/effects.config.template.json +45 -0
  68. package/src/skills-lib/wizz-video-effects/references/data-contract.md +32 -1
  69. package/src/skills-lib/wizz-video-effects/references/gates.md +4 -1
  70. package/src/skills-lib/wizz-video-effects/references/one-take.md +41 -0
  71. package/src/skills-lib/wizz-video-effects/scripts/check_chrome.py +376 -0
  72. package/src/skills-lib/wizz-video-effects/scripts/check_dead_frames.py +193 -0
  73. package/src/skills-lib/wizz-video-effects/scripts/check_one_take.py +159 -0
  74. package/src/skills-lib/wizz-video-effects/scripts/config.py +13 -0
  75. package/src/skills-lib/wizz-video-effects/scripts/test_chrome.py +181 -0
  76. package/src/skills-lib/wizz-video-effects/scripts/test_dead_frames.py +171 -0
  77. package/src/skills-lib/wizz-video-effects/scripts/test_one_take.py +126 -0
  78. package/src/skills-lib/wizz-video-styles/LICENSE-lemo-opuscar.txt +21 -0
  79. package/src/skills-lib/wizz-video-styles/SKILL.md +16 -7
  80. package/src/skills-lib/wizz-video-styles/assets/film-styles/dark-keynote.html +78 -0
  81. package/src/skills-lib/wizz-video-styles/assets/film-styles/remotion/Riso.tsx +63 -0
  82. package/src/skills-lib/wizz-video-styles/assets/film-styles/risograph.html +69 -0
  83. package/src/skills-lib/wizz-video-styles/assets/film-styles/swiss-motion.html +84 -0
  84. package/src/skills-lib/wizz-video-styles/references/check-ins.md +25 -0
  85. package/src/skills-lib/wizz-video-styles/references/film-styles/DIRECTOR.md +139 -0
  86. package/src/skills-lib/wizz-video-styles/references/film-styles/archive-lighttable.md +109 -0
  87. package/src/skills-lib/wizz-video-styles/references/film-styles/art-deco.md +112 -0
  88. package/src/skills-lib/wizz-video-styles/references/film-styles/ascii-crt.md +115 -0
  89. package/src/skills-lib/wizz-video-styles/references/film-styles/backrooms.md +125 -0
  90. package/src/skills-lib/wizz-video-styles/references/film-styles/blueprint.md +120 -0
  91. package/src/skills-lib/wizz-video-styles/references/film-styles/brick-toy.md +114 -0
  92. package/src/skills-lib/wizz-video-styles/references/film-styles/briefing-board.md +122 -0
  93. package/src/skills-lib/wizz-video-styles/references/film-styles/caption-news.md +137 -0
  94. package/src/skills-lib/wizz-video-styles/references/film-styles/cel-anime-80s.md +119 -0
  95. package/src/skills-lib/wizz-video-styles/references/film-styles/city-symphony.md +142 -0
  96. package/src/skills-lib/wizz-video-styles/references/film-styles/countdown.md +132 -0
  97. package/src/skills-lib/wizz-video-styles/references/film-styles/crayon-book.md +109 -0
  98. package/src/skills-lib/wizz-video-styles/references/film-styles/dark-keynote.md +117 -0
  99. package/src/skills-lib/wizz-video-styles/references/film-styles/data-physical.md +119 -0
  100. package/src/skills-lib/wizz-video-styles/references/film-styles/dataviz.md +123 -0
  101. package/src/skills-lib/wizz-video-styles/references/film-styles/engraving.md +123 -0
  102. package/src/skills-lib/wizz-video-styles/references/film-styles/game-show.md +118 -0
  103. package/src/skills-lib/wizz-video-styles/references/film-styles/glass-product.md +110 -0
  104. package/src/skills-lib/wizz-video-styles/references/film-styles/halftone-dossier.md +122 -0
  105. package/src/skills-lib/wizz-video-styles/references/film-styles/hd-2d.md +111 -0
  106. package/src/skills-lib/wizz-video-styles/references/film-styles/hologram-hud.md +129 -0
  107. package/src/skills-lib/wizz-video-styles/references/film-styles/impasto.md +124 -0
  108. package/src/skills-lib/wizz-video-styles/references/film-styles/ink-wash.md +120 -0
  109. package/src/skills-lib/wizz-video-styles/references/film-styles/iso-infographic.md +117 -0
  110. package/src/skills-lib/wizz-video-styles/references/film-styles/kino-montage.md +151 -0
  111. package/src/skills-lib/wizz-video-styles/references/film-styles/lidar-survey.md +118 -0
  112. package/src/skills-lib/wizz-video-styles/references/film-styles/living-screencast.md +124 -0
  113. package/src/skills-lib/wizz-video-styles/references/film-styles/lowpoly-island.md +112 -0
  114. package/src/skills-lib/wizz-video-styles/references/film-styles/microgame.md +122 -0
  115. package/src/skills-lib/wizz-video-styles/references/film-styles/microscope.md +108 -0
  116. package/src/skills-lib/wizz-video-styles/references/film-styles/midcentury-toon.md +124 -0
  117. package/src/skills-lib/wizz-video-styles/references/film-styles/news-package.md +158 -0
  118. package/src/skills-lib/wizz-video-styles/references/film-styles/newsreel.md +136 -0
  119. package/src/skills-lib/wizz-video-styles/references/film-styles/one-line.md +114 -0
  120. package/src/skills-lib/wizz-video-styles/references/film-styles/paper-lantern.md +116 -0
  121. package/src/skills-lib/wizz-video-styles/references/film-styles/paper-popup.md +119 -0
  122. package/src/skills-lib/wizz-video-styles/references/film-styles/papercut-red.md +110 -0
  123. package/src/skills-lib/wizz-video-styles/references/film-styles/pictogram-motion.md +119 -0
  124. package/src/skills-lib/wizz-video-styles/references/film-styles/pixel-rpg.md +117 -0
  125. package/src/skills-lib/wizz-video-styles/references/film-styles/risograph.md +125 -0
  126. package/src/skills-lib/wizz-video-styles/references/film-styles/rubber-hose.md +112 -0
  127. package/src/skills-lib/wizz-video-styles/references/film-styles/satellite-briefing.md +116 -0
  128. package/src/skills-lib/wizz-video-styles/references/film-styles/scifi-toon.md +121 -0
  129. package/src/skills-lib/wizz-video-styles/references/film-styles/shadow-puppet.md +124 -0
  130. package/src/skills-lib/wizz-video-styles/references/film-styles/silent-film.md +109 -0
  131. package/src/skills-lib/wizz-video-styles/references/film-styles/silkscreen-poster.md +140 -0
  132. package/src/skills-lib/wizz-video-styles/references/film-styles/spy-titles.md +116 -0
  133. package/src/skills-lib/wizz-video-styles/references/film-styles/stained-glass.md +123 -0
  134. package/src/skills-lib/wizz-video-styles/references/film-styles/swiss-motion.md +115 -0
  135. package/src/skills-lib/wizz-video-styles/references/film-styles/teardown.md +127 -0
  136. package/src/skills-lib/wizz-video-styles/references/film-styles/telestrator.md +137 -0
  137. package/src/skills-lib/wizz-video-styles/references/film-styles/tilt-shift.md +107 -0
  138. package/src/skills-lib/wizz-video-styles/references/film-styles/ukiyoe.md +112 -0
  139. package/src/skills-lib/wizz-video-styles/references/film-styles/urban-sketch.md +126 -0
  140. package/src/skills-lib/wizz-video-styles/references/film-styles/visual-investigation.md +140 -0
  141. package/src/skills-lib/wizz-video-styles/references/film-styles/watercolor.md +113 -0
  142. package/src/skills-lib/wizz-video-styles/references/film-styles/white-model.md +115 -0
  143. package/src/skills-lib/wizz-video-styles/references/film-styles/whiteboard.md +118 -0
  144. package/src/skills-lib/wizz-video-styles/references/film-styles/woodcut.md +122 -0
  145. package/src/skills-lib/wizz-video-styles/references/film-styles.md +140 -0
  146. package/src/skills-lib/wizz-video-styles/references/insert-recipes.md +33 -0
  147. package/src/skills-lib/wizz-video-styles/references/motion-laws.md +62 -0
  148. package/src/skills-lib/wizz-video-styles/references/styles/desafio-numero.md +1 -0
  149. package/src/skills-lib/wizz-video-styles/scripts/beat_grid.py +38 -6
  150. package/src/skills-lib/wizz-video-styles/scripts/blind_review.py +159 -0
  151. package/src/skills-lib/wizz-video-styles/scripts/taste.mjs +110 -0
  152. package/src/skills-lib/wizz-video-styles/scripts/test_blind_review.py +82 -0
  153. package/src/skills-lib/wizz-vsl/LICENSE +49 -0
  154. package/src/skills-lib/wizz-vsl/SKILL.md +122 -0
  155. package/src/skills-lib/wizz-vsl/references/assembly-qa.md +123 -0
  156. package/src/skills-lib/wizz-vsl/references/blocks-and-leads.md +149 -0
  157. package/src/skills-lib/wizz-vsl/references/diagnosis.md +95 -0
  158. package/src/skills-lib/wizz-vsl/references/intake.md +200 -0
  159. package/src/skills-lib/wizz-vsl/references/mechanisms.md +138 -0
  160. package/src/skills-lib/wizz-vsl/references/niches.md +40 -0
  161. package/src/skills-lib/wizz-vsl/references/offer.md +91 -0
  162. package/src/skills-lib/wizz-vsl/references/production.md +75 -0
  163. package/src/skills-lib/wizz-web-security/SKILL.md +2 -0
  164. package/tools/hooks/README.md +10 -9
  165. package/tools/hooks/wizz-arrumar.js +1 -0
  166. package/tools/hooks/wizz-artifact-guard.js +31 -5
  167. package/tools/hooks/wizz-cerebro-lib.js +36 -13
  168. package/tools/hooks/wizz-feature-lib.js +4 -1
  169. package/tools/hooks/wizz-feature.js +66 -76
  170. package/tools/hooks/wizz-sprint-archive-lib.js +311 -0
  171. package/tools/installer/core/hooks-settings.js +1 -0
  172. package/tools/installer/core/installer.js +6 -0
  173. package/tools/installer/guided/labels.js +16 -0
  174. package/tools/installer/install-text.js +2 -0
  175. package/tools/installer/modules/cli-config.js +3 -0
  176. package/tools/installer/modules/core-seed.js +72 -0
  177. package/tools/installer/modules/mcp-config.js +3 -0
  178. package/tools/installer/ui.js +22 -26
  179. /package/src/skills-lib/{wizz-pesquisa-de-publico-do-piva → wizz-pesquisa-de-publico}/prompts.md +0 -0
@@ -29,13 +29,15 @@ Scripts live in this skill's `scripts/`; run them from the project root (the his
29
29
  - B-roll or stock, a physical product, food, a place?
30
30
  - Niche, goal of the piece (follow, comment, save, click), duration.
31
31
  Never pick a style the material cannot feed. "Talking head" needs a person on camera; "motion editorial" needs nothing but a voice; "macro / ASMR" needs a physical product filmed close.
32
- 2. **Pick the style** with [references/style-picker.md](references/style-picker.md): material decides which styles are possible, niche and goal rank them. Mixed is allowed and common: person on camera for the hook and the CTA, another style in the middle. Before deciding, run `node scripts/references.mjs history` in the project: if the last two pieces used the same style, do not pick it a third time unless the user wants a series; choose another style the material allows, or keep it only for the hook and CTA.
33
- 3. **Open the style card** in `references/styles/` and follow it: rhythm, captions, palette, typography, motion, music, SFX, hook, CTA, and its "do not" list.
32
+ 2. **Pick the style** with [references/style-picker.md](references/style-picker.md): material decides which styles are possible, niche and goal rank them. Mixed is allowed and common: person on camera for the hook and the CTA, another style in the middle. Before deciding, run `node scripts/references.mjs history` in the project: if the last two pieces used the same style, do not pick it a third time unless the user wants a series; choose another style the material allows, or keep it only for the hook and CTA. Also run `node scripts/taste.mjs show`: what this user already approved or rejected in this project outranks the catalogue's ranking.
33
+ 3. **Open the style card** in `references/styles/` (or, for an art-directed film rather than a reach format, a film style from [references/film-styles.md](references/film-styles.md)) and follow it: rhythm, captions, palette, typography, motion, music, SFX, hook, CTA, and its "do not" list. Where the card is silent on how things move, use [references/motion-laws.md](references/motion-laws.md).
34
34
  4. **Get fresh references and watch two** before editing: `node scripts/references.mjs pick --style <key>` returns measured references plus, for styles generated in code, current viral videos from the awesome-opus5-5-videos list, skipping everything this project already used. Reading a card is not watching a video. For how those generated videos were briefed, see [references/generated-prompts.md](references/generated-prompts.md).
35
- 5. **Audio:** music and SFX choices from [references/audio.md](references/audio.md); the redistributable kit is in `assets/audio/` (credits in `assets/audio/CREDITS.md`).
36
- 6. **Hand over** to `wizz-video-effects` with the card's SFX ceiling and music level, then to Remotion.
37
- 7. **Look at the final file**: extract frames and compare them side by side with a contact sheet of one reference.
38
- 8. **Record the piece**: `node scripts/references.mjs record --style <key> --piece <slug> --refs <ids watched>`. It writes `_wizz-output/video-styles/historico.json`, which is what keeps the next piece from repeating the same references and look.
35
+ 5. **Pieces drawn in code** (no footage): run the story, look and storyboard check-ins of [references/check-ins.md](references/check-ins.md) before building, with the panels timed on `scripts/beat_grid.py`.
36
+ 6. **Audio:** music and SFX choices from [references/audio.md](references/audio.md); the redistributable kit is in `assets/audio/` (credits in `assets/audio/CREDITS.md`).
37
+ 7. **Hand over** to `wizz-video-effects` with the card's SFX ceiling and music level, then to Remotion.
38
+ 8. **Look at the final file**: extract frames and compare them side by side with a contact sheet of one reference.
39
+ 9. **Record the piece**: `node scripts/references.mjs record --style <key> --piece <slug> --refs <ids watched>`. It writes `_wizz-output/video-styles/historico.json`, which is what keeps the next piece from repeating the same references and look.
40
+ 10. **Record the user's verdict** after they review it (with two versions, offer `python3 scripts/blind_review.py prepare <dir> a.mp4 b.mp4` first), in their words: `node scripts/taste.mjs add --verdict approved|rejected --piece <slug> --style <key> --quote "..." --lesson "..."` (appends to `_wizz-output/video-styles/gosto.md`; the narrowest lesson the reaction supports).
39
41
 
40
42
  ## What the measurements say across every style
41
43
 
@@ -52,15 +54,22 @@ Details and the per-style table: [references/measured-patterns.md](references/me
52
54
  |---|---|
53
55
  | [references/style-picker.md](references/style-picker.md) | **start here.** Material and niche → which styles |
54
56
  | [references/styles/](references/styles/) | one card per style: recipe, references, do-not list |
57
+ | [references/motion-laws.md](references/motion-laws.md) | how things move when the card is silent: easing, scale, cuts, fades, springs, word cadence (measured on horizontal brand films) |
55
58
  | [references/measured-patterns.md](references/measured-patterns.md) | the numbers behind the cards, per style and per niche |
56
59
  | [references/audio.md](references/audio.md) | music and SFX per style, the kit, libraries and licences |
57
60
  | [references/research-method.md](references/research-method.md) | how the catalogue was measured, its limits, how to add a niche or a style |
58
61
  | `data/references.json` | every measured short: link, channel, views, niche, style, metrics |
62
+ | [references/film-styles.md](references/film-styles.md) | 59 art-directed film styles drawn in code (lemo-opuscar, not measured): index, how to build them in HyperFrames for 9:16, what the test renders taught |
63
+ | [references/insert-recipes.md](references/insert-recipes.md) | b-roll treatments cut into a style (collage b-roll), drawn in code, not measured |
59
64
  | [references/generated-prompts.md](references/generated-prompts.md) | prompts of viral code-generated videos, grouped by style, and how they run here |
60
65
  | `scripts/analyze.sh` | measures one short (cuts, music bed, SFX heuristics, loudness, contact sheet) |
66
+ | `scripts/blind_review.py` | blind side-by-side page for two or more versions, answer key hidden until the pick |
67
+ | `scripts/taste.mjs` | the user's approved and rejected verdicts for this project, read before choosing and appended after review |
61
68
  | `scripts/references.mjs` | fresh references per style without repeats, and the project's history of styles used |
62
- | `scripts/beat_grid.py` | BPM, beats and downbeats of a song, so cuts snap to the music (lyric video, kinetic typography) |
69
+ | [references/check-ins.md](references/check-ins.md) | story, look and storyboard approvals before building a piece drawn in code, plus the beat map |
70
+ | `scripts/beat_grid.py` | BPM, beats, downbeats, loudest hits and drops of a song, so cuts and the payoff snap to the music |
63
71
  | `assets/remotion/editorial/` | Remotion template of the motion editorial style |
72
+ | `assets/film-styles/` | three film styles rebuilt as 9:16 HyperFrames compositions (swiss-motion, risograph, dark-keynote), plus the risograph as a Remotion component, all gated |
64
73
  | `assets/audio/` | licensed music beds and SFX that may ship with a project |
65
74
 
66
75
  ## Out of scope
@@ -0,0 +1,78 @@
1
+ <!doctype html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=1080, height=1920" />
6
+ <title>dark-keynote · 9:16 example</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8
+ <style>
9
+ body { margin: 0; background: #07090D; }
10
+ #root { position: relative; width: 1080px; height: 1920px; overflow: hidden; font-family: "Inter", "Helvetica Neue", sans-serif; color: #E8ECF2; }
11
+ .stage { position: absolute; inset: 0;
12
+ background: radial-gradient(ellipse 80% 40% at 50% 8%, #151A24 0%, transparent 70%),
13
+ radial-gradient(circle at 78% 62%, rgba(110,140,255,0.07) 0%, transparent 45%),
14
+ radial-gradient(ellipse at 50% 50%, transparent 50%, rgba(0,0,0,0.55) 100%), #07090D; }
15
+ .grid { position: absolute; inset: 0;
16
+ background-image: linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
17
+ background-size: 48px 48px; }
18
+ .card { position: absolute; width: 560px; height: 116px; border-radius: 22px; background: #141922;
19
+ border: 1px solid rgba(255,255,255,0.08); box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 20px 40px rgba(0,0,0,0.45); }
20
+ .card .ico { position: absolute; left: 24px; top: 28px; width: 60px; height: 60px; border-radius: 14px; background: #1E2531; }
21
+ .card .l1 { position: absolute; left: 104px; top: 30px; width: 300px; height: 18px; border-radius: 9px; background: #3A4352; }
22
+ .card .l2 { position: absolute; left: 104px; top: 64px; width: 200px; height: 14px; border-radius: 7px; background: #262D39; }
23
+ .card .badge { position: absolute; right: 22px; top: 22px; width: 40px; height: 40px; border-radius: 20px; background: #E5484D;
24
+ font: 600 20px/40px "JetBrains Mono", Menlo, monospace; text-align: center; color: #fff; }
25
+ #btn { position: absolute; left: 340px; top: 1180px; width: 400px; height: 120px; border-radius: 60px; background: #1A2029;
26
+ border: 1px solid rgba(255,255,255,0.1); font: 600 40px/120px Inter, "Helvetica Neue", sans-serif; text-align: center; color: #9AA4B2; }
27
+ #cursor { position: absolute; left: 0; top: 0; width: 44px; height: 56px; }
28
+ #big { position: absolute; left: 0; top: 560px; width: 1080px; text-align: center; font: 700 520px/1 "Inter Tight", "Helvetica Neue", sans-serif;
29
+ letter-spacing: -0.045em; color: #B7F34A; text-shadow: 0 0 80px rgba(183,243,74,0.35); }
30
+ #label { position: absolute; left: 0; top: 1120px; width: 1080px; text-align: center; font: 500 30px "JetBrains Mono", Menlo, monospace; letter-spacing: 0.18em; color: #8A94A3; }
31
+ #toast { position: absolute; left: 240px; top: 1400px; width: 600px; height: 92px; border-radius: 46px; background: rgba(20,25,34,0.9);
32
+ border: 1px solid rgba(255,255,255,0.12); font: 500 38px/92px Inter, "Helvetica Neue", sans-serif; text-align: center; }
33
+ #toast i { display: inline-block; width: 14px; height: 14px; border-radius: 7px; background: #B7F34A; margin-right: 16px; vertical-align: middle; }
34
+ </style>
35
+ </head>
36
+ <body>
37
+ <div id="root" data-composition-id="main" data-width="1080" data-height="1920" data-duration="6" data-fps="24">
38
+ <section id="scene" class="clip" data-start="0" data-duration="6" data-track-index="1" style="position:absolute;inset:0">
39
+ <div class="stage"></div><div class="grid"></div>
40
+ <div id="cards"></div>
41
+ <div id="btn">unificar</div>
42
+ <div id="big">1</div>
43
+ <div id="label">PAINEL · NO LUGAR DE 9 ABAS</div>
44
+ <div id="toast"><i></i>tudo num lugar só</div>
45
+ <svg id="cursor" viewBox="0 0 22 28"><path d="M1 1 L1 22 L7 16.5 L11 26 L14.5 24.5 L10.5 15 L18 15 Z" fill="#fff" stroke="#000" stroke-width="1.2"/></svg>
46
+ </section>
47
+ </div>
48
+ <script>
49
+ // 9 cards on the 48 px grid, fixed positions (no random)
50
+ const pos = [[96,288],[432,416],[144,544],[480,672],[96,800],[432,928],[192,1056],[480,1184],[96,1312]];
51
+ const holder = document.getElementById("cards");
52
+ pos.forEach(([x, y], i) => {
53
+ const c = document.createElement("div"); c.className = "card"; c.style.left = x + "px"; c.style.top = y + "px";
54
+ c.innerHTML = '<div class="ico"></div><div class="l1"></div><div class="l2"></div><div class="badge">' + (i + 2) + '</div>';
55
+ holder.appendChild(c);
56
+ });
57
+ window.__timelines = window.__timelines || {};
58
+ const tl = gsap.timeline({ paused: true });
59
+ const beat = 0.5;
60
+ // spawns: drop + small overshoot, one per half beat (problem state, red badges)
61
+ tl.from(".card", { y: -60, opacity: 0, duration: 0.25, ease: "back.out(1.3)", stagger: beat / 2 }, 0.1);
62
+ tl.to(".card", { x: (i) => (i % 2 ? 4 : -4), duration: 0.05, ease: "none", repeat: 5, yoyo: true }, 2.4); // tremble
63
+ tl.from("#btn", { scale: 0.6, opacity: 0, duration: 0.25, ease: "back.out(1.3)" }, 2.5);
64
+ // cursor flies on a curve to the button, lands on the beat at 3.0
65
+ tl.fromTo("#cursor", { x: 900, y: 1480 }, { x: 560, y: 1250, duration: 0.5, ease: "power3.out" }, 2.5);
66
+ tl.to("#cursor", { scale: 0.85, duration: 0.06, ease: "none", yoyo: true, repeat: 1 }, 3.0);
67
+ tl.to("#btn", { backgroundColor: "#B7F34A", color: "#0A0D10", duration: 0.08, ease: "none" }, 3.0);
68
+ // turn: cards retract into the button, one per eighth note
69
+ tl.to(".card", { x: (i) => 540 - 280 - pos[i][0], y: (i) => 1240 - 58 - pos[i][1], scale: 0.2, opacity: 0, duration: 0.3, ease: "power3.in", stagger: 0.06 }, 3.15);
70
+ tl.to(["#btn", "#cursor"], { scaleY: 0.02, scaleX: 0.4, opacity: 0, duration: 0.2, ease: "power3.in" }, 3.85);
71
+ // the number gets its own screen, no caption over it
72
+ tl.from("#big", { scale: 0.7, opacity: 0, duration: 0.3, ease: "back.out(1.3)" }, 3.9);
73
+ tl.from("#label", { y: 20, opacity: 0, duration: 0.2, ease: "power2.out" }, 4.0);
74
+ tl.from("#toast", { y: 24, opacity: 0, duration: 0.16, ease: "power2.out" }, 4.25);
75
+ window.__timelines["main"] = tl;
76
+ </script>
77
+ </body>
78
+ </html>
@@ -0,0 +1,63 @@
1
+ import React from "react";
2
+ import { AbsoluteFill, Easing, interpolate, useCurrentFrame, useVideoConfig } from "remotion";
3
+
4
+ // Risograph Print (lemo-opuscar card), rebuilt for Remotion: each plate is one ink
5
+ // printed with multiply; tints are a dotted mask; registration is fixed per shot,
6
+ // with one kick on the accent and a drift that snaps back on the downbeat.
7
+ const PAPER = "#F4EEE2";
8
+ const TEAL = "#00838A";
9
+ const ORANGE = "#FF7477";
10
+ const clamp = { extrapolateLeft: "clamp", extrapolateRight: "clamp" } as const;
11
+
12
+ const Tint: React.FC<{ ink: string; dot: number; style: React.CSSProperties }> = ({ ink, dot, style }) => {
13
+ const mask = `radial-gradient(circle, #000 ${dot}px, transparent ${dot + 0.6}px)`;
14
+ return <div style={{ position: "absolute", background: ink, WebkitMaskImage: mask, maskImage: mask, WebkitMaskSize: "7px 7px", maskSize: "7px 7px", ...style }} />;
15
+ };
16
+
17
+ const Title: React.FC<{ ink: string; style?: React.CSSProperties }> = ({ ink, style }) => (
18
+ <div style={{ position: "absolute", left: 110, top: 310, width: 900, fontFamily: "Futura, 'Avenir Next', sans-serif", fontWeight: 800, fontSize: 150, lineHeight: 0.92, letterSpacing: "-0.02em", color: ink, ...style }}>
19
+ <div>anúncio</div>
20
+ <div>que vende</div>
21
+ </div>
22
+ );
23
+
24
+ export const Riso: React.FC = () => {
25
+ const frame = useCurrentFrame();
26
+ const { fps } = useVideoConfig();
27
+ const t = frame / fps;
28
+
29
+ const hillY = interpolate(t, [0, 0.6], [100, 0], { ...clamp, easing: Easing.out(Easing.cubic) });
30
+ const titleClip = interpolate(t, [0.25, 0.75], [100, 0], { ...clamp, easing: Easing.out(Easing.quad) });
31
+ const roller = interpolate(t, [1, 2], [0, 1], clamp);
32
+ // sun rises on twos: 18 steps over 1.5 s
33
+ const sunStep = Math.floor(interpolate(t, [1.4, 2.9], [0, 18], clamp));
34
+ const sunY = 320 - (320 * sunStep) / 18;
35
+ // kick on the accent at 3.0, ringing back
36
+ const kick = t < 3 ? 0 : t < 3.04 ? 1 : interpolate(t, [3.04, 3.34], [1, 0], { ...clamp, easing: Easing.out(Easing.elastic(1.5)) });
37
+ const p2x = -2 - 12 * kick;
38
+ const p2y = 2 + 8 * kick;
39
+ // drift through the hold, snap back on the downbeat
40
+ const p1x = t < 3.4 ? 2 : t < 4.6 ? interpolate(t, [3.4, 4.6], [2, 22]) : 2;
41
+ const p2on = t < 5;
42
+
43
+ const plate: React.CSSProperties = { position: "absolute", inset: -40, mixBlendMode: "multiply" };
44
+ return (
45
+ <AbsoluteFill style={{ background: PAPER }}>
46
+ <div style={{ ...plate, transform: `translate(${p1x}px, -1px)` }}>
47
+ <Tint ink={TEAL} dot={2.2} style={{ left: 0, top: 290, width: 1160, height: 570 }} />
48
+ <div style={{ position: "absolute", left: -100, top: 1180, width: 1400, height: 900, borderRadius: "50% 50% 0 0", background: TEAL, transform: `translateY(${hillY}px)` }} />
49
+ <Title ink={TEAL} style={{ clipPath: `inset(0 0 ${titleClip}% 0)` }} />
50
+ </div>
51
+ {p2on && (
52
+ <div style={{ ...plate, transform: `translate(${p2x}px, ${p2y}px)`, clipPath: `inset(0 0 ${100 - roller * 100}% 0)` }}>
53
+ <div style={{ position: "absolute", left: 380, top: 820, width: 520, height: 520, borderRadius: "50%", background: ORANGE, transform: `translateY(${sunY}px)` }} />
54
+ <Title ink={ORANGE} style={{ transform: "translate(9px, 7px)", opacity: 0.9 }} />
55
+ <Tint ink={ORANGE} dot={2} style={{ left: 0, top: 1350, width: 1160, height: 250 }} />
56
+ </div>
57
+ )}
58
+ {roller > 0 && roller < 1 && (
59
+ <div style={{ position: "absolute", left: 0, top: -40 + roller * 2000, width: 1080, height: 30, background: "rgba(255,116,119,0.35)", mixBlendMode: "multiply" }} />
60
+ )}
61
+ </AbsoluteFill>
62
+ );
63
+ };
@@ -0,0 +1,69 @@
1
+ <!doctype html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=1080, height=1920" />
6
+ <title>risograph · 9:16 example</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8
+ <style>
9
+ body { margin: 0; background: #F4EEE2; }
10
+ #root { position: relative; width: 1080px; height: 1920px; overflow: hidden; font-family: "Futura", "Avenir Next", sans-serif; }
11
+ .paper { position: absolute; inset: 0; background: #F4EEE2; }
12
+ /* each plate is one ink, printed with multiply so overlaps mix */
13
+ .plate { position: absolute; inset: -40px; mix-blend-mode: multiply; }
14
+ .teal { --ink: #00838A; }
15
+ .orange { --ink: #FF7477; }
16
+ .solid { position: absolute; background: var(--ink); }
17
+ .tint { position: absolute; background: var(--ink);
18
+ -webkit-mask-image: radial-gradient(circle, #000 var(--dot), transparent calc(var(--dot) + 0.6px));
19
+ -webkit-mask-size: 7px 7px; mask-image: radial-gradient(circle, #000 var(--dot), transparent calc(var(--dot) + 0.6px)); mask-size: 7px 7px; }
20
+ .title { position: absolute; left: 110px; width: 900px; font-weight: 800; font-size: 150px; line-height: 0.92; letter-spacing: -0.02em; color: var(--ink); }
21
+ .grain { position: absolute; inset: 0; mix-blend-mode: multiply; opacity: 0.35; }
22
+ #roller { position: absolute; left: 0; width: 1080px; height: 30px; background: rgba(255,116,119,0.35); mix-blend-mode: multiply; }
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <div id="root" data-composition-id="main" data-width="1080" data-height="1920" data-duration="6" data-fps="24">
27
+ <section id="scene" class="clip" data-start="0" data-duration="6" data-track-index="1" style="position:absolute;inset:0">
28
+ <div class="paper"></div>
29
+ <!-- plate 1: teal, offset +2px/-1px -->
30
+ <div id="p1" class="plate teal">
31
+ <div class="tint" style="--dot:2.2px; left:0; top:290px; width:1160px; height:570px"></div>
32
+ <div id="hill" class="solid" style="left:-100px; top:1180px; width:1400px; height:900px; border-radius:50% 50% 0 0"></div>
33
+ <div id="t1" class="title" style="top:310px"><span style="display:block">anúncio</span><span style="display:block">que vende</span></div>
34
+ </div>
35
+ <!-- plate 2: orange, offset -2px/+2px, arrives by roller sweep -->
36
+ <div id="p2" class="plate orange">
37
+ <div id="sun" class="solid" style="left:380px; top:820px; width:520px; height:520px; border-radius:50%"></div>
38
+ <div id="t2" class="title" style="top:310px; transform: translate(9px,7px); opacity:0.9"><span style="display:block">anúncio</span><span style="display:block">que vende</span></div>
39
+ <div class="tint" style="--dot:2px; left:0; top:1350px; width:1160px; height:250px"></div>
40
+ </div>
41
+ <svg class="grain" width="1080" height="1920"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" seed="7"/><feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 -1.2 1.1"/></filter><rect width="1080" height="1920" filter="url(#n)"/></svg>
42
+ <div id="roller"></div>
43
+ </section>
44
+ </div>
45
+ <script>
46
+ window.__timelines = window.__timelines || {};
47
+ const tl = gsap.timeline({ paused: true });
48
+ tl.set("#p1", { x: 2, y: -1 }, 0);
49
+ tl.set("#p2", { x: -2, y: 2 }, 0);
50
+ // one-plate version first: teal alone is a complete frame
51
+ tl.from("#t1", { clipPath: "inset(0 0 100% 0)", duration: 0.5, ease: "power2.out" }, 0.25);
52
+ tl.from("#hill", { y: 100, duration: 0.6, ease: "power3.out" }, 0.0);
53
+ // roller sweep prints the orange plate top to bottom (1.0 - 2.0)
54
+ tl.fromTo("#p2", { clipPath: "inset(0 0 100% 0)" }, { clipPath: "inset(0 0 0% 0)", duration: 1.0, ease: "none" }, 1.0);
55
+ tl.fromTo("#roller", { y: -40 }, { y: 1960, duration: 1.0, ease: "none" }, 1.0);
56
+ // sun rises on twos (12 fps steps)
57
+ tl.fromTo("#sun", { y: 320 }, { y: 0, duration: 1.5, ease: "steps(18)" }, 1.4);
58
+ // kick: registration jumps on the accent at 3.0 and rings back
59
+ tl.to("#p2", { x: -14, y: 10, duration: 0.04, ease: "none" }, 3.0);
60
+ tl.to("#p2", { x: -2, y: 2, duration: 0.3, ease: "elastic.out(1, 0.35)" }, 3.04);
61
+ // drift through the hold, snap back on the downbeat
62
+ tl.to("#p1", { x: 22, duration: 1.2, ease: "none" }, 3.4);
63
+ tl.to("#p1", { x: 2, duration: 0.05, ease: "none" }, 4.6);
64
+ // ending: one ink left (the orange plate lifts away)
65
+ tl.to("#p2", { opacity: 0, duration: 0.05, ease: "none" }, 5.0);
66
+ window.__timelines["main"] = tl;
67
+ </script>
68
+ </body>
69
+ </html>
@@ -0,0 +1,84 @@
1
+ <!doctype html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=1080, height=1920" />
6
+ <title>swiss-motion · 9:16 example</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8
+ <style>
9
+ body { margin: 0; background: #EAE9E5; }
10
+ #root { position: relative; width: 1080px; height: 1920px; overflow: hidden;
11
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #111; }
12
+ .fill { position: absolute; inset: 0; background: #EAE9E5; }
13
+ .vline { position: absolute; top: 0; width: 1px; height: 1920px; background: #D3D1CB; transform-origin: top; }
14
+ .hline { position: absolute; left: 0; height: 1px; width: 1080px; background: #D3D1CB; transform-origin: left; }
15
+ #num { position: absolute; left: 60px; top: 330px; width: 900px; height: 760px; overflow: hidden; }
16
+ #num span { display: block; font-size: 900px; font-weight: 700; line-height: 760px; letter-spacing: -0.04em; margin-left: -40px; }
17
+ .row { position: absolute; left: 72px; height: 120px; overflow: hidden; width: 940px; }
18
+ .row span { display: block; font-size: 112px; font-weight: 700; line-height: 120px; letter-spacing: -0.03em; }
19
+ .lead { color: #8E8C86; }
20
+ #signal { position: absolute; left: 0; top: 1470px; width: 180px; height: 48px; background: #E30613; }
21
+ #readout { position: absolute; left: 72px; top: 1530px; font-size: 22px; font-weight: 500; width: 600px; }
22
+ .note { position: absolute; font-size: 21px; font-weight: 500; border-top: 1px solid #111; padding-top: 8px; width: 300px; }
23
+ #knife { position: absolute; left: 0; top: 700px; height: 4px; width: 1080px; background: #111; transform-origin: left; }
24
+ #end { position: absolute; left: 72px; top: 640px; height: 110px; overflow: hidden; width: 600px; }
25
+ #end span { display: block; font-size: 96px; font-weight: 700; line-height: 110px; letter-spacing: -0.03em; }
26
+ </style>
27
+ </head>
28
+ <body>
29
+ <div id="root" data-composition-id="main" data-width="1080" data-height="1920" data-duration="6" data-fps="24">
30
+ <section id="scene" class="clip" data-start="0" data-duration="6" data-track-index="1" style="position:absolute;inset:0">
31
+ <div class="fill"></div>
32
+ <div id="grid"></div>
33
+ <div id="num"><span>3</span></div>
34
+ <div id="knife"></div>
35
+ <div class="row" style="top:1100px"><span class="lead">regras para</span></div>
36
+ <div class="row" style="top:1220px"><span>um reel que</span></div>
37
+ <div class="row" style="top:1340px"><span>segura o dedo.</span></div>
38
+ <div class="note" style="left:72px;top:270px">grade 6 col · 72 px</div>
39
+ <div class="note" style="left:708px;top:270px">120 bpm · 0.5 s</div>
40
+ <div id="signal"></div>
41
+ <div id="readout">x 0 · no grid</div>
42
+ <div id="end"><span>wizz.</span></div>
43
+ </section>
44
+ </div>
45
+ <script>
46
+ // Grid: 6 columns, 72 px margins, 24 px gutters, rows every 120 px
47
+ const grid = document.getElementById("grid");
48
+ const colW = (1080 - 2 * 72 - 5 * 24) / 6;
49
+ for (let i = 0; i <= 6; i++) {
50
+ const x = 72 + i * (colW + 24) - (i === 6 ? 24 : 0);
51
+ const v = document.createElement("div"); v.className = "vline"; v.style.left = x + "px"; grid.appendChild(v);
52
+ }
53
+ for (let y = 120; y < 1920; y += 120) {
54
+ const h = document.createElement("div"); h.className = "hline"; h.style.top = y + "px"; grid.appendChild(h);
55
+ }
56
+ const ease = (t) => { // cubic-bezier(.7,0,.2,1)
57
+ let lo = 0, hi = 1, x;
58
+ for (let i = 0; i < 30; i++) { const m = (lo + hi) / 2; x = 3*(1-m)*(1-m)*m*0.7 + 3*(1-m)*m*m*0.2 + m*m*m; if (x < t) lo = m; else hi = m; }
59
+ const m = (lo + hi) / 2; return 3*(1-m)*m*m + m*m*m;
60
+ };
61
+ window.__timelines = window.__timelines || {};
62
+ const tl = gsap.timeline({ paused: true });
63
+ tl.from(".vline", { scaleY: 0, duration: 0.5, ease: "none", stagger: 0.03 }, 0);
64
+ tl.from(".hline", { scaleX: 0, duration: 0.5, ease: "none", stagger: 0.015 }, 0.1);
65
+ tl.from(".note", { clipPath: "inset(0 100% 0 0)", duration: 0.25, ease }, 0.25);
66
+ // numeral climbs one module at a time, landing on the beat at 1.0
67
+ [0.1, 0.225, 0.35, 0.475].forEach((t, i) => tl.fromTo("#num span", { y: 760 - i * 190 }, { y: 760 - (i + 1) * 190, duration: 0.12, ease, immediateRender: i === 0 }, t));
68
+ // words rise out of their clip rect, each landing on a beat
69
+ tl.from(".row span", { y: 130, duration: 0.25, ease, stagger: 0.25 }, 0.6);
70
+ // the exception: linear, unsnapped, pauses mid-flight
71
+ tl.fromTo("#signal", { x: -200 }, { x: 430, duration: 0.6, ease: "none" }, 2.9);
72
+ tl.to("#signal", { x: 1100, duration: 0.7, ease: "none" }, 3.8);
73
+ tl.set("#readout", { textContent: "x 430 · fora do grid" }, 3.1);
74
+ tl.set("#readout", { textContent: "x — · saiu" }, 4.5);
75
+ // knife cut through the numeral, which collapses to its midline
76
+ tl.from("#knife", { scaleX: 0, duration: 0.25, ease: "none" }, 4.0);
77
+ tl.to("#num", { scaleY: 0, transformOrigin: "50% 50%", duration: 0.25, ease }, 4.25);
78
+ tl.to("#knife", { scaleX: 0, transformOrigin: "right", duration: 0.2, ease }, 4.5);
79
+ tl.to("#readout", { y: -40, opacity: 0, duration: 0.2, ease }, 4.75);
80
+ tl.from("#end span", { y: 120, duration: 0.25, ease }, 4.75);
81
+ window.__timelines["main"] = tl;
82
+ </script>
83
+ </body>
84
+ </html>
@@ -0,0 +1,25 @@
1
+ # Check-ins for a piece drawn in code
2
+
3
+ For pieces with no footage, built in HyperFrames (motion editorial, animated explainer, UI morph, kinetic typography, collage inserts). Drawing a whole film and then hearing "that's not it" wastes the most time; three short approvals before the build catch it while it is cheap. Idea from [cth9191/animate](https://github.com/cth9191/animate) (MIT), written here for this pipeline.
4
+
5
+ Each check-in shows something and waits. Nothing from the next step is made before the user answers.
6
+
7
+ 1. **Story.** A numbered beat table: what each beat says, its length, the fact it claims (checked on the web when it is a fact). Approve or change the beats.
8
+ 2. **Look.** 2 to 4 still frames at full size in the chosen style card's palette and type. When the look comes from a reference, put each frame side by side with it. A thumbs up per frame; a rejected frame is redrawn, not argued.
9
+ 3. **Storyboard.** One key frame per beat, with the sound under it and the transition into the next beat. The user answers by panel number ("4 and 7 no"); only the rejected panels change.
10
+ 4. **Build.** No check-in: animate the approved panels, render, and run the checks of `wizz-video-effects`.
11
+ 5. **Delivery.** The file plus the measured checks: cuts on the beat grid, the payoff on the loudest hit, loudness. The user's notes start a revision of the panels they name, and the verdict goes to `scripts/taste.mjs`.
12
+
13
+ ## Beat map
14
+
15
+ With a music track, run `scripts/beat_grid.py <track> --fps <fps>` before the storyboard, so the panels are timed to the music and not to a guessed BPM:
16
+
17
+ - `downbeat_frames`: where the scene changes land.
18
+ - `hits`: the loudest beats; the payoff (the number, the reveal, the logo) goes on the loudest one.
19
+ - `drops`: where the energy jumps; the piece changes gear there (a new section, a faster rhythm).
20
+
21
+ Put the beat time on each storyboard panel, so the user approves the timing together with the image.
22
+
23
+ ## A character that acts
24
+
25
+ When the piece has a character (a mascot, a drawn presenter), the emotions section of the `ANIMATION_GUIDE.md` in [JohnHeibel/ClaudeAnimationBase](https://github.com/JohnHeibel/ClaudeAnimationBase) (MIT) is the reference for acting: each emotion is a pose, eyes, mouth and a timing, not a face swap. Read it before the storyboard and give each panel the emotion the character plays. For a film where Claude itself appears, the kit is installable as the CLI `claude-animation-base` (designer area) and renders Clawd directly.
@@ -0,0 +1,139 @@
1
+ <!-- Vendored from lemo-opuscar (https://github.com/lemomo-ai/lemo-opuscar/tree/413a6bd6/DIRECTOR.md), MIT, (c) 2026 LemoLab. Its references to AGENTS.md, TECHNIQUE.md and the render tools are that repo's; here the build is HyperFrames (../film-styles.md). -->
2
+
3
+ # Directing a Lemo-Opuscar film
4
+
5
+ The directing method behind every film in this library. Pair it with one `styles/<slug>/STYLE.md` (the style) and [`TECHNIQUE.md`](https://github.com/lemomo-ai/lemo-opuscar/blob/413a6bd6/TECHNIQUE.md) (how to build).
6
+
7
+ You are the director, not a tech demo. A film is judged in this order: **sound, rhythm, camera, directing** (performance, staging, emotional arc). Good-looking frames are only the starting point.
8
+
9
+ ---
10
+
11
+ ## 1. Take the brief
12
+
13
+ The user gives a style and a topic, sometimes more (length, language, voice, must-have shots, brand rules). Everything else is your decision. Ask once, in a single message (AGENTS.md, Workflow), then no more questions. Defaults:
14
+
15
+ - Length **30–60 s**; shorter and tight beats padded. Beyond two or three minutes multiplies time and token cost: tell the user.
16
+ - 1920×1080 at 24 fps by default; an output frame rate set in the style's `STYLE.md` (30 or 60 fps, for example) wins, and is what you pass to `--fps` and `mux.sh`; other sizes (vertical 1080×1920, for example) with `--size WxH` on the render tools.
17
+ - Voice and subtitles in the language the user writes in. Subtitles burned in and exported as `.srt`.
18
+ - Loudness −14 LUFS.
19
+
20
+ Say it in the questions when it matters: a good Chinese voice uses Microsoft's online service (edge-tts) and needs a connection; offline, Kokoro reads Chinese but sounds plain (TECHNIQUE.md §4).
21
+
22
+ Requests that only change the plan:
23
+
24
+ - **No voice, or no subtitles.** Drop those steps and say so in the treatment.
25
+ - **Their own voice recording.** Use it as it is; transcribe it with faster-whisper for word timings.
26
+ - **Their own material**: logos, photos, footage, and for styles built from real material (the Evidence Films) their own data, scans, imagery or CAD. Ask whether they have any; what they give comes first, and the sources in the `STYLE.md` are the fallback. Before you download from those sources, tell the user what you will fetch, from where and under which licence. Rights: section 12.
27
+
28
+ ## 2. Find a benchmark first
29
+
30
+ Before writing anything, pick one or two reference works (films, title sequences, games, ads) that set the bar for this style **and this topic**. They are your choice, made for the user's film; don't borrow the demo's. Write down:
31
+
32
+ - **What to learn**: composition, pacing, camera grammar, colour logic, score structure.
33
+ - **What not to take**: characters, designs, melodies, specific shots, logos, fonts.
34
+
35
+ The benchmark lifts quality more than any rule below.
36
+
37
+ ## 3. Shape the story
38
+
39
+ - **One subject, one goal, one turn.** A character (or a single object, product or idea) wants something, something changes, it ends differently from how it began.
40
+ - **Hook in the first 3 seconds.** No slow logo reveal before anything happens.
41
+ - **An ending that echoes.** Bookend the opening, reveal the scale, or let the character do the thing right the second time.
42
+ - **One native move**: a moment only this medium can do (a fold that becomes a transition, ink that blooms into the next scene, a type grid that snaps into the logo). Put it at the emotional peak. `STYLE.md` lists the medium's native moves; pick or invent the one your story needs.
43
+ - **Cut the extras.** One gag the audience reads at thumbnail size beats three they can't. If a beat needs explaining, remove it.
44
+
45
+ ## 4. Write the treatment
46
+
47
+ Write `TREATMENT.md` before drawing anything, and before you open the style's `DEMO.md` or demo code (an Edit & Documentary style gathers its material first: AGENTS.md, "Treatment first"):
48
+
49
+ 1. **Three candidate structures**, a few lines each (for example: a single journey, a before/after, a countdown, a list that turns), then the one you chose and why. Choose the opening image, the ending and the shape of the score from the topic too; the first idea that comes to mind for a style is usually its cliché.
50
+ 2. **Logline and arc**: one sentence, then setup → turn → ending.
51
+ 3. **Benchmark**: learn / don't learn (section 2).
52
+ 4. **Shot list**: for every shot, the framing (wide / full / medium / close / insert), angle, camera move (push, pull, pan, track, crane, zoom), duration, and **why** it is shot that way.
53
+ 5. **Beat sheet**, second by second.
54
+ 6. **Cue map**: tempo, bar grid, instrumentation per section, and on which beat every cut, key action and subtitle lands.
55
+ 7. **Sound design table**: for each section, the ambience bed, the main foley and the music state.
56
+ 8. **Subtitle and title design**: the type is part of the style.
57
+
58
+ ## 5. Prove the look
59
+
60
+ - **With characters**: draw a model sheet (turnaround, 3–4 expressions, 2–3 key poses, palette) plus two style frames.
61
+ - **Without characters**: three style frames from the film, one of them the signature shot.
62
+
63
+ Render them with the real drawing code, not a mock-up, and check them yourself against the `STYLE.md` before going on.
64
+
65
+ ### The storyboard (only if the user asked for one)
66
+
67
+ Render 6–9 key shots with the real drawing code, tiled into one sheet (`core/render/sheet.py`) with shot number, framing, duration and line under each. Send it with the logline and what you are least sure about, and **wait for approval**. If the user didn't ask for one, don't stop.
68
+
69
+ ## 6. Sound is half the film
70
+
71
+ - **Every visible action has a sound**: landings, page turns, cuts, drips, clicks, cloth. Match the material (paper, wood, metal, ink and glass all sound different).
72
+ - **Three layers**: ambience (room, wind, rain, city), foley (tied to actions) and music. Duck the music under dialogue and key foley.
73
+ - **At least two real silences**, or near-silences, before the turn or the emotional peak. The first sound after the silence should be one of the most important sounds in the film.
74
+ - **Use sound as a transition** at least twice: bring the next scene's sound in early (J-cut) or let the last scene's sound run over the cut (L-cut).
75
+ - **Avoid generic "piano and strings".** Score in the instruments of the style's sound palette.
76
+
77
+ ## 7. Rhythm: the music grid comes first
78
+
79
+ - Write the cue map before animating. The picture locks to the grid, and a script checks every cue (TECHNIQUE.md §3).
80
+ - **Vary the pace**: alternate fast and slow, include one clear acceleration or deceleration, and give the audience one breath (a long take or a held pause). A film at one even speed has failed.
81
+ - One action, one sound, one cut, but don't cut on every beat. Leave time to see.
82
+ - **Pace for the viewer, not the clock**:
83
+ - Hold every subtitle at least 1.8 s, and never shorter than the spoken line + 0.6 s.
84
+ - After text finishes animating in, hold it for roughly (letters ÷ 15 + 1.5) s in English, (characters ÷ 4.5 + 1.5) s in Chinese; `readcheck.mjs` checks this for you.
85
+ - Hold a title card at least 4 s.
86
+ - Give failures and gags enough time to be understood.
87
+ - Fast is fine; make it fast with fewer words per screen, not by cutting before people finish reading.
88
+
89
+ ## 8. Camera: every shot needs a reason
90
+
91
+ - Use at least **four different camera moves** and real changes of framing. 2D has a camera too: push, pull, parallax, focus pulls, frames within frames.
92
+ - **One signature shot** people remember: a oner, a scale reveal, a transition made from the medium itself.
93
+ - **Design transitions inside the medium** (a page turn, a carved line growing, ink spreading), as one consistent grammar. Avoid default fades and hard cuts.
94
+ - At key moments the subject fills at least a third of the frame height, with clear staging and a readable silhouette.
95
+
96
+ ## 9. Performance
97
+
98
+ - **Anticipation, action, follow-through** on every meaningful move. Characters change emotion. They do not just slide across the screen.
99
+ - **Motion continuity**, especially for characters built from code rigs:
100
+ - Blend every pose with keyframes and easing; never switch poses inside an `if`. The only exception is a deliberate one-frame comic pop.
101
+ - Check shoulders and arms on a large action test sheet (reach, raise, run, kneel) before shooting (TECHNIQUE.md §10).
102
+ - Held props sit **between the palms**, at a depth between the two arms. A hand-over interpolates from one palm to the other. A rolling object turns by distance ÷ radius.
103
+ - Step through key actions at 0.2 s intervals, enlarged.
104
+ - Check every expression at final size, especially eyebrow direction: "worried" and "angry" are one flip apart.
105
+
106
+ ## 10. The failures we saw most
107
+
108
+ - Subject too small, too far away, or pushed against the frame edge.
109
+ - Too dark to read, or a colour laid on the same colour (red on red).
110
+ - Subtitles covering the subject.
111
+ - A gag or failure too fast to understand.
112
+ - Blank frames in transitions.
113
+ - A timed effect (iris, zoom, follow cam) that doesn't track the subject after the camera moves (one world → screen function, TECHNIQUE.md §2).
114
+
115
+ ## 11. Before you deliver
116
+
117
+ - Run the review loop (TECHNIQUE.md §8): contact sheets, 0.2 s strips of key actions, one full-speed viewing with sound.
118
+ - **One fix round.** Fix everything the review and the checks below find in one round, then check once more. Small fixes that second check turns up (a level, a frame) belong to the same round; anything bigger, tell the user in one line when you deliver. The user's notes after delivery are new rounds: change only what they ask.
119
+ - **Not the demo again.** After the treatment, read `DEMO.md` and compare: structure, opening, signature shot, camera path, score shape, ending. At least four of the six must differ; rethink the ones that match. Before delivery, put your contact sheet next to the demo poster (`styles/<slug>/poster.jpg`) as a last check.
120
+ - Voice: every line transcribes back correctly (speech-to-text check). For Chinese, one misheard character in a short line is normal: listen, and if it is right, let the check expect what the model heard (TECHNIQUE.md §4).
121
+ - Loudness about −14 LUFS; no black frames, no NaN frames; subtitles in sync and not covering key action.
122
+ - Every row of the sound design table is actually in the mix.
123
+ - No LemoLab sign-off: `grep -rniE "lemo ?lab|opus 5\.5" <project folder>` finds nothing outside `LICENSE`, `CREDITS` and the library's path in `LIB=` lines, and you have watched the last seconds of the film (text drawn into an image can't be grepped).
124
+
125
+ **Deliver**, in the project folder (the complete list):
126
+
127
+ - `<name>.mp4` (24 fps unless `STYLE.md` sets another rate, about −14 LUFS) and `poster.jpg`;
128
+ - `<name>.srt`, when the film has narration, dialogue or subtitles;
129
+ - `TREATMENT.md`;
130
+ - `CREDITS`: every third-party asset in the film (sample libraries, music, fonts, images, the voice engine) with its source and licence (TECHNIQUE.md §11);
131
+ - the source, with a one-command `build.sh` (TECHNIQUE.md §2).
132
+
133
+ **Tell the user**, in their language: where the project folder and the film are; that `CREDITS` lists the third-party assets in the film and their licences; and that they are responsible for the materials they use in it.
134
+
135
+ ## 12. Copyright red lines
136
+
137
+ - References teach grammar only. Don't copy characters, designs, melodies, shots, logos or type designs.
138
+ - No existing works, games, brands or events appear in the film unless the user owns them or has the right to use them. That includes the logos, photos and footage the user hands you: use them when they say they have the right, otherwise draw fictional stand-ins.
139
+ - Some of our demos are unofficial fan films of real events or characters. Keep the style, and never carry those names, marks or characters into a user's film.