primocode 10.12.0 → 10.14.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 (207) hide show
  1. package/README.md +74 -12
  2. package/bin/primocode.js +148 -8
  3. package/lib/act.js +48 -1
  4. package/lib/catalogo.js +12 -1
  5. package/lib/config.js +1 -0
  6. package/lib/estudio/assinaturas/gerativo.json +1 -1
  7. package/lib/estudio/camadas.js +4 -0
  8. package/lib/estudio/cota.js +150 -0
  9. package/lib/estudio/dados/projetos/clube-ad5.json +105 -0
  10. package/lib/estudio/dados/projetos/clube-ae-sem-memoria.json +107 -0
  11. package/lib/estudio/dados/projetos/clube-agent.json +120 -0
  12. package/lib/estudio/dados/projetos/clube-antes-e-agora.json +86 -0
  13. package/lib/estudio/dados/projetos/clube-apresentando-clube.json +110 -0
  14. package/lib/estudio/dados/projetos/clube-bluevisa.json +106 -0
  15. package/lib/estudio/dados/projetos/clube-caught-in-the-fire.json +127 -0
  16. package/lib/estudio/dados/projetos/clube-chat-cliente-satisfeito.json +98 -0
  17. package/lib/estudio/dados/projetos/clube-chatgpt-anuncios.json +120 -0
  18. package/lib/estudio/dados/projetos/clube-claude-dj.json +140 -0
  19. package/lib/estudio/dados/projetos/clube-claude-mcp.json +142 -0
  20. package/lib/estudio/dados/projetos/clube-cleanui.json +106 -0
  21. package/lib/estudio/dados/projetos/clube-clinica-take-unico.json +128 -0
  22. package/lib/estudio/dados/projetos/clube-clinica.json +104 -0
  23. package/lib/estudio/dados/projetos/clube-clube-opener.json +125 -0
  24. package/lib/estudio/dados/projetos/clube-clube.json +108 -0
  25. package/lib/estudio/dados/projetos/clube-codigo.json +101 -0
  26. package/lib/estudio/dados/projetos/clube-distilbook.json +104 -0
  27. package/lib/estudio/dados/projetos/clube-drive-upload.json +115 -0
  28. package/lib/estudio/dados/projetos/clube-dub.json +119 -0
  29. package/lib/estudio/dados/projetos/clube-enxovaly.json +105 -0
  30. package/lib/estudio/dados/projetos/clube-fecha7.json +118 -0
  31. package/lib/estudio/dados/projetos/clube-filatov.json +128 -0
  32. package/lib/estudio/dados/projetos/clube-frame.json +108 -0
  33. package/lib/estudio/dados/projetos/clube-glass.json +118 -0
  34. package/lib/estudio/dados/projetos/clube-letra-em-apps.json +84 -0
  35. package/lib/estudio/dados/projetos/clube-letra-globo-3d.json +111 -0
  36. package/lib/estudio/dados/projetos/clube-letra-nos-apps.json +146 -0
  37. package/lib/estudio/dados/projetos/clube-letra-seis-mundos.json +100 -0
  38. package/lib/estudio/dados/projetos/clube-lula-3.json +146 -0
  39. package/lib/estudio/dados/projetos/clube-morph.json +119 -0
  40. package/lib/estudio/dados/projetos/clube-motion-designer.json +115 -0
  41. package/lib/estudio/dados/projetos/clube-motion-pacote.json +112 -0
  42. package/lib/estudio/dados/projetos/clube-movimento.json +103 -0
  43. package/lib/estudio/dados/projetos/clube-not-like-us.json +117 -0
  44. package/lib/estudio/dados/projetos/clube-pinterest-inspiracao.json +86 -0
  45. package/lib/estudio/dados/projetos/clube-pixel-e-tinta.json +108 -0
  46. package/lib/estudio/dados/projetos/clube-ponte.json +118 -0
  47. package/lib/estudio/dados/projetos/clube-processo-edit-tonal.json +126 -0
  48. package/lib/estudio/dados/projetos/clube-processo-motion-100-ia.json +109 -0
  49. package/lib/estudio/dados/projetos/clube-promo.json +114 -0
  50. package/lib/estudio/dados/projetos/clube-proposito.json +115 -0
  51. package/lib/estudio/dados/projetos/clube-rankhog.json +128 -0
  52. package/lib/estudio/dados/projetos/clube-recursao.json +116 -0
  53. package/lib/estudio/dados/projetos/clube-revelar.json +118 -0
  54. package/lib/estudio/dados/projetos/clube-robo.json +125 -0
  55. package/lib/estudio/dados/projetos/clube-shelby-ep2.json +144 -0
  56. package/lib/estudio/dados/projetos/clube-shelby.json +97 -0
  57. package/lib/estudio/dados/projetos/clube-solar-eclipse.json +96 -0
  58. package/lib/estudio/dados/projetos/clube-soldier.json +128 -0
  59. package/lib/estudio/dados/projetos/clube-som-de-cena.json +108 -0
  60. package/lib/estudio/dados/projetos/clube-spotify-candidatura.json +112 -0
  61. package/lib/estudio/dados/projetos/clube-tda-app.json +118 -0
  62. package/lib/estudio/dados/projetos/clube-tda-ia.json +75 -0
  63. package/lib/estudio/dados/projetos/clube-telegram-chat.json +118 -0
  64. package/lib/estudio/dados/projetos/clube-telegram-ilha.json +106 -0
  65. package/lib/estudio/dados/projetos/clube-tennessee-nike.json +132 -0
  66. package/lib/estudio/dados/projetos/clube-tudo-se-move.json +112 -0
  67. package/lib/estudio/dados/projetos/clube-uiad.json +107 -0
  68. package/lib/estudio/dados/projetos/clube-viralgrow.json +108 -0
  69. package/lib/estudio/dados/projetos/clube-whose-side.json +140 -0
  70. package/lib/estudio/dados/projetos/clube-youtube-inscrever.json +108 -0
  71. package/lib/estudio/dados/projetos/elementos-do-site-em-movimento.json +49 -0
  72. package/lib/estudio/dados/projetos/explainer-narrado.json +51 -0
  73. package/lib/estudio/dados/projetos/lancamento-de-produto.json +51 -0
  74. package/lib/estudio/dados/projetos/motion-so-com-sons.json +50 -0
  75. package/lib/estudio/dados/projetos/titulo-em-after-effects.json +51 -0
  76. package/lib/estudio/dados/projetos/tour-de-saas.json +50 -0
  77. package/lib/estudio/dados/projetos-ae/antes-e-agora/ae/cenas.jsx +733 -0
  78. package/lib/estudio/dados/projetos-ae/antes-e-agora/assets/fazer_assets.py +88 -0
  79. package/lib/estudio/dados/projetos-ae/letra-em-apps/ae/cenas.jsx +402 -0
  80. package/lib/estudio/dados/projetos-ae/letra-em-apps/assets/preparar_assets.py +17 -0
  81. package/lib/estudio/dados/projetos-ae/letra-em-apps/assets/svg_para_ae.py +25 -0
  82. package/lib/estudio/dados/projetos-ae/letra-nos-apps/BRIEF-AGENTES.md +31 -0
  83. package/lib/estudio/dados/projetos-ae/letra-nos-apps/README.md +53 -0
  84. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ROTEIRO-CENAS.md +69 -0
  85. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/A-agenda.jsx +148 -0
  86. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/B-docs.jsx +174 -0
  87. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/C-alttab.jsx +113 -0
  88. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/D-spotify.jsx +118 -0
  89. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/E-notas.jsx +146 -0
  90. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/F-jornal1.jsx +144 -0
  91. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/G-google.jsx +153 -0
  92. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/H-mapa.jsx +176 -0
  93. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/I-imagens.jsx +132 -0
  94. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/J-jornal2.jsx +191 -0
  95. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/K-maps.jsx +184 -0
  96. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/camera-movimentos.jsx +48 -0
  97. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/camera.jsx +57 -0
  98. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/card-spotify.jsx +98 -0
  99. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/digitar.jsx +38 -0
  100. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/jornal-comum.jsx +196 -0
  101. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/letra.jsx +23 -0
  102. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/letra_automatica.py +83 -0
  103. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/montagem.jsx +74 -0
  104. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/w-agenda/render_html.py +13 -0
  105. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/w-agenda/util.jsx +162 -0
  106. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/w-midia-comum.jsx +114 -0
  107. package/lib/estudio/dados/projetos-ae/letra-nos-apps/ae/wg-util.jsx +360 -0
  108. package/lib/estudio/dados/projetos-ae/letra-nos-apps/assets/F-jornal1/render_html.py +13 -0
  109. package/lib/estudio/dados/projetos-ae/letra-nos-apps/assets/render_w-midia.py +26 -0
  110. package/lib/estudio/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/inclin.py +30 -0
  111. package/lib/estudio/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/medir_d.py +36 -0
  112. package/lib/estudio/dados/projetos-ae/letra-nos-apps/assets/w-midia-ferramentas/medir_e.py +27 -0
  113. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/ajustar_movimentos.py +61 -0
  114. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/ancorar.py +74 -0
  115. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/assar.py +47 -0
  116. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/camera3d_jornal.py +172 -0
  117. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/comparar.py +32 -0
  118. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/dados_ae_jornal.py +46 -0
  119. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/folha_contato.py +28 -0
  120. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/homografia_jornal.py +74 -0
  121. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/integrar.py +44 -0
  122. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/medir_quadro_a_quadro.py +32 -0
  123. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/mesa_2d.py +64 -0
  124. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/plot_cenas.py +11 -0
  125. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/retificar_quadros.py +38 -0
  126. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/w-agenda/assar_ab.py +52 -0
  127. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/w-agenda/medir_ab.py +59 -0
  128. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/wg_ajustar_h.py +111 -0
  129. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/wg_corrige_cam.py +17 -0
  130. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/wg_ecc_cadeia.py +80 -0
  131. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/wg_finalizar_cam.py +65 -0
  132. package/lib/estudio/dados/projetos-ae/letra-nos-apps/camera/wg_mosaico.py +61 -0
  133. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/01-gramatica-e-roteiro.md +55 -0
  134. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/02-camera.md +66 -0
  135. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/03-montagem-no-ae.md +50 -0
  136. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/04-render-e-conferencia.md +43 -0
  137. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces/05-abertura-celular-mergulho.md +43 -0
  138. package/lib/estudio/dados/projetos-ae/letra-nos-apps/guia-do-metodo/tutorial-lyric-edit-interfaces.md +42 -0
  139. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/atraso_imagem.py +31 -0
  140. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/fundo.py +56 -0
  141. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/juntar.py +45 -0
  142. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/montar.py +177 -0
  143. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/rastreio.py +74 -0
  144. package/lib/estudio/dados/projetos-ae/letra-nos-apps/transicao/sincronia.py +18 -0
  145. package/lib/estudio/dados/projetos-ae/pinterest-inspiracao/ae/cenas.jsx +530 -0
  146. package/lib/estudio/dados/projetos-ae/pinterest-inspiracao/assets/fazer_assets.py +107 -0
  147. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/assets/pessoas/figurinha.py +46 -0
  148. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/BRIEF-A.md +83 -0
  149. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/audio.py +179 -0
  150. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/confere.py +20 -0
  151. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/dados/tempo-parte1.js +1 -0
  152. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/dados/tempo-parte2.js +1 -0
  153. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/gerar_emojis.py +11 -0
  154. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/img/filmes/_indice.js +122 -0
  155. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/base.js +380 -0
  156. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/main.js +86 -0
  157. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1a.js +169 -0
  158. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1b.js +455 -0
  159. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p1c.js +389 -0
  160. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/js/p2.js +379 -0
  161. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/comp-a/video.py +62 -0
  162. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/take-unico/README.md +65 -0
  163. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/take-unico/oraculo_take.py +137 -0
  164. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/take-unico/render_take.py +388 -0
  165. package/lib/estudio/dados/projetos-ae/processo-motion-100-ia/take-unico/take.js +235 -0
  166. package/lib/estudio/diretor.js +2 -1
  167. package/lib/estudio/editor.js +285 -0
  168. package/lib/estudio/efeitos-fabrica/terminal-digitando.jsx +2 -1
  169. package/lib/estudio/effectcraft.js +152 -0
  170. package/lib/estudio/exportar.js +181 -0
  171. package/lib/estudio/gerativo.js +44 -15
  172. package/lib/estudio/index.js +126 -5
  173. package/lib/estudio/kit/gerativo.jsx +15 -0
  174. package/lib/estudio/kit-ae/base.jsx +1146 -0
  175. package/lib/estudio/kit-ae/cenas.jsx +395 -0
  176. package/lib/estudio/kit-ae/primitivas.jsx +911 -0
  177. package/lib/estudio/kokoro.js +3 -1
  178. package/lib/estudio/maquina-diretor.js +393 -0
  179. package/lib/estudio/maquina-elementos.js +134 -0
  180. package/lib/estudio/maquina-layout.js +198 -0
  181. package/lib/estudio/maquina-som.js +478 -0
  182. package/lib/estudio/maquina-trilha.js +160 -0
  183. package/lib/estudio/maquina-voz.js +429 -0
  184. package/lib/estudio/maquina.js +516 -0
  185. package/lib/estudio/projetos.js +60 -0
  186. package/lib/estudio/remotion.js +6 -4
  187. package/lib/estudio/revisor.js +61 -0
  188. package/lib/estudio/voicestudio.js +81 -0
  189. package/lib/headless.js +71 -0
  190. package/lib/hooks.js +72 -0
  191. package/lib/local/cerebro.json +398 -12
  192. package/lib/local/entrada.js +46 -2
  193. package/lib/marca-kit.js +309 -0
  194. package/lib/mcp.js +286 -6
  195. package/lib/perigo.js +31 -3
  196. package/lib/planos.js +47 -19
  197. package/lib/preparar.js +111 -0
  198. package/lib/retomar.js +55 -0
  199. package/lib/sandbox.js +197 -0
  200. package/lib/skills.js +3 -1
  201. package/lib/tools.js +13 -4
  202. package/lib/ui.js +1 -1
  203. package/lib/video/auto.js +18 -3
  204. package/package.json +4 -2
  205. package/skills/after-effects/SKILL.md +52 -0
  206. package/skills/maquina-de-motion/SKILL.md +84 -0
  207. package/skills/motion-de-primeira/SKILL.md +33 -51
@@ -0,0 +1,455 @@
1
+ /* p1b.js — Parte 1, falas 06–13 (29,6–91,4 s): Passo 1 "Referência" e Passo 2 "Identidade visual". MODO PALCO (STORYBOARD-B.md):
2
+ * a tela é do elemento que desenha a palavra-chave da frase; legenda curta embaixo. Abaixo, peças antigas reaproveitadas.
3
+ * Peças deste trecho (uma janela a cada 2–3 frases):
4
+ * 07 caixa do prompt: o prompt longo corre; o cursor @seu.perfil arrasta 3 prints reais (Pinterest, Mobbin, player de vidro)
5
+ * 08 notificação do iPhone saindo da Dynamic Island em "Apple" (aprovada) + 2 templates do YouMotion no estilo Apple
6
+ * 09 3 estilos diferentes caem na mesma pasta "referências" · 11 brand board se montando · 13 busca real no Pinterest */
7
+ (function () {
8
+ const REF = { pin: '../comp-v31/img/ref-pinterest-apple-ui.jpg', mob: '../assets/telas/mobbin-ios-dashboard-screens.png', vidro: '../comp-v31/img/ref-apple-glass-player.jpg' };
9
+ const UI = '"Inter", "Segoe UI", sans-serif';
10
+ const img = (pai, src, css = {}) => { const e = $('img', null, pai, Object.assign({ position: 'absolute', display: 'block', objectFit: 'cover' }, css)); e.src = src; e.decoding = 'sync'; return e; };
11
+ const cartao = (pai, css = {}) => $('div', 'janela', pai, Object.assign({ background: '#fff' }, css));
12
+ const cursorTag = (pai, tag = '@seu.perfil') => $('div', 'cursor', pai, { width: 'auto', height: 'auto', zIndex: 60 },
13
+ `<svg viewBox="0 0 32 32" width="64" height="64" style="display:block"><path d="M7 3.5 L7 25.5 L12.4 20.4 L16 28.6 L19.6 27 L16.1 19 L23.6 19 Z" fill="#111" stroke="#fff" stroke-width="2" stroke-linejoin="round"/></svg>` +
14
+ `<span style="position:absolute;left:44px;top:50px;font:600 22px/1 GS;color:#fff;background:#2F55F4;padding:7px 12px 8px;border-radius:10px;white-space:nowrap;box-shadow:0 8px 20px rgba(47,85,244,.35)">${tag}</span>`);
15
+ const caminho = (t, K) => { if (t <= K[0].t) return K[0]; for (let i = 0; i < K.length - 1; i++) { const a = K[i], b = K[i + 1]; if (t <= b.t) { const k = IO(seg(t, a.t, b.t)); return { x: lerp(a.x, b.x, k), y: lerp(a.y, b.y, k), s: lerp(a.s ?? 1, b.s ?? 1, k) }; } } return K[K.length - 1]; };
16
+
17
+ // ═══ 07 · caixa do prompt + prints reais arrastados para dentro ═══
18
+ const PROMPT = 'Cria um Reel vertical 1080×1920, narrado, no estilo motion: tipografia cinética palavra a palavra, câmera que nunca para, ícones animados dentro da frase, transições pelo desfoque, trilha jazz hop baixa e um efeito sonoro em cada entrada. Use as referências anexadas para o visual.';
19
+ function promptRefs(o) {
20
+ return bloco(Object.assign({ h: 520, kind: 'abre',
21
+ monta(el, B) {
22
+ B.c = cartao(el);
23
+ B.txt = $('div', null, B.c, { position: 'absolute', left: '36px', right: '36px', top: '40px', height: '300px', overflow: 'hidden', font: `500 28px/1.5 ${UI}`, color: '#141413' });
24
+ const barra = $('div', null, B.c, { position: 'absolute', left: '0', right: '0', bottom: '0', height: '96px', borderTop: '1px solid rgba(0,0,0,.06)' });
25
+ $('div', null, barra, { position: 'absolute', left: '26px', top: '24px', width: '46px', height: '46px', borderRadius: '14px', boxShadow: '0 0 0 1.5px rgba(0,0,0,.14)', display: 'grid', placeItems: 'center', font: `400 32px/1 ${UI}`, color: '#555' }, '+');
26
+ $('div', null, barra, { position: 'absolute', right: '96px', top: '33px', font: `500 22px/1 ${UI}`, color: '#6B6A66' }, 'Opus 5.5 ⌄');
27
+ $('div', null, barra, { position: 'absolute', right: '24px', top: '22px', width: '52px', height: '50px', borderRadius: '14px', background: '#C96442', display: 'grid', placeItems: 'center' }, '<svg width="24" height="24" viewBox="0 0 20 20"><path d="M10 16V4M4.5 9.5 10 4l5.5 5.5" stroke="#fff" stroke-width="2.2" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>');
28
+ // prints: pilha à direita, embaixo do card; o cursor leva um por vez até o slot de anexo
29
+ B.refs = [REF.pin, REF.mob, REF.vidro].map((src, i) => { const d = $('div', null, el, { position: 'absolute', left: '0', top: '0', width: '250px', height: '310px', borderRadius: '20px', overflow: 'hidden', background: '#fff', zIndex: 40 - i, transformOrigin: '0 0', boxShadow: '0 30px 60px -16px rgba(20,20,40,.40), 0 0 0 1px rgba(0,0,0,.06)' }); img(d, src, { inset: '0', width: '100%', height: '100%', objectPosition: i === 1 ? '18% 50%' : '50% 20%' }); return d; });
30
+ B.cur = cursorTag(el);
31
+ const T = B.tRef; B.SLOT = i => ({ x: 30 + i * 136, y: 26 });
32
+ B.PILHA = i => ({ x: 650 + i * 12, y: 130 + i * 12, r: [7, -4, 3][i] });
33
+ B.drag = [0, 1, 2].map(i => ({ t0: T + i * 0.72, t1: T + i * 0.72 + 0.46 }));
34
+ B.drag.forEach((d, i) => { ev(d.t0, 'desliza', 0.4, 0.2); ev(d.t1, 'pouso', -0.2, 0.22); });
35
+ },
36
+ seek(t, B) {
37
+ abreJanela(t, B.c, B.t, { lado: 4 });
38
+ const kA = ILL(seg(t, B.drag[0].t1 - 0.15, B.drag[0].t1 + 0.25));
39
+ B.txt.style.top = lerp(40, 196, kA).toFixed(1) + 'px';
40
+ const n = Math.floor(clamp((t - B.t - 0.15) / 1.1) * PROMPT.length);
41
+ B.txt.innerHTML = PROMPT.slice(0, n) + (t > B.t && t < B.tRef ? '<span style="display:inline-block;width:2px;height:32px;background:#141413;vertical-align:-6px;margin-left:2px"></span>' : '');
42
+ // pilha entra pela direita pelo desfoque antes de "referências"
43
+ const kP = ILL(seg(t, B.tRef - 0.45, B.tRef - 0.05));
44
+ let curPos = null;
45
+ B.refs.forEach((d, i) => {
46
+ const D = B.drag[i], P = B.PILHA(i), S = B.SLOT(i);
47
+ const u = seg(t, D.t0, D.t1), k = IO(u);
48
+ const x = lerp(P.x + (1 - kP) * 380, S.x, k), y = lerp(P.y, S.y, k), sc = lerp(1, 120 / 250, ILL(u)), r = lerp(P.r, 0, k) + Math.sin(Math.PI * u) * 4;
49
+ tf(d, { x, y, s: sc, r, op: kP, blur: (1 - kP) * 16 });
50
+ d.style.borderRadius = lerp(20, 30, k).toFixed(1) + 'px';
51
+ if (t >= D.t0 - 0.25 && t <= D.t1 + 0.05 && !curPos) curPos = { x: x + 120 * sc, y: y + 40 * sc };
52
+ });
53
+ // cursor: vai à pilha, leva o print, volta à pilha (curva única), sai no fim
54
+ const K = []; B.drag.forEach((D, i) => { const P = B.PILHA(i), S = B.SLOT(i); K.push({ t: D.t0 - 0.06, x: P.x + 120, y: P.y + 40 }, { t: D.t1, x: S.x + 120 * 0.48, y: S.y + 40 * 0.48 }); });
55
+ K.unshift({ t: B.tRef - 0.5, x: 1060, y: 640 }); K.push({ t: B.drag[2].t1 + 0.5, x: 1100, y: 600 });
56
+ const c = caminho(t, K), op = seg(t, B.tRef - 0.5, B.tRef - 0.3) * (1 - seg(t, B.drag[2].t1 + 0.25, B.drag[2].t1 + 0.5));
57
+ const pr = Math.max(...B.drag.map(D => Math.exp(-Math.pow((t - D.t0) / 0.05, 2))));
58
+ tf(B.cur, { x: c.x - 7, y: c.y - 4, s: 1 - 0.14 * pr, op });
59
+ } }, o));
60
+ }
61
+
62
+ // ═══ 08 · notificação do iPhone saindo da Dynamic Island (camada de cima, topo da tela) ═══
63
+ function notifIlha(tAp, tOut) {
64
+ cena('08-ilha', tAp - 0.45, tOut + 0.6, (r, c) => {
65
+ c.n = $('div', null, r, { position: 'absolute', left: '0', top: '0', background: '#0A0A0B', overflow: 'hidden', boxShadow: '0 30px 70px -18px rgba(0,0,0,.45)' });
66
+ c.cont = $('div', null, c.n, { position: 'absolute', width: '990px', height: '200px' });
67
+ c.itens = [
68
+ $('div', null, c.cont, { position: 'absolute', left: '34px', top: '36px', width: '128px', height: '128px', borderRadius: '30px', background: '#fff', display: 'grid', placeItems: 'center' }, `<img src="${LOGO('apple-logo-black.svg')}" style="width:60px">`),
69
+ $('div', null, c.cont, { position: 'absolute', left: '192px', top: '40px', font: '600 40px/1 "SF Pro Display", GS', color: '#fff' }, 'Apple'),
70
+ $('div', null, c.cont, { position: 'absolute', right: '40px', top: '44px', font: '500 30px/1 "SF Pro Display", GS', color: 'rgba(255,255,255,.55)' }, 'agora'),
71
+ $('div', null, c.cont, { position: 'absolute', left: '192px', top: '98px', width: '760px', font: '500 34px/1.25 "SF Pro Display", GS', color: 'rgba(255,255,255,.82)' }, 'O design e a UI que eu mais uso')];
72
+ ev(tAp - 0.03, 'notif-iphone', 0, 0.7);
73
+ }, (t, c) => {
74
+ // a ilha desce do topo; a largura puxa primeiro, a altura vem atrás (estica líquido); recolhe e sobe com a mesma curva
75
+ const kIn = ILL(seg(t, tAp - 0.45, tAp - 0.12)), kW = bz(0.2, 1.08, 0.32, 1)(seg(t, tAp - 0.1, tAp + 0.4)), kH = ILL(seg(t, tAp - 0.03, tAp + 0.47)), kR = ILL(seg(t, tOut, tOut + 0.4)), kUp = ILLIN(seg(t, tOut + 0.3, tOut + 0.6));
76
+ let w = lerp(250, 990, kW), h = lerp(72, 200, kH), cy = lerp(70, 220, kH), rr = lerp(36, 58, kH);
77
+ w = lerp(w, 250, kR); h = lerp(h, 72, kR); cy = lerp(cy, 70, kR); rr = lerp(rr, 36, kR);
78
+ cy = cy - (1 - kIn) * 150 - kUp * 150;
79
+ Object.assign(c.n.style, { width: w.toFixed(1) + 'px', height: h.toFixed(1) + 'px', left: (540 - w / 2).toFixed(1) + 'px', top: (cy - h / 2).toFixed(1) + 'px', borderRadius: Math.min(rr, h / 2).toFixed(1) + 'px' });
80
+ c.cont.style.left = ((w - 990) / 2).toFixed(1) + 'px'; c.cont.style.top = ((h - 200) / 2).toFixed(1) + 'px';
81
+ c.itens.forEach((e, i) => { const a = seg(t, tAp + 0.12 + i * 0.04, tAp + 0.32 + i * 0.04) * (1 - seg(t, tOut - 0.1, tOut + 0.05)); tf(e, { y: (1 - a) * 14, op: a, blur: (1 - a) * 10 }); });
82
+ tf(c.n, { op: clamp(kIn * 1.5) * (1 - kUp) });
83
+ });
84
+ }
85
+
86
+ // ═══ 08 · dois templates do YouMotion no estilo Apple, lado a lado (sem som; a trilha segue) ═══
87
+ function parVertical(a, b, o) {
88
+ return bloco(Object.assign({ h: 700, kind: 'abre',
89
+ monta(el, B) { B.ca = cartao(el, { inset: 'auto', left: '0', top: '0', width: '440px', height: '700px' }); B.fa = filme(B.ca, a);
90
+ B.cb = cartao(el, { inset: 'auto', left: '472px', top: '0', width: '440px', height: '700px' }); B.fb = filme(B.cb, b); ev(B.t + 0.3, 'abre', 0.3, 0.2); },
91
+ seek(t, B) { abreJanela(t, B.ca, B.t, { lado: 0 }); abreJanela(t, B.cb, B.t + 0.3, { lado: 0 }); B.fa.toca(t, B.t, false); B.fb.toca(t, B.t + 0.3, false); } }, o));
92
+ }
93
+
94
+ // ═══ 09 · três estilos diferentes caem na mesma pasta "referências" ═══
95
+ function pastaRefs(o) {
96
+ const thumbs = ['img/filmes/glass-hub/0060.jpg', 'img/filmes/illdari-telegram/0055.jpg', 'img/filmes/ai-opener-vertical/0070.jpg'];
97
+ return bloco(Object.assign({ h: 460, kind: 'pop',
98
+ monta(el, B) {
99
+ B.cs = thumbs.map((src, i) => { const d = cartao(el, { inset: 'auto', left: (14 + i * 304) + 'px', top: '10px', width: '276px', height: '300px', zIndex: 5 - i }); img(d, src, { inset: '0', width: '100%', height: '100%' }); return d; });
100
+ B.p = $('div', null, el, { position: 'absolute', left: '336px', top: '150px', width: '240px', height: '300px', zIndex: 10, transformOrigin: '50% 70%' },
101
+ `<svg viewBox="0 0 240 190" width="240" height="190" style="display:block;filter:drop-shadow(0 22px 30px rgba(30,90,200,.30))"><path d="M14 30c0-9 7-16 16-16h58c6 0 10 2 13 7l9 13h100c9 0 16 7 16 16v14H14z" fill="#3E8EF0"/><rect x="14" y="44" width="212" height="132" rx="16" fill="#62A8F7"/><rect x="14" y="44" width="212" height="132" rx="16" fill="url(#gp)"/><defs><linearGradient id="gp" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".18"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>` +
102
+ `<div style="text-align:center;font:600 34px/1 GS;letter-spacing:-.02em;color:#131313;margin-top:22px">referências</div>`);
103
+ B.tF = B.tF ?? B.t + 0.55; B.cai = thumbs.map((_, i) => B.tF + 0.15 + i * 0.13);
104
+ B.cai.forEach((tc, i) => ev(tc + 0.4, 'pouso', [-0.4, 0, 0.4][i], 0.22));
105
+ },
106
+ seek(t, B) {
107
+ B.cs.forEach((d, i) => { const n = nasce(t, B.t + i * 0.12, 0.45), u = seg(t, B.cai[i], B.cai[i] + 0.45), k = IO(u);
108
+ const dx = (456 - (14 + i * 304 + 138)) * k, dy = (250 - 160) * k;
109
+ tf(d, { x: dx, y: dy + n.y, s: lerp(1, 0.22, k) * lerp(0.7, 1, n.k), r: [-5, 0, 5][i] * (1 - k), op: n.op * (1 - seg(t, B.cai[i] + 0.32, B.cai[i] + 0.45)), blur: n.blur }); });
110
+ const nF = nasce(t, B.tF, 0.45); let sq = 0; B.cai.forEach(tc => { const d = t - (tc + 0.4); if (d > 0 && d < 0.2) sq = Math.max(sq, Math.sin(Math.PI * d / 0.2)); });
111
+ tf(B.p, { op: nF.op, s: nF.s * (1 + 0.06 * sq), y: nF.y + 6 * sq, blur: nF.blur });
112
+ } }, o));
113
+ }
114
+
115
+ // ═══ 11 · brand board se montando: fonte, paleta e ícones da identidade deste vídeo ═══
116
+ function brandBoard(o) {
117
+ const cores = [['#131313', 'Tinta'], ['#F4F3EF', 'Fundo'], ['#2F55F4', 'Vídeo'], ['#D97757', 'IA'], ['#A19E96', 'Passado']];
118
+ const ic = ['<path d="M8 5v14l11-7z" fill="currentColor"/>', '<path d="M4 12h2M8 8v8M12 5v14M16 9v6M20 11v2" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" fill="none"/>',
119
+ '<path d="M12 2l2.2 6.6L21 11l-6.8 2.4L12 20l-2.2-6.6L3 11l6.8-2.4z" fill="currentColor"/>', '<path d="M6 3v16l4.5-4.2 3 7 3-1.3-3-6.8H20z" fill="currentColor"/>'];
120
+ return bloco(Object.assign({ h: 560, kind: 'abre',
121
+ monta(el, B) {
122
+ B.c = cartao(el);
123
+ B.aa = $('div', null, B.c, { position: 'absolute', left: '48px', top: '24px', font: '600 230px/1 GS', letterSpacing: '-0.05em', color: '#131313' }, 'Aa');
124
+ B.nome = $('div', null, B.c, { position: 'absolute', left: '54px', top: '262px', font: '600 34px/1.25 GS', color: '#131313' }, 'General Sans<br><span style="font-weight:500;color:#8B8880;font-size:26px">Semibold · 120 px</span>');
125
+ B.sw = cores.map(([cor, nome], i) => $('div', null, B.c, { position: 'absolute', left: (430 + (i % 3) * 150) + 'px', top: (44 + Math.floor(i / 3) * 170) + 'px', width: '120px', textAlign: 'center', font: `500 20px/1.3 ${UI}`, color: '#6B6A66' },
126
+ `<div style="width:104px;height:104px;margin:0 auto 10px;border-radius:50%;background:${cor};box-shadow:0 10px 24px -8px rgba(0,0,0,.25), inset 0 0 0 1px rgba(0,0,0,.08)"></div>${nome}`));
127
+ $('div', null, B.c, { position: 'absolute', left: '48px', right: '48px', top: '384px', height: '1px', background: 'rgba(0,0,0,.08)' });
128
+ B.ics = ic.map((p, i) => $('div', null, B.c, { position: 'absolute', left: (48 + i * 128) + 'px', top: '420px', width: '104px', height: '104px', borderRadius: '30px', background: i === 3 ? '#FBEDE7' : '#EEF1FE', color: i === 3 ? '#D97757' : '#2F55F4', display: 'grid', placeItems: 'center' }, `<svg viewBox="0 0 24 24" width="50" height="50">${p}</svg>`));
129
+ B.lg = $('div', null, B.c, { position: 'absolute', right: '48px', top: '436px', font: '600 30px/1.3 GS', color: '#131313', textAlign: 'right' }, 'Identidade<br><span style="color:#8B8880;font-weight:500">do vídeo</span>');
130
+ ev(B.t + 0.45, 'pop', -0.2, 0.18); ev(B.t + 0.95, 'pop', 0.2, 0.18);
131
+ },
132
+ seek(t, B) {
133
+ abreJanela(t, B.c, B.t, { lado: 4 });
134
+ const vida = (e, t0) => { const n = nasce(t, t0, 0.42); tf(e, { op: n.op, s: lerp(0.85, 1, n.k), y: n.y * 0.6, blur: n.blur }); };
135
+ vida(B.aa, B.t + 0.15); vida(B.nome, B.t + 0.3);
136
+ B.sw.forEach((e, i) => vida(e, B.t + 0.42 + i * 0.08)); B.ics.forEach((e, i) => vida(e, B.t + 0.9 + i * 0.08)); vida(B.lg, B.t + 1.2);
137
+ } }, o));
138
+ }
139
+
140
+ // ═══ 13 · busca real no Pinterest (barra recriada + print real rolando) ═══
141
+ function buscaPinterest(o) {
142
+ const Q = 'apple ui motion design';
143
+ return bloco(Object.assign({ h: 640, kind: 'abre',
144
+ monta(el, B) {
145
+ B.c = cartao(el);
146
+ img(B.c, LOGO('pinterest-icon-512.png'), { left: '30px', top: '28px', width: '60px', height: '60px', objectFit: 'contain' });
147
+ const bar = $('div', null, B.c, { position: 'absolute', left: '112px', right: '30px', top: '24px', height: '68px', borderRadius: '34px', background: '#EFEFEF' });
148
+ $('div', null, bar, { position: 'absolute', left: '24px', top: '19px' }, '<svg width="30" height="30" viewBox="0 0 24 24"><circle cx="10.5" cy="10.5" r="6.5" fill="none" stroke="#767676" stroke-width="2.4"/><path d="M15.5 15.5L21 21" stroke="#767676" stroke-width="2.6" stroke-linecap="round"/></svg>');
149
+ B.q = $('div', null, bar, { position: 'absolute', left: '70px', top: '18px', font: `500 28px/1.2 ${UI}`, color: '#111', whiteSpace: 'nowrap' });
150
+ B.vp = $('div', null, B.c, { position: 'absolute', left: '30px', right: '30px', top: '116px', bottom: '0', overflow: 'hidden', background: '#fff' });
151
+ B.im = $('div', null, B.vp, { position: 'absolute', left: '0', top: '0', width: '852px', height: '1400px' });
152
+ const F = 'img/filmes/', CW = 274, G = 15;
153
+ const cols = [[[REF.pin, 331], [F + 'illdari-telegram/0040.jpg', 274], [F + 'glass-hub/0080.jpg', 230], [F + 'emoji-ui-vertical/0090.jpg', 420]],
154
+ [[REF.vidro, 194], [F + 'emoji-ui-vertical/0060.jpg', 487], [F + 'illdari-upload/0030.jpg', 274], [REF.pin, 331]],
155
+ [['../comp-v31/img/ref-mobbin-sweatcoin.jpg', 470], [F + 'smartphone-ui-vertical/0100.jpg', 420], [F + 'ai-opener-vertical/0040.jpg', 360]]];
156
+ B.pins = [];
157
+ cols.forEach((col, c) => { let y = c === 1 ? 40 : 0; col.forEach(([src, h], j) => { const d = $('div', null, B.im, { position: 'absolute', left: (c * (CW + G)) + 'px', top: y + 'px', width: CW + 'px', height: h + 'px', borderRadius: '18px', overflow: 'hidden', background: '#eee' }); img(d, src, { inset: '0', width: '100%', height: '100%' }); B.pins.push({ d, i: c + j * 3 }); y += h + G; }); });
158
+ ev(B.t + 0.25, 'digita', 0.2, 0.3);
159
+ },
160
+ seek(t, B) {
161
+ abreJanela(t, B.c, B.t, { lado: 4 });
162
+ const n = Math.floor(clamp((t - B.t - 0.2) / 0.6) * Q.length); B.q.innerHTML = Q.slice(0, n) + (t < B.t + 1.0 ? '<span style="display:inline-block;width:2px;height:30px;background:#111;vertical-align:-6px;margin-left:2px"></span>' : '');
163
+ const rola = IO(seg(t, B.t + 1.2, B.t + 4.4)) * 380; tf(B.im, { y: -rola });
164
+ B.pins.forEach(p => { const k = nasce(t, B.t + 0.7 + p.i * 0.05, 0.45); tf(p.d, { op: k.op, y: (1 - k.k) * 50, s: lerp(0.94, 1, k.k), blur: k.blur }); });
165
+ } }, o));
166
+ }
167
+
168
+ // ─────────────────────────────── Passo 1 · MODO PALCO (17/10) ───────────────────────────────
169
+ // a tela é do elemento da frase; o texto é legenda curta embaixo (o grupo da vez). A coluna some até a fala 08.
170
+ ocultaColuna(CN('vitrine').t1 + 0.44, F0('14') - 0.15); // falas 06–13 inteiras em modo palco (a coluna volta só se o p1c ainda usar linhas)
171
+ // 06 · "Passo um: não existe vídeo diferente sem referência."
172
+ const tH1 = PF('06', 'nao') - 0.12;
173
+ passoHeroi(1, 'u1f50d', F0('06') - 0.08, tH1, { ate: F0('10') - 0.25 });
174
+ legenda('06', [pula(2), ['não existe', 'vídeo', 'f|diferente'], 'sem af|referência.']);
175
+ // palco: um vídeo vazio (moldura tracejada); a lupa procura e não acha nada → 🤷 em "referência"
176
+ palco(tH1 + 0.02, F0('07') + 0.15, (el, P) => {
177
+ P.fr = $('div', null, el, { position: 'absolute', left: (540 - 290) + 'px', top: (PALCO_Y - 360) + 'px', width: '580px', height: '720px' },
178
+ `<svg width="580" height="720" viewBox="0 0 580 720"><rect x="4" y="4" width="572" height="712" rx="56" fill="rgba(255,255,255,.55)" stroke="#C9C6BE" stroke-width="5" stroke-dasharray="22 18"/>` +
179
+ `<path d="M262 330 L262 390 L314 360 Z" fill="none" stroke="#C9C6BE" stroke-width="7" stroke-linejoin="round"/></svg>`);
180
+ P.lupa = $('div', null, el, { position: 'absolute', left: '0', top: '0', width: '230px', height: '230px' }); P.lot = emojiLot(P.lupa, 'u1f50d', 230);
181
+ P.sh = $('div', null, el, { position: 'absolute', left: (540 - 170) + 'px', top: (PALCO_Y - 170) + 'px', width: '340px', height: '340px' }); P.shl = emojiLot(P.sh, 'u1f937-200d-2642', 340);
182
+ P.tR = PF('06', 'referencia') + 0.05; ev(P.tR, 'pop', 0, 0.3);
183
+ }, (t, P) => {
184
+ const u = t - P.t0, kS = ILL(seg(t, P.tR - 0.1, P.tR + 0.3));
185
+ tf(P.lupa, { x: 540 - 115 + 170 * Math.sin(u * 2.3), y: PALCO_Y - 140 - 115 + 150 * Math.sin(u * 4.6), op: 1 - kS, s: 1 - 0.4 * kS, blur: kS * 14 }); P.lot.toca(t, P.t0);
186
+ tf(P.fr, { op: 1 - 0.45 * kS, s: 1 - 0.03 * kS });
187
+ const n = nasce(t, P.tR, 0.5); tf(P.sh, { op: n.op, s: n.s, y: n.y, blur: n.blur }); P.shl.toca(t, P.tR);
188
+ }, { esc: 1.2 });
189
+
190
+ // 07 · "Como você já deve saber, não basta você ter um super prompt bem feito e detalhado, se você não tem referências..."
191
+ legenda('07', [
192
+ 'Como você já deve saber,',
193
+ 'não basta você ter',
194
+ ['um super', 'f|prompt', emoji('u270d')],
195
+ 'bem feito e detalhado,',
196
+ ['se você não tem', 'af|referências', logo('pinterest-icon-512.png', { tam: 84, gira: false })],
197
+ 'do estilo que você quer',
198
+ 'pro seu a|vídeo.',
199
+ ], { ate: F0('08') - 0.3 });
200
+ // palco: 😉 ("como você já deve saber") vira a caixa do prompt (aprovada): o prompt corre e o cursor arrasta os prints
201
+ palco(F0('07') - 0.02, PF('07', 'ter') - 0.05, (el, P) => {
202
+ P.e = $('div', null, el, { position: 'absolute', left: (540 - 190) + 'px', top: (PALCO_Y - 190) + 'px', width: '380px', height: '380px' }); P.l = emojiLot(P.e, 'u1f609', 380); ev(P.t0 + 0.05, 'pop', 0, 0.25);
203
+ }, (t, P) => { tf(P.e, { r: 4 * Math.sin((t - P.t0) * 2.2), y: 6 * Math.sin((t - P.t0) * 1.7) }); P.l.toca(t, P.t0); }, { esc: 1.3 });
204
+ palco(PF('07', 'ter') - 0.05, F0('08') - 0.3, promptRefs({ t: PF('07', 'ter') + 0.02, tRef: PF('07', 'referencias') + 0.05 }), { y: 800 });
205
+
206
+ // ═════════════════════════════ falas 08–13 · MODO PALCO (STORYBOARD-B) ═════════════════════════════
207
+ // Peças que viram a próxima; o palco desenha a palavra-chave no instante em que ela é dita.
208
+ const GOO = (() => { const s = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); s.setAttribute('width', 0); s.setAttribute('height', 0); s.style.position = 'absolute';
209
+ s.innerHTML = '<defs><filter id="gooB" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur in="SourceGraphic" stdDeviation="18" result="b"/><feColorMatrix in="b" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 28 -12"/></filter></defs>';
210
+ document.body.appendChild(s); return 'url(#gooB)'; })();
211
+ const CORACAO = '<svg viewBox="0 0 24 24" width="100%" height="100%"><path d="M12 21s-7.5-4.6-9.6-9.2C.8 8.2 3 4.5 6.6 4.5c2.2 0 3.6 1.3 5.4 3.3 1.8-2 3.2-3.3 5.4-3.3 3.6 0 5.8 3.7 4.2 7.3C19.5 16.4 12 21 12 21z" fill="#FF3B5C"/></svg>';
212
+ const PASTA = `<svg viewBox="0 0 240 190" width="100%" height="100%" style="display:block;filter:drop-shadow(0 22px 30px rgba(30,90,200,.30))"><path d="M14 30c0-9 7-16 16-16h58c6 0 10 2 13 7l9 13h100c9 0 16 7 16 16v14H14z" fill="#3E8EF0"/><rect x="14" y="44" width="212" height="132" rx="16" fill="#62A8F7"/></svg>`;
213
+ const caixa = (pai, x, y, w, h, css = {}, html) => $('div', null, pai, Object.assign({ position: 'absolute', left: x + 'px', top: y + 'px', width: w + 'px', height: h + 'px' }, css), html);
214
+ const emo = (pai, id, cx, cy, tam) => { const b = caixa(pai, cx - tam / 2, cy - tam / 2, tam, tam); b.lot = emojiLot(b, id, tam); return b; };
215
+ const vive = (e, t, t0, d = 0.45) => { const n = nasce(t, t0, d); return n; };
216
+ // pilar de templo (SVG) com o nome gravado na base; revela de baixo para cima
217
+ function pilar(pai, cx, base, rotulo, esc = 1) {
218
+ const W = 260, Hh = 640, p = caixa(pai, cx - W / 2, base - Hh, W, Hh, { transformOrigin: '50% 100%' });
219
+ p.innerHTML = `<svg viewBox="0 0 260 640" width="260" height="640" style="display:block;filter:drop-shadow(0 30px 40px rgba(60,50,30,.18))"><defs><linearGradient id="pd${rotulo}" x1="0" x2="1"><stop offset="0" stop-color="#DCD5C7"/><stop offset=".5" stop-color="#F5F1EA"/><stop offset="1" stop-color="#D3CBBB"/></linearGradient></defs>
220
+ <rect x="0" y="0" width="260" height="34" rx="6" fill="url(#pd${rotulo})"/><path d="M24 34 H236 L214 66 H46 Z" fill="url(#pd${rotulo})"/>
221
+ <rect x="44" y="66" width="172" height="474" fill="url(#pd${rotulo})"/>${[78, 108, 130, 152, 182].map(x => `<line x1="${x}" y1="72" x2="${x}" y2="534" stroke="#CFC6B6" stroke-width="3"/>`).join('')}
222
+ <rect x="26" y="540" width="208" height="30" rx="4" fill="url(#pd${rotulo})"/><rect x="0" y="570" width="260" height="70" rx="6" fill="url(#pd${rotulo})"/>
223
+ <text x="130" y="616" text-anchor="middle" font-family="GS" font-weight="600" font-size="30" letter-spacing="-0.5" fill="#8A8170">${rotulo}</text></svg>`;
224
+ p.style.transform = `scale(${esc})`; return p;
225
+ }
226
+ // brand book: capa escura que abre (3D) e mostra paleta + "Aa" + ícones
227
+ function brandBook(pai, cx, cy) {
228
+ const B = caixa(pai, cx - 440, cy - 300, 880, 600, { perspective: '2200px' });
229
+ B.pd = caixa(B, 440, 0, 440, 600, { background: '#fff', borderRadius: '6px 22px 22px 6px', boxShadow: '0 40px 80px -24px rgba(30,30,60,.30), 0 0 0 1px rgba(0,0,0,.05)' },
230
+ `<div style="position:absolute;left:44px;top:40px;font:600 170px/1 GS;letter-spacing:-.05em;color:#131313">Aa</div><div style="position:absolute;left:50px;top:226px;font:600 30px/1.3 GS;color:#131313">General Sans<br><span style="color:#8B8880;font-weight:500;font-size:24px">Semibold · 80–120 px</span></div>` +
231
+ `<div style="position:absolute;left:44px;top:350px;display:flex;gap:16px">${['<path d="M8 5v14l11-7z" fill="currentColor"/>', '<path d="M12 2l2.2 6.6L21 11l-6.8 2.4L12 20l-2.2-6.6L3 11l6.8-2.4z" fill="currentColor"/>', '<path d="M4 12h2M8 8v8M12 5v14M16 9v6M20 11v2" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" fill="none"/>'].map((p, i) => `<div style="width:96px;height:96px;border-radius:28px;background:${i === 1 ? '#FBEDE7' : '#EEF1FE'};color:${i === 1 ? '#D97757' : '#2F55F4'};display:grid;place-items:center"><svg viewBox="0 0 24 24" width="46" height="46">${p}</svg></div>`).join('')}</div>` +
232
+ `<div style="position:absolute;left:44px;bottom:40px;font:500 22px/1 GS;color:#A19E96">brand book · página 2</div>`);
233
+ B.capa = caixa(B, 440, 0, 440, 600, { transformOrigin: '0 50%', transformStyle: 'preserve-3d' });
234
+ B.frente = caixa(B.capa, 0, 0, 440, 600, { background: 'linear-gradient(160deg,#1C1C1F,#0E0E10)', borderRadius: '6px 22px 22px 6px', backfaceVisibility: 'hidden', boxShadow: '0 40px 80px -24px rgba(20,20,40,.45)', overflow: 'hidden' },
235
+ `<div style="position:absolute;left:44px;top:56px;font:600 64px/1 GS;letter-spacing:-.04em;color:#fff">Brand<br>book</div><div style="position:absolute;left:46px;top:200px;font:500 28px/1 GS;color:rgba(255,255,255,.55)">seu vídeo</div>` +
236
+ `<div style="position:absolute;left:44px;bottom:48px;display:flex;gap:12px">${['#F4F3EF', '#2F55F4', '#D97757', '#A19E96'].map(c => `<i style="display:block;width:44px;height:44px;border-radius:50%;background:${c}"></i>`).join('')}</div><div style="position:absolute;left:0;top:0;bottom:0;width:18px;background:linear-gradient(90deg,rgba(255,255,255,.12),transparent)"></div>`);
237
+ B.verso = caixa(B.capa, 0, 0, 440, 600, { background: '#FBFAF7', borderRadius: '22px 6px 6px 22px', backfaceVisibility: 'hidden', transform: 'rotateY(180deg)', boxShadow: 'inset -14px 0 20px -14px rgba(0,0,0,.12)' },
238
+ `<div style="position:absolute;left:44px;top:44px;font:600 30px/1 GS;color:#131313">Paleta</div>` +
239
+ [['#131313', 'Tinta'], ['#F4F3EF', 'Fundo'], ['#2F55F4', 'Vídeo'], ['#D97757', 'IA'], ['#A19E96', 'Passado']].map(([c, n], i) => `<div style="position:absolute;left:${44 + (i % 2) * 180}px;top:${104 + Math.floor(i / 2) * 150}px;font:500 22px/1.3 Inter,sans-serif;color:#6B6A66"><div style="width:110px;height:110px;border-radius:50%;background:${c};box-shadow:inset 0 0 0 1px rgba(0,0,0,.08);margin-bottom:8px"></div>${n}</div>`).join(''));
240
+ // k = abertura 0–1; o livro fechado fica centrado (x −220), aberto centra o par de páginas
241
+ B.abre = k => { B.capa.style.transform = `rotateY(${(-178 * k).toFixed(2)}deg)`; B.pd.style.opacity = '1'; return -220 * (1 - k); };
242
+ return B;
243
+ }
244
+ // iPhone (moldura + tela de bloqueio clara) — a ilha dele estica e vira a notificação (aprovada)
245
+ function iphone(pai, cx, cy) {
246
+ const P = caixa(pai, cx - 215, cy - 440, 430, 880, { borderRadius: '78px', background: '#0E0E10', boxShadow: '0 60px 120px -30px rgba(20,20,50,.45), inset 0 0 0 3px #3A3A3E' });
247
+ const tela = caixa(P, 14, 14, 402, 852, { borderRadius: '66px', overflow: 'hidden', background: 'linear-gradient(170deg,#7FA2FF 0%,#AFC2FF 45%,#F3C9B8 100%)' });
248
+ caixa(tela, 0, 120, 402, 40, { textAlign: 'center', font: '600 24px/1 "SF Pro Display", GS', color: 'rgba(255,255,255,.9)' }, 'sexta-feira, 17 de outubro');
249
+ caixa(tela, 0, 156, 402, 150, { textAlign: 'center', font: '600 132px/1 "SF Pro Display", GS', letterSpacing: '-0.02em', color: '#fff' }, '9:41');
250
+ [0, 1].forEach(i => caixa(tela, 70 + i * 150, 690, 112, 112, { borderRadius: '50%', background: 'rgba(255,255,255,.28)', backdropFilter: 'blur(10px)' }));
251
+ caixa(tela, 131, 832, 140, 6, { borderRadius: '3px', background: 'rgba(255,255,255,.85)' });
252
+ P.ilhaY = cy - 440 + 14 + 18 + 18; // centro da ilha (coordenadas do palco)
253
+ return P;
254
+ }
255
+ const somMarca = (arq, t0, t1, alvo = -17) => VIDEOS.push({ nome: arq.split('/').pop().replace('.wav', ''), arquivo: arq, t0, t1, trilha: 'para', alvo });
256
+
257
+ // ───────── 08 · Apple / meus vídeos / diferente / combina ─────────
258
+ const tAp = PF('08', 'apple'), tOut = PF('08', 'entao') + 0.45;
259
+ legenda('08', ['Aqui, por exemplo,', 'eu uso bastante o', 'a|estilo de design', ['e de', 'UI#2', 'da', 'f|Apple.'], 'Então, você já deve ter', 'percebido que muitos',
260
+ ['dos meus', 'af|vídeos'], 'seguem nesse estilo,', 'que eu particularmente', ['acho bem', 'f|diferente'], ['e que', 'af|combina', 'bastante'], ['com', 'a|vídeo', 'em motion.']]);
261
+ // iPhone: a caixa do prompt sai e o iPhone entra; em "Apple" a ilha estica para fora do aparelho e vira a notificação
262
+ palco(F0('08') - 0.3, PF('08', 'muitos') + 0.15, (el, P) => {
263
+ P.ph = iphone(el, 540, PALCO_Y + 40);
264
+ P.n = caixa(el, 0, 0, 10, 10, { background: '#0A0A0B', overflow: 'hidden', boxShadow: '0 30px 70px -18px rgba(0,0,0,.45)', zIndex: 5 });
265
+ P.cont = caixa(P.n, 0, 0, 940, 200);
266
+ P.itens = [caixa(P.cont, 32, 36, 128, 128, { borderRadius: '30px', background: '#fff', display: 'grid', placeItems: 'center' }, `<img src="${LOGO('apple-logo-black.svg')}" style="width:60px">`),
267
+ caixa(P.cont, 188, 40, 400, 50, { font: '600 40px/1 "SF Pro Display", GS', color: '#fff' }, 'Apple'), caixa(P.cont, 760, 46, 140, 40, { font: '500 30px/1 "SF Pro Display", GS', color: 'rgba(255,255,255,.55)', textAlign: 'right' }, 'agora'),
268
+ caixa(P.cont, 188, 98, 720, 84, { font: '500 34px/1.25 "SF Pro Display", GS', color: 'rgba(255,255,255,.82)' }, 'O design e a UI que eu mais uso')];
269
+ ev(tAp - 0.03, 'notif-iphone', 0, 0.7);
270
+ }, (t, P) => {
271
+ const iy = P.ph.ilhaY, kW = bz(0.2, 1.08, 0.32, 1)(seg(t, tAp - 0.1, tAp + 0.4)), kH = ILL(seg(t, tAp - 0.03, tAp + 0.47)), kR = ILL(seg(t, tOut, tOut + 0.4));
272
+ let w = lerp(126, 940, kW), h = lerp(37, 200, kH), cy = lerp(iy, iy + 150, kH), rr = lerp(18, 58, kH);
273
+ w = lerp(w, 126, kR); h = lerp(h, 37, kR); cy = lerp(cy, iy, kR); rr = lerp(rr, 18, kR);
274
+ Object.assign(P.n.style, { width: w.toFixed(1) + 'px', height: h.toFixed(1) + 'px', left: (540 - w / 2).toFixed(1) + 'px', top: (cy - h / 2).toFixed(1) + 'px', borderRadius: Math.min(rr, h / 2).toFixed(1) + 'px' });
275
+ P.cont.style.left = ((w - 940) / 2).toFixed(1) + 'px'; P.cont.style.top = ((h - 200) / 2).toFixed(1) + 'px';
276
+ P.itens.forEach((e, i) => { const a = seg(t, tAp + 0.12 + i * 0.04, tAp + 0.32 + i * 0.04) * (1 - seg(t, tOut - 0.1, tOut + 0.05)); tf(e, { y: (1 - a) * 14, op: a, blur: (1 - a) * 10 }); });
277
+ tf(P.ph, { y: 8 * Math.sin((t - P.t0) * 0.9), r: 1.2 * Math.sin((t - P.t0) * 0.6) });
278
+ }, { esc: 1.1 });
279
+ // meus vídeos: 2 templates estilo Apple lado a lado → "diferente": eles se afastam e um 3º, colorido, pula da fila com 😍
280
+ palco(PF('08', 'meus') - 0.05, PF('08', 'combina') - 0.1, (el, P) => {
281
+ const f = [['emoji-ui-vertical', 50, 0], ['smartphone-ui-vertical', 560, 1.2], ['ai-opener-vertical', 305, 0]]; // [filme, x, segundo inicial com imagem]
282
+ P.cs = f.map(([n, x, of], i) => { const c = cartao(el, { inset: 'auto', left: x + 'px', top: (PALCO_Y - 417) + 'px', width: '470px', height: '834px', zIndex: i === 2 ? 5 : 1 }); c.f = filme(c, n); c.of = of; return c; });
283
+ P.tD = PF('08', 'diferente') - 0.05; P.e = emo(el, 'u1f60d', 800, PALCO_Y - 400, 210); P.e.style.zIndex = 6; ev(P.tD, 'pop', 0, 0.3);
284
+ }, (t, P) => {
285
+ const kD = ILL(seg(t, P.tD - 0.1, P.tD + 0.45));
286
+ P.cs.forEach((c, i) => { if (i < 2) { abreJanela(t, c, P.t0 + 0.05 + i * 0.25, { lado: 0, ex: lerp(1, 0.78, kD) }); c.style.transform += ` translateX(${((i ? 1 : -1) * 70 * kD).toFixed(1)}px)`; c.f.toca(t, P.t0 + i * 0.25 - c.of, false); }
287
+ else { const n = nasce(t, P.tD, 0.5); tf(c, { op: n.op, s: n.s * 1.02, y: n.y - 20, blur: n.blur }); c.f.toca(t, P.tD, false); } });
288
+ const n = nasce(t, P.tD + 0.18, 0.45); tf(P.e, { op: n.op, s: n.s, y: n.y, blur: n.blur, r: 8 * Math.sin((t - P.tD) * 3) }); P.e.lot.toca(t, P.tD);
289
+ });
290
+ // combina: a UI da Apple (vidro) e um card de motion (curva + keyframes) se aproximam e se fundem (gooey) num card só
291
+ palco(PF('08', 'combina') - 0.12, F1('08') + 0.25, (el, P) => {
292
+ P.tc = PF('08', 'combina');
293
+ P.goo = caixa(el, 0, 0, 1080, 1300, { filter: GOO + ' drop-shadow(0 34px 50px rgba(30,30,60,.22))' });
294
+ P.a = caixa(P.goo, 0, 0, 340, 340, { background: '#fff', borderRadius: '70px' }); P.b = caixa(P.goo, 0, 0, 340, 340, { background: '#fff', borderRadius: '70px' });
295
+ P.ca = caixa(el, 0, 0, 340, 340, {}, `<div style="position:absolute;left:44px;top:40px;font:600 110px/1 'SF Pro Display',GS;color:#131313">Aa</div><div style="position:absolute;left:44px;top:190px;width:120px;height:66px;border-radius:33px;background:#34C759"><i style="position:absolute;right:5px;top:5px;width:56px;height:56px;border-radius:50%;background:#fff;box-shadow:0 2px 6px rgba(0,0,0,.2)"></i></div><img src="${LOGO('apple-logo-black.svg')}" style="position:absolute;right:44px;top:200px;width:46px">`);
296
+ P.cb = caixa(el, 0, 0, 340, 340, {}, `<svg viewBox="0 0 340 340" width="340" height="340"><path d="M50 260 C 140 260, 150 80, 290 80" fill="none" stroke="#2F55F4" stroke-width="8" stroke-linecap="round"/><path d="M50 260 L120 260 M290 80 L220 80" stroke="#A19E96" stroke-width="3"/><g fill="#D97757"><rect x="38" y="248" width="24" height="24" transform="rotate(45 50 260)"/><rect x="278" y="68" width="24" height="24" transform="rotate(45 290 80)"/></g></svg>`);
297
+ P.cm = caixa(el, 540 - 260, PALCO_Y - 260, 520, 520, {}, `<svg viewBox="0 0 520 520" width="520" height="520"><path id="cvB" d="M80 400 C 220 400, 240 130, 440 130" fill="none" stroke="#2F55F4" stroke-width="10" stroke-linecap="round"/></svg>` +
298
+ `<div style="position:absolute;left:56px;top:48px;font:600 64px/1 GS;letter-spacing:-.04em;color:#131313">motion</div><div style="position:absolute;right:56px;bottom:52px;width:96px;height:96px;border-radius:50%;background:#131313;display:grid;place-items:center"><svg width="40" height="40" viewBox="0 0 24 24"><path d="M8 5v14l11-7z" fill="#fff"/></svg></div>`);
299
+ P.dot = caixa(P.cm, 0, 0, 34, 34, { borderRadius: '50%', background: '#D97757', boxShadow: '0 0 0 8px rgba(217,119,87,.18)' }); P.path = P.cm.querySelector('#cvB');
300
+ ev(P.tc + 0.55, 'pouso', 0, 0.3);
301
+ }, (t, P) => {
302
+ const kJ = IO(seg(t, P.tc + 0.05, P.tc + 0.7)), kM = ILL(seg(t, P.tc + 0.55, P.tc + 1.05));
303
+ const xa = lerp(290, 540 - 170 + 60, kJ), xb = lerp(790, 540 + 170 - 60, kJ), sz = lerp(340, 520, kM);
304
+ [[P.a, xa], [P.b, xb]].forEach(([e, x]) => Object.assign(e.style, { left: (x - sz / 2).toFixed(1) + 'px', top: (PALCO_Y - sz / 2).toFixed(1) + 'px', width: sz.toFixed(1) + 'px', height: sz.toFixed(1) + 'px', borderRadius: lerp(70, 90, kM).toFixed(1) + 'px' }));
305
+ const opP = 1 - seg(t, P.tc + 0.35, P.tc + 0.65);
306
+ tf(P.ca, { x: xa - 170, y: PALCO_Y - 170, op: opP, blur: (1 - opP) * 10 }); tf(P.cb, { x: xb - 170, y: PALCO_Y - 170, op: opP, blur: (1 - opP) * 10 });
307
+ const n = nasce(t, P.tc + 0.7, 0.45); tf(P.cm, { op: n.op, s: lerp(0.9, 1, n.k), blur: n.blur });
308
+ const L = P.path.getTotalLength(), q = P.path.getPointAtLength(((t - P.tc) * 0.55 % 1) * L); Object.assign(P.dot.style, { left: (q.x - 17).toFixed(1) + 'px', top: (q.y - 17).toFixed(1) + 'px' });
309
+ }, { esc: 1.32 });
310
+
311
+ // ───────── 09 · gosto ❤️ / processo (caminho a caneta) / pilar / único ─────────
312
+ legenda('09', [['Bom, cada', 'f|gosto', 'é único,'], ['mas o', 'af|processo', 'é o mesmo:'], ['a|referência', 'é um dos'], ['af|pilares', 'principais'], ['para a sua', 'o|IA', 'fazer'], ['algo realmente', 'of|único.']]);
313
+ palco(F0('09') - 0.1, F0('10') - 0.2, (el, P) => {
314
+ const tG = PF('09', 'gosto'), tP = PF('09', 'processo'), tM = PF('09', 'mesmo'), tPi = PF('09', 'pilares'), tIA = PF('09', 'ia'), tU = PF('09', 'unico', 1);
315
+ Object.assign(P, { tG, tP, tM, tPi, tIA, tU });
316
+ const srcs = ['img/filmes/smartphone-ui-vertical/0050.jpg', 'img/filmes/ai-opener-vertical/0060.jpg', 'img/filmes/illdari-telegram/0040.jpg'];
317
+ P.xs = [232, 540, 848];
318
+ P.cs = srcs.map((s, i) => { const c = cartao(el, { inset: 'auto', left: (P.xs[i] - 140) + 'px', top: '250px', width: '280px', height: '390px' }); img(c, s, { inset: '0', width: '100%', height: '100%' }); return c; });
319
+ P.cor = P.xs.map((x, i) => caixa(el, x + 52, 212, 96, 96, {}, CORACAO));
320
+ P.cor.forEach((_, i) => ev(tG + 0.08 + i * 0.13, 'toque', [-0.4, 0, 0.4][i], 0.3));
321
+ P.svg = caixa(el, 0, 0, 1080, 1300, {}, `<svg width="1080" height="1300" viewBox="0 0 1080 1300">${P.xs.map((x, i) => `<path class="cam" d="M${x} 645 C ${x} 760, 540 740, 540 830" fill="none" stroke="#131313" stroke-width="7" stroke-linecap="round"/>`).join('')}<path class="cam" d="M540 830 L540 915" fill="none" stroke="#131313" stroke-width="7" stroke-linecap="round"/></svg>`);
322
+ P.cam = [...P.svg.querySelectorAll('.cam')]; P.cam.forEach(p => { const L = p.getTotalLength(); p.style.strokeDasharray = L; p.L = L; });
323
+ ev(tP, 'desenha', 0, 0.4);
324
+ P.pasta = caixa(el, 540 - 120, 915, 240, 260, { transformOrigin: '50% 100%' }, PASTA + '<div style="text-align:center;font:600 30px/1 GS;letter-spacing:-.02em;color:#131313;margin-top:14px">referências</div>');
325
+ P.pil = pilar(el, 540, 1200, 'referência'); ev(tPi, 'pouso', 0, 0.45);
326
+ P.cl = caixa(el, 540 - 70, 410, 140, 140, {}, `<img src="${LOGO('claude-symbol.svg')}" style="width:140px;height:140px">`); P.br = emo(el, 'u2728', 540, 460, 300); ev(tU - 0.25, 'brilho', 0, 0.35);
327
+ }, (t, P) => {
328
+ const kSai = ILL(seg(t, P.tPi - 0.35, P.tPi + 0.1)); // cards, corações e caminhos saem quando a pasta vira pilar
329
+ P.cs.forEach((c, i) => { const n = nasce(t, P.t0 + 0.05 + i * 0.12, 0.45); tf(c, { op: n.op * (1 - kSai), s: lerp(0.85, 1, n.k) * (1 - 0.1 * kSai), y: n.y - 60 * kSai, r: [-6, 0, 6][i], blur: n.blur + kSai * 16 }); });
330
+ P.cor.forEach((h, i) => { const n = nasce(t, P.tG + 0.08 + i * 0.13, 0.4); tf(h, { op: n.op * (1 - kSai), s: n.s * (1 + 0.08 * Math.sin((t - P.tG) * 7 + i)), y: n.y, blur: n.blur + kSai * 14 }); });
331
+ P.cam.forEach((p, i) => { const k = i < 3 ? IO(seg(t, P.tP + i * 0.08, P.tP + 0.55 + i * 0.08)) : IO(seg(t, P.tP + 0.55, P.tM + 0.2)); p.style.strokeDashoffset = (p.L * (1 - k)).toFixed(1); p.style.opacity = (1 - kSai).toFixed(3); });
332
+ const nP = nasce(t, P.tM - 0.05, 0.45), kPi = ILL(seg(t, P.tPi - 0.1, P.tPi + 0.55));
333
+ tf(P.pasta, { op: nP.op * (1 - kPi), s: nP.s * lerp(1, 0.7, kPi), y: nP.y - 40 * kPi, blur: nP.blur + kPi * 12 });
334
+ P.pil.style.clipPath = `inset(${((1 - kPi) * 100).toFixed(2)}% 0 0 0)`; tf(P.pil, { op: clamp(kPi * 3), y: (1 - kPi) * 30 });
335
+ const kC = ILL(seg(t, P.tIA - 0.1, P.tIA + 0.5)); tf(P.cl, { op: kC, y: (1 - kC) * 260 + 4 * Math.sin(t * 2), r: lerp(-120, 0, kC) + (t - P.tIA) * 25, s: lerp(0.4, 1, kC) });
336
+ const nb = nasce(t, P.tU - 0.25, 0.4); tf(P.br, { op: nb.op, s: nb.s, blur: nb.blur }); P.br.lot.toca(t, P.tU - 0.25);
337
+ }, { esc: 1.08 });
338
+
339
+ // ───────── 10–11 · Passo 2 / identidade visual (brand book) / pilares / irreplicável (Face ID) ─────────
340
+ const tH2 = PF('10', 'identidade') - 0.12;
341
+ passoHeroi(2, 'u1f3a8', F0('10') - 0.08, tH2, { ate: F0('14') - 0.3 });
342
+ legenda('10', [pula(2), ['identidade', 'af|visual.']]);
343
+ legenda('11', [['Sim, a identidade', 'visual do seu vídeo'], ['é um dos', 'af|pilares'], 'que fazem dele ser', ['algo', 'af|irreplicável.']]);
344
+ palco(tH2 + 0.02, F1('11') + 0.3, (el, P) => {
345
+ P.tV = PF('10', 'visual'); P.tPi = PF('11', 'pilares'); P.tI = PF('11', 'irreplicavel');
346
+ P.bk = brandBook(el, 540, PALCO_Y); ev(P.tV, 'pagina', 0, 0.35);
347
+ P.p1 = pilar(el, 330, 1250, 'referência', 0.62); P.p2 = pilar(el, 750, 1250, 'identidade', 0.62); ev(P.tPi + 0.1, 'pouso', 0, 0.4);
348
+ P.fid = caixa(el, 540 - 330, PALCO_Y - 330, 660, 660, {}, `<svg viewBox="0 0 660 660" width="660" height="660" fill="none" stroke-width="16" stroke-linecap="round" stroke-linejoin="round">` +
349
+ `<g class="cn"><path d="M20 170 V70 Q20 20 70 20 H170"/><path d="M490 20 H590 Q640 20 640 70 V170"/><path d="M640 490 V590 Q640 640 590 640 H490"/><path d="M170 640 H70 Q20 640 20 590 V490"/></g>` +
350
+ `<g class="fc"><path d="M230 250 V300"/><path d="M430 250 V300"/><path d="M330 250 V370 Q330 390 305 390"/><path d="M240 460 Q330 530 420 460"/></g></svg>`);
351
+ P.cn = P.fid.querySelector('.cn'); P.fc = [...P.fid.querySelectorAll('.fc path')]; P.fc.forEach(p => { p.L = p.getTotalLength(); p.style.strokeDasharray = p.L; });
352
+ P.ok = emo(el, 'u2705', 540 + 250, PALCO_Y + 250, 170); P.so = caixa(el, 0, PALCO_Y + 370, 1080, 70, { textAlign: 'center', font: '600 52px/1 GS', letterSpacing: '-0.03em', color: '#1E9E4A' }, 'só seu');
353
+ ev(P.tI - 0.1, 'trava', 0, 0.3); ev(P.tI + 0.45, 'sucesso', 0, 0.35);
354
+ }, (t, P) => {
355
+ // livro: nasce fechado em "identidade", abre em "visual"; nos "pilares" encolhe e senta no 2º pilar; no "irreplicável" volta ao centro
356
+ const kA = IO(seg(t, P.tV - 0.05, P.tV + 0.65)), kPi = ILL(seg(t, P.tPi - 0.1, P.tPi + 0.5)), kI = ILL(seg(t, P.tI - 0.55, P.tI - 0.05));
357
+ const dx = P.bk.abre(clamp(kA - kI));
358
+ const n = nasce(t, P.t0 + 0.02, 0.5);
359
+ let s = lerp(0.8, 1, n.k), x = dx * (kA > 0 ? 1 : s), y = n.y;
360
+ x = lerp(x, 750 - 540 - 220 * 0.32, kPi); y = lerp(y, -8, kPi); s = lerp(s, 0.32, kPi);
361
+ x = lerp(x, -220 * 0.78, kI); y = lerp(y, 0, kI); s = lerp(s, 0.78, kI);
362
+ tf(P.bk, { x, y, s, op: n.op, blur: n.blur });
363
+ const kPs = kPi * (1 - kI);
364
+ [P.p1, P.p2].forEach((p, i) => { const k = ILL(seg(t, P.tPi - 0.15 + i * 0.25, P.tPi + 0.4 + i * 0.25)) * (1 - kI); p.style.clipPath = `inset(${((1 - k) * 100).toFixed(2)}% 0 0 0)`; p.style.transform = `scale(0.62)`; p.style.opacity = clamp(k * 3).toFixed(3); });
365
+ // Face ID: os cantos fecham sobre o livro, o rosto se desenha, fica verde, ✅ "só seu"
366
+ const kc = IO(seg(t, P.tI - 0.25, P.tI + 0.25)), kf = seg(t, P.tI, P.tI + 0.4), kv = seg(t, P.tI + 0.38, P.tI + 0.55);
367
+ const cor = kv > 0.5 ? '#34C759' : '#2F55F4'; P.fid.querySelector('svg').style.stroke = cor;
368
+ tf(P.fid, { op: clamp(seg(t, P.tI - 0.3, P.tI - 0.1) * 3), s: lerp(1.35, 1, kc) * (1 + 0.04 * Math.sin(Math.PI * kv)) });
369
+ P.fc.forEach((p, i) => { p.style.strokeDashoffset = (p.L * (1 - IO(seg(kf, i * 0.12, 0.6 + i * 0.12)))).toFixed(1); });
370
+ const no = nasce(t, P.tI + 0.45, 0.4); tf(P.ok, { op: no.op, s: no.s, y: no.y, blur: no.blur }); P.ok.lot.toca(t, P.tI + 0.45);
371
+ const ns = palavraVida(t, P.tI + 0.55, true); tf(P.so, { op: ns.op, y: ns.y, s: ns.s, blur: ns.blur });
372
+ }, { esc: 1.15 });
373
+
374
+ // ───────── 12 · você 🫵 / assistindo 👀 / marca (Netflix → Disney → McDonald's, com som) / negócio / vídeo / casa ─────────
375
+ legenda('12', [['Provavelmente', 'af|você,'], ['que tá aí me', 'af|assistindo,'], ['sabe que', 'af|marca', 'bem feita'], 'e bem posicionada', 'é importante para', ['qualquer', 'af|negócio.'],
376
+ 'Esse mesmo conceito', 'também é importante', 'para construir um', ['a|vídeo', 'bem feito,'], ['e', 'af|casa', 'muito com'], 'as referências que você manda.']);
377
+ const tVo = PF('12', 'voce'), tAs = PF('12', 'assistindo'), tMa = PF('12', 'marca'), tNe = PF('12', 'negocio'), tVi = PF('12', 'video'), tCa = PF('12', 'casa');
378
+ palco(F0('12') - 0.1, tAs - 0.05, (el, P) => { P.e = emo(el, 'u1faf5', 540, PALCO_Y, 520); ev(tVo, 'toque', 0, 0.35); },
379
+ (t, P) => { const c = Math.max(0, Math.sin((t - tVo) * 7)) * Math.exp(-Math.max(0, t - tVo) * 1.2) * (t > tVo ? 1 : 0); tf(P.e, { s: 1 + 0.12 * c, y: -10 * c }); P.e.lot.toca(t, P.t0); }, { esc: 1.3 });
380
+ palco(tAs - 0.05, tMa - 0.12, (el, P) => { P.e = emo(el, 'u1f440', 540, PALCO_Y, 460); }, (t, P) => { tf(P.e, { x: 10 * Math.sin((t - P.t0) * 2.4) }); P.e.lot.toca(t, P.t0); }, { esc: 1.45 });
381
+ // as assinaturas: Netflix (tudum) → Disney (arco, vídeo real) → McDonald's (jingle); a trilha para
382
+ const tD1 = tMa + 0.95, tD2 = tD1 + 1.15, tD3 = tD2 + 1.05;
383
+ somMarca('audio/sfx/marcas/netflix-tudum.wav', tMa - 0.05, tD1 + 0.15, -16);
384
+ VIDEOS.push({ nome: 'disney-arco', t0: tD1, t1: tD2 + 0.12, trilha: 'para', alvo: -17 });
385
+ somMarca('audio/sfx/marcas/mcdonalds-jingle.wav', tD2, tD3 + 0.2, -16);
386
+ palco(tMa - 0.12, tD3, (el, P) => {
387
+ P.nf = caixa(el, 540 - 260, PALCO_Y - 260, 520, 520, { borderRadius: '72px', background: '#000', boxShadow: '0 50px 100px -30px rgba(0,0,0,.5)' }, `<img src="${LOGO('netflix-n.svg')}" style="position:absolute;left:170px;top:90px;height:340px">`);
388
+ P.ds = cartao(el, { inset: 'auto', left: '84px', top: (PALCO_Y - 256) + 'px', width: '912px', height: '513px', background: '#0B1A3A' }); P.fd = filme(P.ds, 'disney-arco');
389
+ P.mc = caixa(el, 540 - 260, PALCO_Y - 260, 520, 520, { borderRadius: '72px', background: '#DA291C', boxShadow: '0 50px 100px -30px rgba(160,20,10,.5)' }, `<img src="${LOGO('mcdonalds-arcos.svg')}" style="position:absolute;left:90px;top:120px;width:340px">`);
390
+ }, (t, P) => {
391
+ const troca = (e, a, b, extra = {}) => { const n = nasce(t, a, 0.4), s = sai(t, b, 0.25, { dy: -30, blur1: 22 }); tf(e, Object.assign({ op: n.op * s.op, s: lerp(0.8, 1, n.k) * (1 + 0.06 * s.u), y: n.y * 0.5 + s.y, blur: n.blur + s.blur }, extra)); };
392
+ const pulso = Math.exp(-Math.pow((t - (P.t0 + 0.55)) / 0.08, 2)) * 0.1;
393
+ troca(P.nf, P.t0 + 0.05, tD1 + 0.05); P.nf.style.transform += ` scale(${(1 + pulso).toFixed(3)})`;
394
+ abreJanela(t, P.ds, tD1 - 0.05, { lado: 4 }); if (t > tD2) { const s = sai(t, tD2 + 0.12, 0.25); tf(P.ds, { op: s.op, blur: s.blur, y: s.y }); } P.fd.toca(t, tD1, false);
395
+ troca(P.mc, tD2 - 0.02, tD3 + 0.05, {}); const sal = Math.max(0, Math.sin((t - tD2) * 9)) * Math.exp(-Math.max(0, t - tD2) * 2) * (t > tD2 ? 1 : 0); P.mc.style.transform += ` translateY(${(-18 * sal).toFixed(1)}px)`;
396
+ }, { sai: false, esc: 1.12 });
397
+ // negócio: as 3 marcas pequenas na vitrine de uma fachada de loja
398
+ palco(tD3 - 0.05, tVi - 0.25, (el, P) => {
399
+ P.f = caixa(el, 540 - 380, PALCO_Y - 330, 760, 660, {}, `<svg viewBox="0 0 760 660" width="760" height="660" style="filter:drop-shadow(0 40px 60px rgba(30,30,60,.18))"><rect x="40" y="120" width="680" height="520" rx="26" fill="#FFFFFF"/>` +
400
+ `<path d="M20 120 H740 L720 40 H40 Z" fill="#2F55F4"/>${[...Array(8)].map((_, i) => `<path d="M${20 + i * 90} 120 a45 40 0 0 0 90 0" fill="${i % 2 ? '#2F55F4' : '#FFFFFF'}" stroke="#2F55F4" stroke-width="4"/>`).join('')}` +
401
+ `<rect x="80" y="230" width="380" height="330" rx="16" fill="#EEF1FE"/><rect x="510" y="250" width="170" height="390" rx="12" fill="#F4F3EF" stroke="#D9D6CF" stroke-width="4"/><circle cx="530" cy="450" r="8" fill="#A19E96"/></svg>`);
402
+ P.lg = [['netflix-n.svg', 60], ['disney-logo.svg', 130], ['mcdonalds-arcos.svg', 90]].map(([a, w], i) => { const b = caixa(P.f, 100 + i * 120, 330, 120, 140, { display: 'grid', placeItems: 'center' }, `<img src="${LOGO(a)}" style="width:${w}px;max-height:110px;object-fit:contain">`); return b; });
403
+ P.lg.forEach((_, i) => ev(tNe + 0.05 + i * 0.12, 'pop', -0.3 + i * 0.3, 0.2));
404
+ }, (t, P) => { P.lg.forEach((b, i) => { const n = nasce(t, tNe + i * 0.12, 0.4); tf(b, { op: n.op, s: n.s, y: n.y, blur: n.blur }); }); }, { esc: 1.25 });
405
+ // vídeo: a fachada vira um player com o brand book "vestido" nele → casa: o player e a pasta de referências se encaixam ❤️
406
+ palco(tVi - 0.25, F1('12') + 0.25, (el, P) => {
407
+ P.pl = cartao(el, { inset: 'auto', left: '84px', top: (PALCO_Y - 256) + 'px', width: '912px', height: '513px', background: '#FBFAF7' });
408
+ P.pl.innerHTML = `<div style="position:absolute;left:56px;top:46px;font:600 150px/1 GS;letter-spacing:-.05em;color:#131313">Aa</div>` + ['#131313', '#2F55F4', '#D97757', '#A19E96'].map((c, i) => `<i style="position:absolute;left:${420 + i * 110}px;top:70px;width:90px;height:90px;border-radius:50%;background:${c}"></i>`).join('') +
409
+ `<div style="position:absolute;left:56px;right:56px;bottom:46px;height:10px;border-radius:5px;background:rgba(0,0,0,.08)"><b class="pr" style="position:absolute;left:0;top:0;bottom:0;border-radius:5px;background:#2F55F4"></b></div><div style="position:absolute;left:56px;bottom:84px;width:84px;height:84px;border-radius:50%;background:#131313;display:grid;place-items:center"><svg width="34" height="34" viewBox="0 0 24 24"><path d="M8 5v14l11-7z" fill="#fff"/></svg></div>`;
410
+ P.pr = P.pl.querySelector('.pr');
411
+ P.ps = caixa(el, 0, 0, 240, 250, {}, PASTA + '<div style="text-align:center;font:600 30px/1 GS;color:#131313;margin-top:12px">referências</div>');
412
+ P.co = caixa(el, 540 - 70, PALCO_Y - 250, 140, 140, {}, CORACAO); ev(tCa + 0.25, 'pouso', 0, 0.35); ev(tCa + 0.3, 'pop', 0, 0.25);
413
+ }, (t, P) => {
414
+ abreJanela(t, P.pl, P.t0 + 0.05, { lado: 4 }); P.pr.style.width = (100 * clamp((t - P.t0) / 4)).toFixed(1) + '%';
415
+ const kC = IO(seg(t, tCa - 0.15, tCa + 0.35));
416
+ P.pl.style.transform += ` translateX(${(-180 * kC).toFixed(1)}px) scale(${lerp(1, 0.5, kC).toFixed(3)})`;
417
+ const np = nasce(t, tCa - 0.15, 0.35); tf(P.ps, { op: np.op, x: lerp(1000, 600, kC), y: PALCO_Y - 125, s: np.s, blur: np.blur });
418
+ const nc = nasce(t, tCa + 0.3, 0.4); tf(P.co, { op: nc.op, s: nc.s * (1 + 0.08 * Math.sin((t - tCa) * 8)), y: nc.y, blur: nc.blur });
419
+ }, { esc: 1.1 });
420
+
421
+ // ───────── 13 · mente 🧠 / buscar (Pinterest) / agente construir (tijolos) / branding (carimbo) ─────────
422
+ legenda('13', ['Então, é importante', 'que você já tenha', 'uma identidade visual', ['do seu vídeo em', 'af|mente,'], 'para que as referências', ['que você', 'af|buscar'],
423
+ 'sejam relevantes', ['para o seu', 'of|agente', 'construir'], ['com base no', 'af|branding'], 'que você escolheu.'], { ate: F0('14') - 0.3 });
424
+ const tMe = PF('13', 'mente'), tBu = PF('13', 'buscar'), tAg = PF('13', 'agente'), tBr = PF('13', 'branding');
425
+ palco(F0('13') - 0.15, tBu - 0.12, (el, P) => {
426
+ P.bk = brandBook(el, 540, PALCO_Y); P.cb = emo(el, 'u1f9e0', 420, PALCO_Y + 120, 420);
427
+ P.bol = [0, 1, 2].map(i => caixa(el, 620 + i * 46, PALCO_Y - 80 - i * 50, 26 + i * 12, 26 + i * 12, { borderRadius: '50%', background: '#fff', boxShadow: '0 8px 20px rgba(0,0,0,.10)' }));
428
+ P.bal = caixa(el, 700, PALCO_Y - 420, 300, 260, { borderRadius: '130px', background: '#fff', boxShadow: '0 20px 50px -10px rgba(30,30,60,.18)' }); ev(tMe, 'pop', 0, 0.3); P.bk.style.zIndex = 5;
429
+ }, (t, P) => {
430
+ const kM = ILL(seg(t, tMe - 0.15, tMe + 0.4)), n = nasce(t, P.t0 + 0.05, 0.5);
431
+ P.bk.abre(0); const s0 = lerp(0.8, 0.86, n.k); tf(P.bk, { x: lerp(-220 * s0, 255, kM), y: lerp(n.y, -290, kM), s: lerp(s0, 0.25, kM), op: n.op, blur: n.blur, r: lerp(-6 + 4 * Math.sin((t - P.t0) * 1.3), 0, kM) });
432
+ const nb = nasce(t, tMe, 0.45); tf(P.cb, { op: nb.op, s: nb.s, y: nb.y, blur: nb.blur }); P.cb.lot.toca(t, tMe);
433
+ P.bol.forEach((b, i) => { const k = nasce(t, tMe + 0.12 + i * 0.08, 0.3); tf(b, { op: k.op, s: k.s }); }); const kb = nasce(t, tMe + 0.3, 0.4); tf(P.bal, { op: kb.op, s: kb.s, blur: kb.blur });
434
+ }, { esc: 1.2 });
435
+ palco(tBu - 0.12, tAg - 0.15, buscaPinterest({ t: tBu - 0.1 }), { y: PALCO_Y + 40 });
436
+ // agente constrói: o Claude puxa 3 pins e monta um card tijolo a tijolo nas cores do brand book; branding = o livro carimba
437
+ palco(tAg - 0.15, F1('13') + 0.35, (el, P) => {
438
+ P.cl = caixa(el, 175, 330, 130, 130, {}, `<img src="${LOGO('claude-symbol.svg')}" style="width:130px;height:130px">`);
439
+ P.pins = ['../comp-v31/img/ref-pinterest-apple-ui.jpg', 'img/filmes/emoji-ui-vertical/0060.jpg', '../comp-v31/img/ref-apple-glass-player.jpg'].map((s, i) => { const d = caixa(el, 760 - i * 40, 260 + i * 30, 150, 190, { borderRadius: '18px', overflow: 'hidden', boxShadow: '0 16px 30px -10px rgba(0,0,0,.3)' }); img(d, s, { inset: '0', width: '100%', height: '100%' }); return d; });
440
+ const cols = 8, lin = 5, bw = 84, bh = 76, x0 = 540 - cols * bw / 2, y0 = PALCO_Y - lin * bh / 2 + 40;
441
+ const cor = (c, l) => (l === 0 ? '#2F55F4' : (l === lin - 1 && c > 4) ? '#D97757' : (c === 0 || l === 1 && c < 4) ? '#131313' : '#FFFFFF');
442
+ P.tij = []; for (let l = lin - 1; l >= 0; l--) for (let c = 0; c < cols; c++) P.tij.push(caixa(el, x0 + c * bw + 2, y0 + l * bh + 2, bw - 4, bh - 4, { borderRadius: '10px', background: cor(c, l), boxShadow: '0 6px 14px -6px rgba(0,0,0,.25), inset 0 0 0 1px rgba(0,0,0,.05)' }));
443
+ P.tij.forEach((_, i) => { if (i % 8 === 0) ev(tAg + 0.35 + i * 0.022, 'pouso', 0, 0.12); });
444
+ P.st = caixa(el, 540 + 120, PALCO_Y - 40, 300, 300, { transformOrigin: '50% 50%' }, `<svg viewBox="0 0 300 300" width="300" height="300"><circle cx="150" cy="150" r="128" fill="none" stroke="#2F55F4" stroke-width="12"/><circle cx="150" cy="150" r="104" fill="none" stroke="#2F55F4" stroke-width="4" stroke-dasharray="8 10"/><path d="M95 152 L135 192 L210 112" fill="none" stroke="#2F55F4" stroke-width="22" stroke-linecap="round" stroke-linejoin="round"/></svg>`);
445
+ P.bk = brandBook(el, 540, PALCO_Y); ev(tBr + 0.18, 'carimbo', 0, 0.6);
446
+ }, (t, P) => {
447
+ const nC = nasce(t, P.t0 + 0.05, 0.45); tf(P.cl, { op: nC.op, s: nC.s, r: (t - P.t0) * 60, blur: nC.blur });
448
+ P.pins.forEach((d, i) => { const n = nasce(t, P.t0 + 0.05 + i * 0.08, 0.35), k = IO(seg(t, tAg + 0.05 + i * 0.1, tAg + 0.45 + i * 0.1)); tf(d, { op: n.op * (1 - k), x: lerp(0, 240 - (760 - i * 40), k), y: lerp(0, 395 - (260 + i * 30), k), s: lerp(1, 0.2, k), r: [8, -5, 4][i] * (1 - k), blur: n.blur + k * 6 }); });
449
+ P.tij.forEach((b, i) => { const u = seg(t, tAg + 0.35 + i * 0.022, tAg + 0.55 + i * 0.022); tf(b, { op: clamp(u * 3), y: (1 - ILL(u)) * -60, s: lerp(0.6, 1, ILL(u)) }); });
450
+ // carimbo: o brand book (fechado, pequeno) desce com peso e deixa a marca ✓ no card
451
+ const kd = seg(t, tBr - 0.15, tBr + 0.18), kb = ILL(seg(t, tBr + 0.18, tBr + 0.6));
452
+ P.bk.abre(0); tf(P.bk, { x: lerp(240, 193, kd), y: lerp(-560, 100, ILLIN(kd)) - 140 * kb, s: 0.35, r: lerp(-20, -12, kd), op: clamp(seg(t, tBr - 0.3, tBr - 0.1) * 3) * (1 - seg(t, tBr + 0.5, tBr + 0.8)) });
453
+ const ks = seg(t, tBr + 0.18, tBr + 0.3); tf(P.st, { op: ks > 0 ? 0.9 : 0, s: lerp(1.25, 1, ILL(ks)), r: -12 });
454
+ }, { esc: 1.25 });
455
+ })();