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,150 @@
1
+ /**
2
+ * cota.js — o plano decide o vídeo: cota do mês, resolução e marca d'água.
3
+ *
4
+ * "o plano ter render de vídeo" (Joel, 18/10/2026)
5
+ *
6
+ * A regra mora no servidor (server/lib/planos.js, POST /api/video/cota); aqui
7
+ * só se pergunta antes do render do estudio_motion/estudio_ae, se aplica o que
8
+ * o plano libera no mp4 pronto (teto de resolução, marca d'água) e se conta o
9
+ * vídeo depois que ele saiu. Sem rede ou servidor mudo: MODO LOCAL generoso —
10
+ * 4K, sem marca, sem teto. Errar para o lado de quem trabalha, como o gate.
11
+ */
12
+
13
+ 'use strict';
14
+
15
+ const fs = require('fs');
16
+ const os = require('os');
17
+ const path = require('path');
18
+ const zlib = require('zlib');
19
+ const { spawnSync } = require('child_process');
20
+
21
+ const LOCAL = { ok: true, offline: true, liberado: true, plano: 'local', restam: null, usados: 0,
22
+ recursos: { videosMes: 0, resolucao: 2160, marcaDagua: false } };
23
+
24
+ /** Pergunta (acao "checar") ou conta (acao "gastar") no servidor. */
25
+ async function consultar(acao = 'checar', { buscar = fetch, servidor, token, prazo = 6000 } = {}) {
26
+ try {
27
+ if (servidor === undefined) servidor = require('../config').loadConfig().server;
28
+ if (token === undefined) token = await require('../conta').tokenValido().catch(() => null);
29
+ const h = { 'Content-Type': 'application/json' };
30
+ if (token) h['x-primocode-token'] = token;
31
+ const r = await buscar(new URL('/api/video/cota', servidor).href, {
32
+ method: 'POST', headers: h, body: JSON.stringify({ acao }), signal: AbortSignal.timeout(prazo),
33
+ });
34
+ const j = await r.json();
35
+ if (!r.ok || !j || !j.recursos) return LOCAL;
36
+ return j;
37
+ } catch { return LOCAL; }
38
+ }
39
+
40
+ /** A mensagem do limite, com o degrau seguinte e o caminho para assinar. */
41
+ function mensagemLimite(c) {
42
+ const u = c.upgrade;
43
+ const reais = (n) => `R$ ${Number(n).toFixed(2).replace('.', ',')}`;
44
+ return `Seus ${c.recursos.videosMes} vídeos do mês acabaram (plano ${c.plano}).`
45
+ + (u ? ` O ${u.nome} (${reais(u.preco)}/mês) libera ${u.videosMes} por mês. Veja com: primocode planos`
46
+ : ' A cota volta no primeiro dia do próximo mês.');
47
+ }
48
+
49
+ /* ── a marca d'água: um PNG pequeno desenhado aqui, sem depender de fonte no ffmpeg ── */
50
+ const LETRAS = {
51
+ P: ['1111', '1 1', '1111', '1 ', '1 '], R: ['1111', '1 1', '1111', '1 1 ', '1 1'],
52
+ I: ['111', ' 1 ', ' 1 ', ' 1 ', '111'], M: ['1 1', '11 11', '1 1 1', '1 1', '1 1'],
53
+ O: ['1111', '1 1', '1 1', '1 1', '1111'], C: ['1111', '1 ', '1 ', '1 ', '1111'],
54
+ D: ['111 ', '1 1', '1 1', '1 1', '111 '], E: ['1111', '1 ', '111 ', '1 ', '1111'],
55
+ };
56
+
57
+ function crc32(buf) {
58
+ let c, crc = ~0;
59
+ for (const b of buf) { c = (crc ^ b) & 0xff; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; crc = (crc >>> 8) ^ c; }
60
+ return ~crc >>> 0;
61
+ }
62
+ function pedaco(tipo, dados) {
63
+ const t = Buffer.from(tipo), len = Buffer.alloc(4), crc = Buffer.alloc(4);
64
+ len.writeUInt32BE(dados.length); crc.writeUInt32BE(crc32(Buffer.concat([t, dados])));
65
+ return Buffer.concat([len, t, dados, crc]);
66
+ }
67
+
68
+ /** PNG RGBA do texto "PRIMOCODE" (letras brancas sobre fundo preto translúcido), `px` pixels por ponto da fonte. */
69
+ function pngMarca(px = 3, texto = 'PRIMOCODE') {
70
+ const cols = [], pad = 3;
71
+ for (const ch of texto) { const g = LETRAS[ch]; for (let x = 0; x < g[0].length; x++) cols.push(g.map((l) => l[x] === '1')); cols.push(null); }
72
+ cols.pop();
73
+ const L = (cols.length + pad * 2) * px, A = (5 + pad * 2) * px;
74
+ const raw = Buffer.alloc((L * 4 + 1) * A);
75
+ for (let y = 0; y < A; y++) {
76
+ raw[y * (L * 4 + 1)] = 0;
77
+ for (let x = 0; x < L; x++) {
78
+ const cx = Math.floor(x / px) - pad, cy = Math.floor(y / px) - pad;
79
+ const aceso = cx >= 0 && cy >= 0 && cy < 5 && cols[cx] && cols[cx][cy];
80
+ const o = y * (L * 4 + 1) + 1 + x * 4;
81
+ const v = aceso ? [255, 255, 255, 235] : [0, 0, 0, 110];
82
+ raw[o] = v[0]; raw[o + 1] = v[1]; raw[o + 2] = v[2]; raw[o + 3] = v[3];
83
+ }
84
+ }
85
+ const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(L, 0); ihdr.writeUInt32BE(A, 4); ihdr[8] = 8; ihdr[9] = 6;
86
+ return Buffer.concat([Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), pedaco('IHDR', ihdr), pedaco('IDAT', zlib.deflateSync(raw)), pedaco('IEND', Buffer.alloc(0))]);
87
+ }
88
+
89
+ function dimensoes(arquivo) {
90
+ const r = spawnSync('ffprobe', ['-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=width,height', '-of', 'csv=p=0', arquivo], { encoding: 'utf8' });
91
+ const [w, h] = String(r.stdout || '').trim().split(',').map(Number);
92
+ return w && h ? { w, h } : null;
93
+ }
94
+
95
+ /** Os filtros que o plano pede para um vídeo `w`×`h`; [] quando nada muda. */
96
+ function filtros({ w, h }, recursos) {
97
+ const lado = Math.min(w, h), teto = recursos.resolucao || 2160;
98
+ return { escala: lado > teto ? (w >= h ? `scale=-2:${teto}` : `scale=${teto}:-2`) : null, marca: !!recursos.marcaDagua };
99
+ }
100
+
101
+ /**
102
+ * Aplica o plano ao mp4 pronto (no lugar). Devolve {ok, resolucao, marcaDagua, mudou}.
103
+ * `rodar` e `dim` são injetáveis nos testes.
104
+ */
105
+ function aplicar(arquivo, recursos, { rodar = spawnSync, dim = dimensoes } = {}) {
106
+ if (!arquivo || !fs.existsSync(arquivo)) return { ok: false, mudou: false };
107
+ const d = dim(arquivo);
108
+ if (!d) return { ok: false, mudou: false };
109
+ const f = filtros(d, recursos);
110
+ if (!f.escala && !f.marca) return { ok: true, mudou: false, resolucao: Math.min(d.w, d.h), marcaDagua: false };
111
+
112
+ const tmp = path.join(os.tmpdir(), `primocode-marca-${process.pid}-${Date.now()}`);
113
+ const png = tmp + '.png', saida = arquivo.replace(/\.mp4$/i, '') + '.plano.mp4';
114
+ const args = ['-y', '-i', arquivo];
115
+ let g;
116
+ if (f.marca) {
117
+ const lado = Math.min(d.w, d.h) / (f.escala ? Math.min(d.w, d.h) / recursos.resolucao : 1);
118
+ fs.writeFileSync(png, pngMarca(Math.max(2, Math.round(lado / 300))));
119
+ args.push('-i', png);
120
+ g = `[0:v]${f.escala ? f.escala : 'null'}[v];[v][1:v]overlay=W-w-24:H-h-24[o]`;
121
+ args.push('-filter_complex', g, '-map', '[o]', '-map', '0:a?');
122
+ } else {
123
+ args.push('-vf', f.escala, '-map', '0:v', '-map', '0:a?');
124
+ }
125
+ args.push('-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-crf', '18', '-c:a', 'copy', saida);
126
+ const r = rodar('ffmpeg', args, { encoding: 'utf8', timeout: 10 * 60000 });
127
+ fs.rmSync(png, { force: true });
128
+ if (r.status !== 0 || !fs.existsSync(saida)) return { ok: false, mudou: false, erro: String(r.stderr || '').slice(-300) };
129
+ fs.renameSync(saida, arquivo);
130
+ return { ok: true, mudou: true, resolucao: Math.min(f.escala ? recursos.resolucao : Math.min(d.w, d.h), Math.min(d.w, d.h)), marcaDagua: f.marca };
131
+ }
132
+
133
+ /**
134
+ * O envelope do render: checa a cota, roda `render()`, aplica o plano ao mp4 e
135
+ * conta o vídeo. `render` devolve o resultado da ferramenta ({ok, video,...}).
136
+ */
137
+ async function comCota(render, deps = {}) {
138
+ const c = await (deps.consultar || consultar)('checar');
139
+ if (!c.liberado) return { ok: false, error: mensagemLimite(c), cota: { plano: c.plano, restam: 0, upgrade: c.upgrade } };
140
+ const r = await render();
141
+ if (!r || !r.ok) return r;
142
+ const a = c.offline ? { ok: true, mudou: false } : (deps.aplicar || aplicar)(r.video, c.recursos);
143
+ if (!c.offline) await (deps.consultar || consultar)('gastar');
144
+ const restam = c.restam == null ? null : Math.max(0, c.restam - 1);
145
+ return { ...r, plano: { id: c.plano, restam, resolucao: c.recursos.resolucao, marcaDagua: !!(a.mudou && c.recursos.marcaDagua) },
146
+ ...(c.offline ? { aviso: 'sem rede: modo local, sem cota nem marca d\'água.' }
147
+ : restam === 0 ? { aviso: 'Foi o seu último vídeo do mês. Veja os planos com: primocode planos' } : {}) };
148
+ }
149
+
150
+ module.exports = { LOCAL, consultar, mensagemLimite, pngMarca, filtros, aplicar, comCota };
@@ -0,0 +1,105 @@
1
+ {
2
+ "id": "clube-ad5",
3
+ "titulo": "AJ1 Low Last Dance",
4
+ "categoria": "produto",
5
+ "resumo": "anúncio de produto de 19,4 s, em story 9:16, para a loja argentina do Clube dos Sneakers. A base é um vídeo curto de celular do Air Jordan 1 Low Last Dance, publicado por outra loja de tênis e sem a marca dela na tela, posto em câmera lenta interpolada. Os 3 primeiros segundos são um gancho de interface: o card do tênis estala inclinado, a mão-cursor arrasta \"Deslizá para comprar\", o check vira \"+\" e, no drop, o \"+\" infla e vira a tela inteira com o vídeo real. No meio vêm cortes na batida e cartões de preço, envío e talle; no fim, a página real do par na loja, o toque em COMPRAR e o logo. Montado no After Effects por um gerador em Python, o \"modo startup\", que serviu aos anúncios 2 a 5 da campanha. Escolhido pelo autor para os anúncios da loja.",
6
+ "indicado": "loja online que quer anunciar um produto específico em story, a partir de um vídeo curto gravado no celular.",
7
+ "estilo": [
8
+ "gancho de interface",
9
+ "forma que vira vídeo",
10
+ "câmera lenta",
11
+ "cortes na batida",
12
+ "cartões flutuantes",
13
+ "página real da loja",
14
+ "loop."
15
+ ],
16
+ "ficha": {
17
+ "formato": "1080×1920, 30 qps, 9:16 (story), cor BT.709",
18
+ "duracao": "19,4 s",
19
+ "motor": "ae",
20
+ "voz": "sem narração: texto na tela, música e efeitos",
21
+ "musica": "ver o guia de estilo",
22
+ "fontes": "ver o guia de estilo"
23
+ },
24
+ "ferramentas": [
25
+ "Claude Code",
26
+ "After Effects",
27
+ "ElevenLabs"
28
+ ],
29
+ "ficha_tecnica": {
30
+ "Duração": "19,4 s",
31
+ "Formato": "1080×1920, 30 qps, 9:16 (story), cor BT.709",
32
+ "Voz": "sem narração: texto na tela, música e efeitos",
33
+ "Ferramenta": "After Effects, com o projeto gerado por um script em Python",
34
+ "Idioma": "espanhol da Argentina",
35
+ "Uso": "anúncio em story no Meta Ads",
36
+ "Trilha": "\"Butterfly Doors\" (Lil Pump), 130 BPM",
37
+ "Fecho": "\"clubdossneakers.com · Hasta 6 cuotas sin interés\" sobre o logo"
38
+ },
39
+ "etapas": [
40
+ {
41
+ "titulo": "O roteiro",
42
+ "texto": "**Resumo:** o anúncio não tem narração; o texto na tela e os cartões contam a história, presos à batida de 130 BPM. Aqui estão os textos exatos e as cenas por tempo (marcas de `marcas-lastdance.json` e chaves do `startup.py`). Gancho: o card do tênis e \"Deslizá para comprar\".\n\n## Os textos da tela (espanhol da Argentina, verbatim)\n\n | \n\n | Momento\n | Texto\n\n | Card do gancho\n | \"Air Jordan\" · \"NUEVO\" · \"AJ1 Low Last Dance\" · \"$ 99.900\" · \"6 cuotas sin interés\"\n\n | Pílula\n | \"Deslizá para comprar\"\n\n | Nome\n | \"Last Dance\" / \"Air Jordan 1 Low\"\n\n | Cartão de preço\n | \"BIENVENIDO10 · 10% off\" · \"$ 99.900\" · \"6 cuotas sin interés\"\n\n | Chip\n | \"Envío gratis\"\n\n | Card de talle\n | \"Elegí tu talle\" · 39 AR a 43 AR · \"41 AR\" selecionado · \"Disponible\" · \"Envío gratis · 6 cuotas sin interés\"\n\n | Frase grande\n | \"Pagalo en\" / \"6 cuotas.\"\n\n | Fecho\n | página real do produto na loja · \"clubdossneakers.com\" · \"Hasta 6 cuotas sin interés\"\n\n## Como o vídeo base entrou\n\n | \n\n | Trecho do original (s)\n | Batidas no anúncio\n | Começa em (s)\n\n | 0,00–2,43\n | 6\n | 2,77 (dentro do círculo)\n\n | 2,43–3,90\n | 4\n | 5,54\n\n | 3,90–5,20\n | 4\n | 7,38\n\n | 5,20–7,30\n | 6\n | 9,23\n\n | 7,30–9,00\n | 6\n | 12,00\n\nTodos os trechos foram interpolados para 60 qps com compensação de movimento e esticados para caber nas batidas.\n\n## Cenas por tempo\n\n## Gancho (0 a 3,7 s)\n\n | \n\n | Tempo (s)\n | Música\n | Tela\n\n | 0–0,75\n | introdução\n | o card do tênis estala inclinado no estúdio claro; as linhas entram em cascata e o tênis gira e flutua\n\n | 0,30\n | \n | a pílula \"Deslizá para comprar\" estala por baixo\n\n | 0,52–1,0\n | \n | a mão-cursor entra em arco e aperta o botão\n\n | 1,16–1,86\n | pausa antes do drop\n | o botão desliza até o fim; a faixa laranja enche atrás dele; a câmera empurra até a pílula\n\n | 1,92–2,26\n | \n | a pílula colapsa em círculo, o check se desenha com faíscas e vira \"+\"\n\n | 2,77\n | \n | o \"+\" começa a crescer e vira um card com o vídeo dentro\n\n | 3,23\n | **drop**\n | o card vira a tela inteira com o vídeo real; a interface recua\n\n## Vídeo real (3,7 a 14,8 s)\n\n | \n\n | Tempo (s)\n | Tela\n\n | 4,15–5,9\n | \"Last Dance\" / \"Air Jordan 1 Low\" entra pela esquerda\n\n | 5,54 · 7,38 · 9,23 · 12,00\n | cortes com chicote, alternando o lado\n\n | 6,46–8,2\n | o cartão de preço estala com o cupom\n\n | 8,31–10,1\n | o chip \"Envío gratis\" estala, com três emojis 3D saltando em volta\n\n | 10,15–11,9\n | o card \"Elegí tu talle\" estala; em 11,08 s a mão toca o 41, que fica preto com \"Disponible\", e o card se abre em acordeão com zoom\n\n | 12,46–14,6\n | \"Pagalo en\" / \"6 cuotas.\" grande, no centro\n\n## Fecho (14,8 a 19,4 s)\n\n | \n\n | Tempo (s)\n | Tela\n\n | 14,77–15,3\n | a forma encolhe num card com a página real do par na loja AR\n\n | 15,92\n | a mão toca COMPRAR, com ripple; a página afunda e volta\n\n | 16,62\n | corte para um close de 2,5× no preço, com pan até o botão\n\n | 17,31\n | corte para um plano médio que sai pela direita\n\n | 17,77\n | o círculo escuro cresce do centro; o monograma do CDS estala; entram \"clubdossneakers.com\" e \"Hasta 6 cuotas sin interés\"\n\n | 18,96–19,4\n | o círculo fecha e sobra o fundo claro do primeiro quadro (loop)"
43
+ },
44
+ {
45
+ "titulo": "A identidade visual",
46
+ "texto": "**Resumo:** estúdio claro no estilo Apple, com uma luz laranja (HOT) por baixo e grade de pontos, onde vive o gancho de interface; depois, o vídeo real do tênis em tela cheia, com vinheta escura e cartões brancos por cima. Movimento de \"startup\": pop inclinado, cursor em arco, colapso em círculo, chicote na batida. Rap com drop no 7º tempo e efeitos nivelados, mix a −16 LUFS. Números tirados de `startup.py`, `base.py` e `trilha.py`.\n\n## Fontes\n\n | \n\n | Uso\n | Fonte\n | Onde baixar\n\n | Nome do tênis, preço, \"Envío gratis\", palavra forte\n | SF Pro Display Bold (tracking −18)\n | developer.apple.com/fonts\n\n | Linha leve do texto (\"Air Jordan 1 Low\", \"Pagalo en\")\n | SF Pro Display Light\n | developer.apple.com/fonts\n\n | Marca, pílula, talles, cupom\n | SF Pro Display Medium\n | developer.apple.com/fonts\n\n | \"6 cuotas sin interés\" e textos pequenos\n | SF Pro Text Regular\n | developer.apple.com/fonts\n\n | Seta do botão\n | Material Icons\n | Google Fonts\n\n## Cores\n\n | \n\n | Token\n | Hex\n | Uso\n\n | Fundo\n | `#F5F5F7`\n | estúdio, igual no primeiro e no último quadro\n\n | Branco\n | `#FFFFFF`\n | cards, chips, botão da pílula\n\n | Estúdio do card\n | `#F2F2F5`\n | fundo da foto do tênis\n\n | Tinta\n | `#1D1D1F`\n | texto, pílula, selo \"NUEVO\", círculo do logo\n\n | Tinta 2\n | `#3A3A3C`\n | marca e parcelamento\n\n | Cinza\n | `#86868B`\n | texto secundário\n\n | Cinza claro\n | `#EDEDF0`\n | linhas de talle\n\n | **HOT**\n | **`#FF4A12`**\n | a faixa que enche, a pílula colapsada, faíscas, a forma única, luz do estúdio a 9%\n\n | Azul do cupom\n | `#4A61DF`\n | pílula \"BIENVENIDO10 · 10% off\"\n\n | Verde\n | `#34C759`\n | \"Disponible\"\n\n | Cinza do fecho\n | `#C7C7CC`\n | \"Hasta 6 cuotas sin interés\"\n\n## Componentes\n\n- **Card do produto** 760×880, raio 64, sombra larga: foto do tênis girando de −18° para −6° e flutuando, marca, selo \"NUEVO\", nome, preço e \"6 cuotas sin interés\".\n\n- **Pílula \"Deslizá para comprar\"** 820×150: botão branco redondo com seta, faixa HOT que enche atrás dele, colapso em círculo, check desenhado, 8 faíscas radiais e o \"+\".\n\n- **Mão-cursor** com sombra, ponta do dedo como âncora, entrando em arco (Bézier quadrática por expressão).\n\n- **Forma única (HEROI)**: o círculo do \"+\" vira card 440×560 e depois a tela inteira; no fecho, encolhe para um card de 680×1472, raio 70.\n\n- **Vídeo real** com vinheta (elipse com traço preto de 520 px a 55%, desfocada 160).\n\n- **Cartões sobre o vídeo:** preço (cupom, valor, parcelamento), chip \"Envío gratis\" com o caminhão e três emojis 3D que saltam em volta (fogo, brilho, rosto apaixonado), card \"Elegí tu talle\" com cinco talles (39 a 43 AR) em acordeão, o 41 selecionado em preto com \"Disponible\".\n\n- **Página real** do par na loja AR, com cantos arredondados, ripple branco no toque em COMPRAR.\n\n- **Fecho:** círculo cor de tinta que cresce de 0 a 2.400 px, monograma do CDS, endereço e parcelamento.\n\n## Movimento\n\n- **Pop inclinado (R1):** escala 29% → 100% com a mola da casa (passa de ~112%), rotação −10° → 0° e Y subindo 95 px, passando 81 px do ponto e voltando, nos quadros 0, 4 e 16.\n\n- **Cascata (R5):** cada linha do card entra 60 px abaixo e a −7°, com 2 quadros entre uma e outra.\n\n- **Cursor (R2):** entra com escala 0 → 34% em arco, aperta (34 → 29%) no clique e solta.\n\n- **Colapso (R4):** a pílula vira círculo, o botão some em 3 quadros e o check se desenha em 4 quadros.\n\n- **Câmera do gancho:** a interface empurra até 112% na pílula enquanto ela desliza e recua para 80% no drop.\n\n- **Chicote em cada corte:** o vídeo entra deslocado 150 px (alternando os lados), volta em 0,16 s e o desfoque direcional cai de 90 a 0 em 0,18 s.\n\n- **Texto:** entra palavra por palavra (0,05 s entre elas), deslizando com desfoque 16 → 0 e escala 115 → 100%, com sombra suave; sai em chicote para cima em 0,22 s.\n\n- **Fecho da página:** aberto → close de 2,5× no preço e pan de 13 quadros até o botão → plano médio de 1,4× que sai pela direita em 12 quadros.\n\n- Motion blur ligado, obturador de 180°.\n\n## Curvas e molas\n\n | \n\n | Nome\n | Bezier\n | Uso\n\n | saas\n | (.86, 0, .07, 1)\n | arraste do botão, forma única, câmera, saídas dos cartões\n\n | fast\n | (.10, 0, 0, 1)\n | subida do pop inclinado, chicote do corte\n\n | desl\n | (.33, 0, .17, 1)\n | escala do vídeo entre cortes\n\n | sai\n | (.16, 1, .3, 1)\n | entrada do texto\n\n | chicote\n | (.7, 0, .84, 0)\n | saída do texto\n\n | pan\n | (.33, 0, .67, 1)\n | check, talles, pan do close\n\n | easein\n | (.55, 0, 1, .45)\n | plano médio saindo\n\n**Mola da casa (\"nossa\"):** sobe linear em 0,25 s e quica `1 + 0,2·sin(4π·q)·e^(−4q)`, passando cerca de 112%.\n\n## Trilha\n\n | \n\n | Item\n | Valor\n\n | Música\n | \"Butterfly Doors\" (Lil Pump), a partir de 13,39 s da faixa\n\n | Tempo\n | 130 BPM (batida de 0,4615 s)\n\n | Drop\n | 16,62 s da faixa, no 7º tempo do vídeo (3,23 s), quando a forma vira a tela inteira\n\n | Respiro\n | a pausa da própria música antes do drop recebe o arraste e o check\n\n | Fecho\n | a partir do fim do vídeo real (14,77 s), mistura de 55% da música com passa-baixas de 1,4 kHz; fade no último segundo\n\n## Sound design e mix\n\n | \n\n | Faixa\n | Nível\n\n | Música\n | −18 LUFS\n\n | Efeitos\n | o volume de cada evento vem da lista; o barramento todo entra com −4 dB\n\n | Final\n | −16 LUFS, limitador em torno de −1,5 dBFS\n\nUm efeito para cada ação, todos da biblioteca nivelada: pop no card e na pílula, whoosh no cursor e no arraste, clique no aperto, sucesso no check, pop no \"+\", whoosh grave e impacto no drop, whoosh em cada corte (alternando dois), pop em cada cartão e emoji, clique no talle, impacto na frase do parcelamento, whoosh longo no fecho, clique em COMPRAR, impacto no close, whoosh grave no plano médio e no logo, pop no monograma e whoosh no loop.\n\n## O que é \"humano\" neste vídeo\n\n- O tênis do card flutua e balança de leve enquanto o resto entra.\n\n- O cursor faz curva, como uma mão, e o botão afunda no clique.\n\n- A luz laranja do estúdio deriva devagar por expressão.\n\n- Os emojis flutuam alguns pixels fora de fase.\n\n- O vídeo original é amador, tremido e de verdade; a câmera lenta só dá peso a ele."
47
+ },
48
+ {
49
+ "titulo": "A montagem no After Effects",
50
+ "texto": "| \n\n | Script\n | O que faz\n\n | `startup.py`\n | o anúncio inteiro, configurado no dicionário `ADS` (`ANUNCIO=lastdance`): corta o vídeo na batida com o ffmpeg (com a câmera lenta interpolada), escreve o JSON do AE, o `.jsx`, a lista de efeitos e as marcas de tempo. O mesmo gerador faz os anúncios do Nike Mind, do Rookie Card e do BadBo\n\n | `base.py`, `kit_ae.py`\n | tokens, curvas por segmento, a mola da casa e as funções de comp, camada, forma, texto e efeito\n\n | `trilha.py`\n | música a partir de uma batida, efeitos, música abafada no fecho e mix final\n\n | `render.ps1`, `montar.py`\n | render em trechos de 2 s e junção com o áudio, com a cor etiquetada em BT.709\n\n | `capturas/capturar.mjs`\n | captura das telas reais da loja (Playwright, sem chamar a API)\n\nO `startup.py` escreve `startup-lastdance.json`, que uma ponte MCP do After Effects importa (`ae_project_import_json`, da `mcp-aftereffects`, de código aberto); depois roda o `pos-startup-lastdance.jsx` (cantos da tela e matte do vídeo). O `.aep` já vem montado: os scripts servem para estudar e reaproveitar. Algumas linhas apontam para pastas da máquina onde o vídeo foi feito (fontes, músicas, efeitos e o vídeo original); ao reaproveitar, peça ao agente para trocar pelos caminhos da sua central.\n\n- **Instale as fontes:** SF Pro (SF Pro Display Light, Medium, Semibold e Bold, e SF Pro Text Regular), da página de fontes da Apple para desenvolvedores (developer.apple.com/fonts), e Material Icons (Google Fonts, grátis). Instale para todos os usuários e reinicie o After Effects. No Windows, se não aparecer no AE, copie para `C:\\Program Files\\Common Files\\Adobe\\Fonts`.\n\n- **Mantenha a pasta `projeto/` como veio**: `ae/`, `capturas/` e `footage/` ficam nas mesmas posições relativas. Abra no After Effects 2026 ou mais novo.\n\n- **Comp:** `MAIN Startup lastdance`. O gancho está em `UI gancho`; o vídeo real, em `VIDEO real`. Renderize a `MAIN`.\n\n- **Arquivo faltando:** File › Dependencies › Find Missing Footage; clique com o direito › Replace Footage › File e aponte para a pasta certa (`ae/assets`, `capturas` ou `footage`).\n\n- **Render:** `render.ps1` com `-Passo 60` (trechos de 2 s); trechos de 8 s deram erro 9988 e quadros pretos no fim de cada trecho. Não importe JSON pela ponte enquanto o `aerender` roda: a importação responde, mas o projeto fica vazio. Depois, `montar.py` junta tudo com o mix; confira se há quadro preto."
51
+ },
52
+ {
53
+ "titulo": "As decisões de direção",
54
+ "texto": "- **Prender nos 3 primeiros segundos com interface.** O anúncio 1, só com o vídeo editado na batida, foi uma \"variação boa\", mas \"não ficou algo super editado\". O gancho aplica técnicas medidas no tutorial da keyframelord: o card nasce em 29% e −10° e passa de 100% com a mola; as linhas entram em cascata (−7°, 2 quadros de defasagem); o cursor entra em arco e afunda no clique; a faixa enche atrás do botão; a pílula colapsa em círculo em 3 quadros; o check se desenha em 4 quadros, com faíscas, e vira \"+\".\n\n- **O deslize cai no silêncio antes do drop.** A música foi escolhida por ter uma pausa logo antes do drop (faixa de 120 a 140 BPM); o arraste e o check acontecem nela.\n\n- **Uma forma só.** O \"+\" é o mesmo círculo que infla em card e depois na tela inteira, e o vídeo real aparece recortado por ele.\n\n- **O vídeo obedece à música.** Cada trecho do original foi esticado para um número inteiro de batidas, com câmera lenta interpolada. Cada corte ganha um chicote (deslocamento de 150 px e desfoque direcional de 90 a 0), e a escala do vídeo desliza devagar de 112% a 104% até o próximo corte, então nada fica parado.\n\n- **Informação na ordem da decisão de compra:** nome do par, preço com o cupom real da loja, envío grátis, talle disponível e parcelamento. Cada cartão entra com o mesmo pop inclinado do gancho.\n\n- **O fecho mostra o depois.** A forma encolhe num card com a página real do par na loja, a mão toca COMPRAR e a página é coberta em cortes na batida: aberto, close de 2,5× no preço com pan até o botão e plano médio saindo pela direita.\n\n- **Loop.** O logo surge numa revelação circular; no fim, o círculo fecha e sobra o fundo do primeiro quadro.\n\nDetalhes de cores, curvas e som: estilo.md. Textos e cenas por tempo: roteiro.md. Para fazer um anúncio no mesmo estilo: PROMPT.md."
55
+ },
56
+ {
57
+ "titulo": "As versões até o final",
58
+ "texto": "| \n\n | Versão\n | O que mudou\n\n | anúncio 1\n | edit simples: vídeo de referência na batida, texto, cartão de preço e celular no fecho; retorno: \"variação boa\", mas simples demais, sem câmera, transições e elementos\n\n | **modo startup**\n | este gerador: gancho de interface, forma única, cortes com chicote, cartões e página real no fecho. Fez os anúncios 2 a 5; o Last Dance (5) é este\n\n | rodada seguinte\n | retorno aos anúncios 2 a 5: \"ficou bom, só que é mais do mesmo… cada vídeo tem que ser uma coisa diferente\". A campanha ganhou um conceito por anúncio, e este continuou entre os escolhidos para anunciar"
59
+ }
60
+ ],
61
+ "pacote": [
62
+ {
63
+ "pasta": "projeto/",
64
+ "conteudo": "`startup-lastdance.aep`, o JSON de importação, o `.jsx` de pós-importação (máscara da tela e matte do vídeo), a pasta `ae/assets/` (foto do par, emojis 3D de fogo, brilho, rosto apaixonado e caminhão, mão-cursor, monograma do CDS e grade de pontos), a captura real da página do par na loja AR com o capturador, o vídeo já cortado na batida (`footage/lastdance-startup-30.mp4`), o mix e os scripts"
65
+ },
66
+ {
67
+ "pasta": "audio/",
68
+ "conteudo": "mix final (`mix-lastdance.wav`), `trilha.py`, a lista de efeitos (`sfx-lastdance.json`), as marcas de tempo (`marcas-lastdance.json`) e os efeitos usados (`sfx/`)"
69
+ },
70
+ {
71
+ "pasta": "referencias/",
72
+ "conteudo": "o vídeo original usado como base, os quadros do tutorial de animação SaaS estudado (keyframelord) e os links"
73
+ },
74
+ {
75
+ "pasta": "render/",
76
+ "conteudo": "`final.mp4`"
77
+ },
78
+ {
79
+ "pasta": "startup.py",
80
+ "conteudo": "o anúncio inteiro, configurado no dicionário `ADS` (`ANUNCIO=lastdance`): corta o vídeo na batida com o ffmpeg (com a câmera lenta interpolada), escreve o JSON do AE, o `.jsx`, a lista de efeitos e as marcas de tempo. O mesmo gerador faz os anúncios do Nike Mind, do Rookie Card e do BadBo"
81
+ },
82
+ {
83
+ "pasta": "trilha.py",
84
+ "conteudo": "música a partir de uma batida, efeitos, música abafada no fecho e mix final"
85
+ },
86
+ {
87
+ "pasta": "capturas/capturar.mjs",
88
+ "conteudo": "captura das telas reais da loja (Playwright, sem chamar a API)"
89
+ }
90
+ ],
91
+ "prompt": "Quero fazer um anúncio em story no mesmo estilo do projeto \"AJ1 Low Last Dance\", que está em 07-videos/projetos/ad5/, com o meu produto.\n\nProduto: {{PRODUTO}} (nome, preço, parcelamento e a foto sem fundo)\nLoja: {{LOJA}} (endereço e a página do produto, para capturar)\nVídeo do produto: {{VIDEO_PRODUTO}} (um vídeo curto de celular, de 8 a 15 s, sem marca de outra loja na tela)\nCartões do meio: {{CARTOES}} (ex.: preço com cupom, frete grátis, tamanho disponível)\nFrase grande antes do fecho: {{FRASE}} (ex.: \"Pagalo en 6 cuotas.\")\nIdioma: {{IDIOMA}}\n(Se algum desses estiver vazio ou com as chaves, me pergunte antes de começar.)\n\n1. Estude o projeto antes de propor qualquer coisa. Leia, nesta ordem: 07-videos/projetos/ad5/LEIA-ME.md, estilo.md e roteiro.md. Depois abra projeto/ae/startup.py (o dicionário ADS, o gancho, a forma única, os cartões e o fecho) e o trilha.py, e me explique em poucas linhas como o vídeo é cortado na batida, como o \"+\" vira a tela inteira e como os cartões entram. Diga o que vai reaproveitar.\n\n2. Siga o passo a passo de 07-videos/_LEIA.md e os números de 07-videos/regras-vigentes.md. Crie o meu projeto em 07-videos/projetos/AAAA-MM-DD-tema/ a partir de 07-videos/projetos/_modelo/README.md e marque cada etapa no checklist. Não edite os arquivos do projeto ad5: copie o startup.py e acrescente uma entrada nova no ADS.\n\n3. Use as skills instaladas: video-referencias (assets reais), motion-app-ae (interface no After Effects), animacao-saas (pop, cursor, forma que vira a próxima) e better-portuguese (todo texto da tela).\n\n4. Música primeiro: escolha uma faixa real de 120 a 140 BPM com uma pausa curta logo antes do drop. Meça o BPM e o tempo exato do drop e me mostre onde caem o arraste, o check e a forma virando a tela inteira (no drop). Espere o meu ok.\n\n5. O vídeo do produto: escolha de 4 a 6 trechos e estique cada um para um número inteiro de batidas. Se o vídeo for curto ou amador, use câmera lenta interpolada (minterpolate) como na referência. Confira os cortes numa folha de contato antes de abrir o After Effects.\n\n6. Tela real: capture a página do produto da minha loja com Playwright, sem chamar a API, no tamanho de celular (390 px ×3). Marque a posição do botão de compra e do preço na captura, porque o fecho dá um close nos dois.\n\n7. Reaproveite o motor, troque o conteúdo. Mantenha deste projeto: o gancho de 3 s (card com pop inclinado, cascata, pílula de deslizar com mão-cursor em arco, colapso em círculo, check que vira \"+\"), a forma única que vira a tela inteira com o vídeo recortado por ela, o chicote em cada corte, os cartões com o mesmo pop inclinado, o toque no botão de compra da página real, a cobertura em cortes na batida (aberto, close, plano médio saindo), o logo em revelação circular e o loop no último quadro, um efeito por ação e o mix a −16 LUFS. Troque: produto, textos, cores de destaque, cartões, vídeo, música e a página da loja. Se a minha marca tiver identidade forte, use a fonte e as cores dela no lugar do estúdio claro com laranja.\n\n8. Renderize em trechos de 2 s e confira se há quadro preto. Revise quadro a quadro com o áudio: o gancho prende nos 3 primeiros segundos? Cada cartão é lido antes de sair? Está humano ou robotizado? Me entregue o vídeo em story, a ficha atualizada e uma anotação em anotacoes/.",
92
+ "campos": [
93
+ "CARTOES",
94
+ "FRASE",
95
+ "IDIOMA",
96
+ "LOJA",
97
+ "PRODUTO",
98
+ "VIDEO_PRODUTO"
99
+ ],
100
+ "fonte": {
101
+ "nome": "Clube do Motion",
102
+ "url": "https://clubedomotion.com/projeto/?id=ad5",
103
+ "uso": "liberado pelo dono do Clube do Motion em 18/10/2026 (docs/permissoes/clube-do-motion.md)"
104
+ }
105
+ }
@@ -0,0 +1,107 @@
1
+ {
2
+ "id": "clube-ae-sem-memoria",
3
+ "titulo": "O After Effects travou",
4
+ "categoria": "produto",
5
+ "resumo": "loop quadrado de 9,3 s, sem narração, que conta a piada do After Effects travando por falta de RAM em telas claras da Apple. O ícone do Ae assenta entre os outros ícones da Adobe em cinza, uma barra fina vira o painel de arquivos, o aviso de \"travou\" entra no topo, uma mão em luva clica em \"Ver info\" e o aviso final sugere o upgrade de RAM. A câmera nunca para, e as trocas acontecem dentro de um desfoque de quadro inteiro tingido de lavanda. Um script do After Effects (`cenas.jsx`) monta o projeto do zero. Feito pelo Clube do Motion como recriação do estilo de @illdari.",
6
+ "indicado": "humor de ofício para criadores, editores e designers; post de marca de software ou de hardware; portfólio de UI motion com piada de interface.",
7
+ "estilo": [
8
+ "interface da Apple",
9
+ "modo claro",
10
+ "câmera viva",
11
+ "transição por desfoque tingido",
12
+ "cor só no assunto",
13
+ "texto em arco",
14
+ "loop"
15
+ ],
16
+ "ficha": {
17
+ "formato": "1080×1080, 30 qps, desfoque de movimento com obturador de 360° (fase −180°, 16 amostras)",
18
+ "duracao": "9,3 s, sem narração; o trecho de 4,633 s (139 quadros) se repete a partir de 4,63 s e de 9,27 s",
19
+ "motor": "ae",
20
+ "voz": "ver o guia de estilo",
21
+ "musica": "ver o guia de estilo",
22
+ "fontes": "SF Pro Display (Bold, Semibold, Medium e Regular) e SF Pro Text"
23
+ },
24
+ "ferramentas": [
25
+ "Claude Code",
26
+ "After Effects"
27
+ ],
28
+ "ficha_tecnica": {
29
+ "Duração": "9,3 s, sem narração; o trecho de 4,633 s (139 quadros) se repete a partir de 4,63 s e de 9,27 s",
30
+ "Formato": "1080×1080, 30 qps, desfoque de movimento com obturador de 360° (fase −180°, 16 amostras)",
31
+ "Ferramenta": "After Effects: um script ExtendScript (`cenas.jsx`) cria as comps `PAINEL`, `LOOP` e `RECRIACAO`; o `.aep` já vem montado",
32
+ "Assets": "ícones oficiais da Adobe (Ae, Pr, Ai, Xd e An) e o logo vermelho da Adobe; mão em luva, lupa, ícone (i) e ícone de arquivo desenhados para o projeto",
33
+ "Fontes": "SF Pro Display (Bold, Semibold, Medium e Regular) e SF Pro Text",
34
+ "Som": "trecho de \"Better Now\" (Post Malone), a 95,7 BPM, recortado para as trocas caírem na batida, e 46 efeitos sonoros pela Mesa; −14,0 LUFS. A música fica fora do pacote",
35
+ "Referência": "edit \"Buttery smooth motion in apple style\" de @illdari (23/07/2026)",
36
+ "Arquivo final": "MP4 H.264 com áudio AAC"
37
+ },
38
+ "etapas": [
39
+ {
40
+ "titulo": "O roteiro",
41
+ "texto": "**Resumo:** o vídeo não tem narração; o roteiro é a piada contada em cinco telas, com o texto que aparece e os tempos do `cenas.jsx`. A segunda passada repete tudo com +4,63 s.\n\n## De onde veio a estrutura\n\nO edit de @illdari faz uma piada que todo editor reconhece: o After Effects trava, alguém clica em \"Get Info\" e o sistema responde com uma provocação sobre a RAM. São cinco ideias, uma a cada 0,8 a 1 s, num trecho tocado duas vezes. Esta recriação mantém as telas, a câmera e os tempos, e escreve a piada em português.\n\n## Cenas por tempo\n\n | \n\n | Tempo (s)\n | Texto na tela\n | O que acontece\n\n | 0,00–0,33\n | —\n | a lavanda clareia; o ícone do Ae, enorme e desfocado, assenta no centro\n\n | 0,13–0,57\n | \"After Effects\"\n | os ícones cinza da Adobe fecham em volta; o nome chega letra por letra em arco\n\n | 0,55–1,40\n | —\n | o fundo pulsa em lavanda, o quadro desfoca de leve, a câmera abre e anda para a esquerda\n\n | 0,87–1,20\n | \"Arquivos\" · \"projeto 15MB\" · \"intro 12MB\" · \"apple 2MB\" · \"saas 1.6MB\"\n | uma barra fina ao lado do ícone abre e vira o painel; as linhas entram em cascata\n\n | 1,43–1,72\n | —\n | o painel cresce e engole a tela; o Ae sai pela esquerda\n\n | 1,67–2,48\n | \"After Effects travou\" · \"Arrume mais memória RAM.\"\n | o aviso vermelho entra no topo, os arquivos ficam vermelhos e a câmera mergulha; as linhas de baixo desfocam e o painel some\n\n | 2,40–2,75\n | \"Ver info\"\n | o \"(i)\", o \"Ver\" e o \"info\" caem girando; a pílula cinza aparece por trás\n\n | 2,75–3,20\n | —\n | a mão em luva entra pela direita, freia na pílula e clica\n\n | 3,05–3,55\n | —\n | brilho lavanda do clique, a pílula se enche de ciano e estica; o quadro inteiro desfoca\n\n | 3,53–4,20\n | \"Upgrade de RAM · 16GB\" · \"editar no AE com 8 GB de RAM é coragem\"\n | o aviso sai do desfoque; a câmera passa do ponto, assenta e desce\n\n | 4,20–4,63\n | —\n | o aviso desfoca e tudo volta à lavanda do primeiro quadro\n\n | 4,63–9,30\n | o mesmo\n | segunda passada e o começo da terceira\n\n## Momentos para o som\n\n- A música começa no primeiro quadro; o ícone, a barra que vira painel, o clique e o aviso final ficam perto das batidas, com desvio de até 0,2 s.\n\n- Pop para cada ícone que fecha em volta e para cada peça que cai; som de letras no nome em arco.\n\n- Alerta no \"travou\", mergulho na descida da câmera, clique e brilho no \"Ver info\" e um som de sucesso no aviso final.\n\n- Na segunda passada a música não repete; os eventos tocam de novo com +4,63 s."
42
+ },
43
+ {
44
+ "titulo": "A identidade visual",
45
+ "texto": "**Resumo:** cinzas muito claros (`#E6E6E6` e `#EEEEEE`), lavanda (`#B7B4DA`) nas trocas, painel de contraste baixíssimo e sem sombra, só o ícone do After Effects colorido e um ciano no clique. Câmera viva em todas as cenas e transição por desfoque de quadro inteiro. Números tirados do `cenas.jsx`.\n\n## Palco\n\n | \n\n | Peça\n | Como é\n\n | Tela\n | 1080×1080, 30 qps\n\n | Desfoque de movimento\n | obturador 360°, fase −180°, 16 amostras (limite adaptativo 128)\n\n | Montagem\n | comp `LOOP` de 4,633 s; a `RECRIACAO` empilha três cópias em 0, 4,633 e 9,267 s\n\n | Pré-comp\n | `PAINEL` (1080×1080), desenhado no tamanho e no lugar em que aparece aos 1,20 s\n\n## Cores\n\n | \n\n | Peça\n | Valor\n\n | Fundo\n | `#E6E6E6`, que vira `#EEEEEE` entre 1,50 e 1,75 s\n\n | Tinta da abertura e do fim\n | `#B7B4DA`\n\n | Pulso no meio da cena 1\n | `#C3C0DC`\n\n | Painel e linha destacada\n | `#EFEFEF` · `#FBFBFB`\n\n | Tamanhos de arquivo\n | `#BDBDBD`\n\n | Vizinhos da Adobe\n | Tint com preto `#838383` e branco `#9D9D9D`\n\n | Arquivo travado\n | Tint `#E8302F` / `#FFC2C2`\n\n | Brilho do aviso\n | `#FF6B6B` a 28%\n\n | Pílula e aviso final\n | `#E3E3E5`\n\n | Clique\n | ciano `#86DCE8` e brilho `#CFCBE6`\n\n## Fontes\n\n | \n\n | Fonte\n | Onde\n\n | SF Pro Display Bold\n | \"After Effects\" (48 px, `#14143C`)\n\n | SF Pro Display Medium\n | \"Arquivos\" (34 px), \"Ver\" e \"info\" (34 px)\n\n | SF Pro Display Regular\n | linhas do painel (30 px), tamanhos (18 px), aviso de travou (22 e 15 px), \"Upgrade de RAM\" (36 px) e \"16GB\" (32 px)\n\n | SF Pro Text Regular\n | a piada do aviso final (19 px, `#6E6E73`)\n\n## Curvas\n\n | \n\n | Nome\n | Chaves\n | Uso\n\n | Saída rápida\n | saída 5% · chegada 85–90%\n | ícones, letras, peças que caem, aviso\n\n | Contínua (\"A\")\n | Bézier contínua e automática em cada chave\n | nulos de câmera e escala do painel: a velocidade nunca chega a zero entre chaves\n\n | Suave\n | 50/50\n | clique da mão, pulsos de desfoque\n\n## Cena a cena\n\n | \n\n | Cena\n | Números\n\n | Ícone Ae\n | 368 px; escala 200 › 100%, desfoque 130 › 0 e sobe 150 px em 0–0,33 s\n\n | Vizinhos\n | Pr, Ai, Xd e An a 314 px, a ±475 px do centro; entram de 140 px para fora com desfoque 70 › 0, um a cada quadro, a partir de 0,13 s\n\n | Nome em arco\n | animador com posição (70, −70), rotação 45°, opacidade 0 e desfoque 12; faixa de 40%; deslocamento −40 › 100 em 0,12–0,55 s (cada letra viaja ~6 quadros, ~1 quadro depois da anterior)\n\n | Câmera A\n | escala 100 › 95,7 › 87 › 85 › 84% e x 540 › 235 entre 0,30 e 1,43 s; depois volta a 100% e leva o Ae para x −170 até 1,67 s\n\n | Pulso\n | fundo lavanda de 0 a 100% em 0,55–0,85 s e de volta a 0 em 1,40 s; desfoque do quadro até 22 em 0,90 s\n\n | Painel\n | barra de 20×470 que abre para 444×490 em 0,87–1,10 s; linhas em cascata a cada quadro desde 0,97 s; cresce até 1400×1500 em 1,72 s\n\n | Travou\n | aviso de 370×85 entra em 1,67 s e desce 35 px; linhas descem 66–74 px; ícones ficam vermelhos em 1,80–2,04 s\n\n | Mergulho\n | escala do painel 100 › 103 › 112 › 118 › 165 › 170 › 173% e y até 990 entre 0,85 e 2,48 s; desfoque das linhas 2, 6, 14 e 22 de cima para baixo; o painel some em 2,36–2,48 s\n\n | Ver info\n | \"(i)\", \"Ver\" e \"info\" caem 60 px girando −25° › 0 em 0,2 s, com 2 quadros entre eles; pílula de 232×88 aparece em 2,65–2,72 s\n\n | Mão e clique\n | luva entra de (440, 260) até a pílula em 2,75–2,98 s, girando −20° › 0; aperta para 88% em 3,05–3,20 s; brilho de 820 px com desfoque 260 vai de 20 a 100% e de 0 a 38% de opacidade\n\n | Morph\n | ciano enche a pílula da esquerda para a direita (3,20–3,42 s), a pílula estica 130% na horizontal e o quadro desfoca até 80 (3,46–3,55 s)\n\n | Aviso final\n | card de 608×180, raio 50; câmera 112 › 96 › 97,5 › 97% entre 3,50 e 4,63 s e desce 53 px; desfoque 0 › 60 em 4,20–4,45 s e lavanda a 100% no último quadro\n\n## Som\n\n | \n\n | Item\n | Valor\n\n | Música\n | trecho a partir de 88,464 s de \"Better Now\", 95,7 BPM; ganho −10 dB antes da soma\n\n | Eventos\n | 46 (23 por passada): logo, pop, letras, transição, painel, item, zoom, alerta, mergulho, palavra, move, clique, brilho, sucesso e sai\n\n | Efeitos\n | um por evento, pelo mapa padrão da Mesa, sem tonais; barramentos ×4\n\n | Medido\n | final −14,0 LUFS, pico −1,3 dBFS; música −15,3 e efeitos −18,6 LUFS\n\n## O que é \"humano\" neste vídeo\n\n- Em nenhuma cena a câmera fica parada: abre, anda, mergulha ou assenta.\n\n- A câmera do aviso final passa do ponto e volta, em vez de quicar o card.\n\n- A mão segue derivando alguns pixels depois do clique."
46
+ },
47
+ {
48
+ "titulo": "A montagem no After Effects",
49
+ "texto": "| \n\n | Arquivo\n | O que faz\n\n | `ae/cenas.jsx`\n | apaga o que houver no projeto aberto e monta tudo. No topo ficam o bloco `CFG` (textos, cores, fontes, duração do loop) e o mapa das cenas em segundos. Ajudantes: `K` (chaves com influência, linear, hold ou \"A\", a curva contínua que não deixa a câmera parar), `retang`, `circulo`, `texto`, `textoDireita`, `animador`, `blur`, `tinge` (ícone colorido para cinza) e `rastro`. Cada cena tem um nulo de câmera próprio (`CAM A`, `CAM C`, `CAM D`)\n\n | `ae/ae-apple.aep`\n | o resultado do script, pronto para abrir e renderizar\n\n | `audio/trilha.py`\n | lê `eventos.json`, põe a música 10 dB abaixo antes da soma, coloca um efeito por evento pelo mapa padrão, reforça os efeitos ×4 e mixa para −14 LUFS\n\n | `audio/eventos.json`\n | tempos e tipos de cada evento (logo, pop, letras, transição, painel, item, alerta, mergulho, palavra, clique, brilho, sucesso…)\n\n- **Fontes:** instale SF Pro Display e SF Pro Text em `C:\\Program Files\\Common Files\\Adobe\\Fonts` e reinicie o After Effects.\n\n- **Abrir:** `projeto/ae/ae-apple.aep`. Se o AE pedir arquivos, aponte para `projeto/assets/`.\n\n- **Adaptar:** troque os textos em `CFG.textos` (nome do app, linhas do painel, aviso e piada final), as cores em `CFG.cor` e os ícones em `assets/`, mantendo os nomes. Abra um projeto vazio e rode File › Scripts › Run Script File › `cenas.jsx`.\n\n- **Render:** fila do AE com a comp `RECRIACAO` em H.264.\n\n- **Som:** no `audio/trilha.py`, troque o `sys.path` para a pasta `audio/mesa`, ponha a sua faixa em `audio/musica.wav` e rode `python audio/trilha.py`. Cole o `audio/mix.wav` no vídeo com o ffmpeg (`-c:v copy -c:a aac -shortest`).\n\n**Pegadinhas:** opacidade de nulo não chega aos filhos; por isso cada linha do painel aplica a opacidade em cada parte. O ícone de arquivo está a 17% de escala e o desfoque dele vai ×5,5 para bater com o texto. O Tint com Amount 0 deixa o ícone com a cor original; anime o Amount, e não o preenchimento. Sem a SF Pro instalada, o AE troca a fonte e os textos mudam de largura."
50
+ },
51
+ {
52
+ "titulo": "As decisões de direção",
53
+ "texto": "- **A câmera nunca para.** Cada cena tem o seu nulo de câmera com chaves de curva contínua: abre de 100 a 84% e anda 300 px na primeira, mergulha de 100 a 173% no painel e passa do ponto e assenta (112 › 96 › 97,5%) no aviso final.\n\n- **A troca acontece dentro do desfoque.** Uma camada de ajuste desfoca o quadro inteiro nas trocas (até 80 no clique) e a lavanda tinge a abertura e o fim do loop.\n\n- **Só o assunto tem cor.** Os vizinhos da Adobe passam por um Tint cinza; o Ae fica azul-marinho e lilás.\n\n- **O painel nasce de uma linha.** Uma barra de 20 px abre para 444 px com a borda direita parada, e depois engole a tela.\n\n- **O erro tem consequência visível.** Quando o aviso entra, as linhas descem, os ícones de arquivo ficam vermelhos e as linhas de baixo desfocam com a distância.\n\n- **Texto que cai.** \"After Effects\" chega letra por letra em arco, girando; \"(i)\", \"Ver\" e \"info\" caem de cima com 2 quadros entre eles.\n\n- **O clique é um evento de luz.** A mão afunda, um brilho lavanda de 820 px cresce enquanto apaga e a pílula se enche de ciano antes do desfoque total.\n\n- **Loop barato.** O trecho toca duas vezes; o último quadro cai na mesma lavanda do primeiro.\n\nDetalhes de cores, tempos e números: estilo.md. Cenas por tempo: roteiro.md. Para fazer o seu com outra piada de interface: PROMPT.md."
54
+ },
55
+ {
56
+ "titulo": "As versões até o final",
57
+ "texto": "| \n\n | Versão\n | O que mudou\n\n | **v1**\n | recriação ajustada lado a lado com o original, com as medidas de câmera tiradas quadro a quadro; textos e piada em português"
58
+ }
59
+ ],
60
+ "pacote": [
61
+ {
62
+ "pasta": "projeto/",
63
+ "conteudo": "`ae/cenas.jsx` (o gerador comentado), `ae/ae-apple.aep` (o projeto montado) e `assets/` (os 10 PNGs que o script importa)"
64
+ },
65
+ {
66
+ "pasta": "audio/",
67
+ "conteudo": "`trilha.py` (o som inteiro), `eventos.json` (os 46 eventos), `mix.wav`, `relatorio-som.json` e `mesa/`, com o motor de mix `mesa.py` e o `mapa_padrao.py`"
68
+ },
69
+ {
70
+ "pasta": "referencias/",
71
+ "conteudo": "`links.md` (o post original) e `fora-do-pacote.md`"
72
+ },
73
+ {
74
+ "pasta": "render.mp4",
75
+ "conteudo": "o vídeo final"
76
+ },
77
+ {
78
+ "pasta": "ae/cenas.jsx",
79
+ "conteudo": "apaga o que houver no projeto aberto e monta tudo. No topo ficam o bloco `CFG` (textos, cores, fontes, duração do loop) e o mapa das cenas em segundos. Ajudantes: `K` (chaves com influência, linear, hold ou \"A\", a curva contínua que não deixa a câmera parar), `retang`, `circulo`, `texto`, `textoDireita`, `animador`, `blur`, `tinge` (ícone colorido para cinza) e `rastro`. Cada cena tem um nulo de câmera próprio (`CAM A`, `CAM C`, `CAM D`)"
80
+ },
81
+ {
82
+ "pasta": "ae/ae-apple.aep",
83
+ "conteudo": "o resultado do script, pronto para abrir e renderizar"
84
+ },
85
+ {
86
+ "pasta": "audio/trilha.py",
87
+ "conteudo": "lê `eventos.json`, põe a música 10 dB abaixo antes da soma, coloca um efeito por evento pelo mapa padrão, reforça os efeitos ×4 e mixa para −14 LUFS"
88
+ },
89
+ {
90
+ "pasta": "audio/eventos.json",
91
+ "conteudo": "tempos e tipos de cada evento (logo, pop, letras, transição, painel, item, alerta, mergulho, palavra, clique, brilho, sucesso…)"
92
+ }
93
+ ],
94
+ "prompt": "Quero um loop quadrado de piada de interface no mesmo método do projeto \"ae-sem-memoria\", que está em 07-videos/projetos/ae-sem-memoria/: telas claras da Apple, câmera viva, trocas dentro de um desfoque tingido e cor só no assunto.\n\nApp ou ferramenta da piada: {{APP}}\nA piada em 4 ou 5 telas (ex.: ícone › lista › erro › botão › aviso irônico): {{PIADA}}\nFamília do app (os vizinhos que ficam cinza): {{VIZINHOS}}\nCor da tinta das trocas (tom claro): {{COR_TINTA}}\nMúsica (arquivo e segundo de início): {{MUSICA}}\n(Se algum desses estiver vazio ou com as chaves, me pergunte antes de começar.)\n\n1. Estude o projeto antes de propor qualquer coisa. Leia LEIA-ME.md, estilo.md e roteiro.md e abra projeto/ae/cenas.jsx: o bloco CFG, a função K com a curva contínua \"A\", os nulos de câmera de cada cena, a pré-comp PAINEL e as camadas DESFOQUE e TINTA. Me diga em poucas linhas o que vai reaproveitar.\n\n2. Junte os ícones oficiais do app e da família dele (SVG ou PNG do site oficial ou da Wikimedia). Os vizinhos passam por um Tint cinza; só o assunto tem cor.\n\n3. Escreva a piada em português, com frases curtas de interface, e monte a tabela tempo › tela › texto, uma ideia a cada 0,8 a 1 s. Me mostre e espere meu ok.\n\n4. Construa copiando o projeto, sem editar o original. Cada cena ganha um nulo de câmera com chaves contínuas (zoom de 15 a 40% e deriva de centenas de pixels); nenhum trecho com a câmera parada por mais de 10 quadros. Trocas grandes acontecem dentro do desfoque do quadro inteiro; a tinta clara abre e fecha o loop. Painéis nascem de uma linha fina; texto entra letra por letra ou palavra por palavra caindo em arco.\n\n5. O erro precisa ter consequência visível (itens que mudam de cor, câmera que mergulha, profundidade de campo), e o clique precisa de um evento de luz antes da tela seguinte.\n\n6. Feche o loop no mesmo tom do primeiro quadro. Meça as batidas da música (librosa), escreva os eventos num eventos.json e faça o som pelo audio/trilha.py: um efeito por peça, música 10 dB abaixo antes da soma, final em −14 LUFS.\n\n7. Antes do render, me mostre uma folha de contato com 12 quadros, incluindo o meio dos movimentos, e confira se a câmera não para, se nenhum texto fica cortado e se a emenda do loop não aparece. Renderize a comp RECRIACAO em H.264, cole o som com o ffmpeg e entregue o MP4 com uma anotação do que mudou.",
95
+ "campos": [
96
+ "APP",
97
+ "COR_TINTA",
98
+ "MUSICA",
99
+ "PIADA",
100
+ "VIZINHOS"
101
+ ],
102
+ "fonte": {
103
+ "nome": "Clube do Motion",
104
+ "url": "https://clubedomotion.com/projeto/?id=ae-sem-memoria",
105
+ "uso": "liberado pelo dono do Clube do Motion em 18/10/2026 (docs/permissoes/clube-do-motion.md)"
106
+ }
107
+ }
@@ -0,0 +1,120 @@
1
+ {
2
+ "id": "clube-agent",
3
+ "titulo": "TDA Agent",
4
+ "categoria": "saas",
5
+ "resumo": "vídeo de 20 s, sem narração, que apresenta um agente de IA para atendimento. Começa como um lançamento de produto (o ícone se revela, o nome nasce letra por letra, um arco vira a barra de prompt, alguém digita \"Atende meus clientes por mim\" e clica) e, no drop da música, o botão infla e vira um cartão que se transforma em cada função: WhatsApp de madrugada, agenda da semana, cliente sumida que volta, leads quentes e frios e as ferramentas em órbita. Feito em código, no Remotion, pelo método de animação SaaS do Mojtaba Sorbi. As conversas e os números são de demonstração.",
6
+ "indicado": "startup ou empresa lançando um app, um agente de IA ou um SaaS que quer mostrar várias funções em poucos segundos, num post ou num anúncio.",
7
+ "estilo": [
8
+ "animação SaaS",
9
+ "forma que se transforma",
10
+ "modo claro",
11
+ "preto e lime",
12
+ "Geist",
13
+ "cortes na batida",
14
+ "remix cinematográfico."
15
+ ],
16
+ "ficha": {
17
+ "formato": "projeto em 1080×1920, 30 qps, 9:16; o vídeo final do pacote é a cópia publicada no Instagram (720×1280)",
18
+ "duracao": "20 s",
19
+ "motor": "ae",
20
+ "voz": "sem narração; as frases da tela contam as funções",
21
+ "musica": "ver o guia de estilo",
22
+ "fontes": "ver o guia de estilo"
23
+ },
24
+ "ferramentas": [
25
+ "Claude Code",
26
+ "After Effects",
27
+ "ElevenLabs"
28
+ ],
29
+ "ficha_tecnica": {
30
+ "Duração": "20 s",
31
+ "Formato": "projeto em 1080×1920, 30 qps, 9:16; o vídeo final do pacote é a cópia publicada no Instagram (720×1280)",
32
+ "Voz": "sem narração; as frases da tela contam as funções",
33
+ "Ferramenta": "Remotion (React), um arquivo só: `IntroTdaAgentV4.tsx`",
34
+ "Trilha": "\"Paddling Out\" (Miike Snow), em remix cinematográfico com drop em 7,512 s; 127,8 BPM",
35
+ "Som final": "−14,0 LUFS",
36
+ "Publicado": "no Instagram da TDA; em 09/10/2026 virou anúncio de tráfego para o perfil"
37
+ },
38
+ "etapas": [
39
+ {
40
+ "titulo": "O roteiro",
41
+ "texto": "**Resumo:** o roteiro visual dos 20 s, sem narração. O texto da tela é tudo que se lê: o nome do produto, o prompt digitado, cinco frases curtas (uma por função) e a frase do fecho. As fases depois do drop caem em batidas da música.\n\n## Texto da tela\n\n | \n\n | Onde\n | Texto\n\n | Nome\n | TDA Agent\n\n | Barra de prompt (exemplo)\n | Pergunte ao TDA Agent\n\n | Prompt digitado\n | Atende meus clientes por mim\n\n | Função 1\n | Responde no WhatsApp / até de madrugada\n\n | Função 2\n | Agenda e confirma / sozinho\n\n | Função 3\n | Chama de volta / quem sumiu\n\n | Função 4\n | Separa quem quer / comprar\n\n | Função 5\n | Com o que você / já usa\n\n | Fecho\n | TDA Agent · IA que trabalha / do jeito da sua empresa · logo TDA DIGITAL\n\nTextos dentro do cartão (demonstração): a cliente pergunta às 03:12 \"Vocês abrem sábado?\" e o agente responde \"Abrimos sim, das 9h às 13h! Quer que eu já reserve um horário pra você? 😊\", com o selo \"respondido pelo TDA Agent\"; na agenda da semana entram cinco horários (Ana, Bruno, Carla, Diego, Elis); a cliente \"visto por último há 12 dias\" recebe \"Oi, Ana! Ainda quer aquele orçamento da limpeza de pele? 😊\" e responde \"Quero sim! Pode fechar 🙌\"; a venda fecha em \"+ R$ 1.290\"; nos leads, Ana (\"quero fechar hoje\") e Carla (\"quanto fica pra 2?\") vão para quentes, e Bruno (\"só tô olhando\") para frios.\n\n## Cenas por tempo\n\n | \n\n | Tempo (s)\n | O que acontece\n\n | 0,35–2,3\n | o ícone aparece por varredura diagonal com uma luz passando; gira, encolhe e desliza; \"TDA Agent\" nasce letra por letra\n\n | 1,3–3,9\n | um arco lime se desenha embaixo e vira o contorno da barra de prompt; o \"+\", \"Pergunte ao TDA Agent\", o microfone e o botão sobem de dentro dela\n\n | 4,05–5,3\n | digita \"Atende meus clientes por mim\" com rastro lime; a câmera empurra até o botão\n\n | 6,0–7,15\n | a mão entra e clica no silêncio antes do drop\n\n | **7,51 (drop)**\n | o botão infla, vira um quadrado lime, pausa e abre no cartão do WhatsApp; barra e logo se dissolvem atrás\n\n | 8,0–10,3\n | \"Responde no WhatsApp até de madrugada\": a cliente pergunta às 03:12, o agente digita e responde; lua 3D no canto\n\n | 10,33\n | o cartão vira a agenda da semana; cinco horários entram a cada meia batida e ganham um ✓ lime\n\n | 12,21\n | vira a conversa com a cliente sumida há 12 dias, que responde que quer fechar; o cartão encolhe na pílula preta \"+ R$ 1.290\", com a sacola 3D e o valor contando\n\n | 14,09\n | a pílula abre no quadro de leads; três contatos caem no meio e escorregam para quentes (fogo) ou frios (gelo)\n\n | 15,49\n | o quadro encolhe no hub preto com o ícone; seis ferramentas entram uma por vez, ligadas por linhas pontilhadas, e giram devagar\n\n | 16,9–17,7\n | faixas desfocadas lime, preta e clara sobem e limpam a tela\n\n | 17,5–20\n | o fecho repete a abertura, mais rápido; \"IA que trabalha do jeito da sua empresa\"; o logo entra na batida final de 18,78 s, com um pulso\n\n## Momentos da trilha\n\n- 0–7,5 s: introdução tonal do remix, crescendo até o clique.\n\n- 7,15 s: clique no silêncio.\n\n- 7,512 s: drop, com o botão inflando.\n\n- Depois do drop, uma fase por compasso ou meio compasso: 10,33 · 12,21 · 14,09 · 15,49 · 16,9 s.\n\n- 18,78 s: batida final com o golpe tonal e o logo.\n\nAs conversas, os nomes e os valores são de demonstração."
42
+ },
43
+ {
44
+ "titulo": "A identidade visual",
45
+ "texto": "**Resumo:** modo claro na marca da agência (off-white, preto e lime), com uma luz lime viva no fundo e uma grade de pontos quase invisível. Uma forma única se transforma em cada função do produto, com a curva `cubic-bezier(.86, 0, .07, 1)` medida nos projetos do Mojtaba Sorbi. Frases palavra por palavra que nascem lime e viram tinta. Trilha real em remix cinematográfico, com cada troca num tempo da música. Números tirados de `IntroTdaAgentV4.tsx` e do tutorial da animação SaaS v4.\n\n## Fontes\n\n | \n\n | Uso\n | Fonte\n | Onde baixar\n\n | Nome do produto, frases, valores, leads\n | Geist 600 (e 300 no \"+\" da barra)\n | Google Fonts (carregada pelo `@remotion/google-fonts`)\n\n | Interfaces dentro do cartão (WhatsApp, agenda)\n | Inter 400 a 700\n | Google Fonts\n\n## Cores\n\n | \n\n | Token\n | Hex\n | Uso\n\n | Off-white\n | `#F4F4F2`\n | fundo\n\n | Tinta\n | `#0A0A0A`\n | texto, pílula de venda, hub\n\n | **Lime**\n | **`#A3E635`**\n | botão, ponto condutor, traço do arco, cursor, brilhos\n\n | Lime escuro\n | `#4D7C0F`\n | letra recém-nascida, rastro da digitação, linhas da órbita\n\n | WhatsApp\n | fundo `#EFEAE2`, bolha enviada `#D9FDD3`, tique `#53BDEB`, meta `#667781`, texto `#111B21`, linha `#E9EDEF`\n | o chat dentro do cartão\n\n | Google Agenda\n | azul `#039BE5`, verde `#33B679`, roxo `#8E24AA`, laranja `#F4511E`, hoje `#1A73E8`, grade `#E0E0E0`, texto `#3C4043`, cinza `#70757A`\n | a agenda da semana\n\n | Lead quente / frio\n | borda laranja `rgba(255,120,40,.55)` / azul `rgba(80,160,240,.5)`\n | quadro de leads\n\n | Sombra\n | `0 40px 90px rgba(20,30,10,.13), 0 10px 26px rgba(20,30,10,.07)`\n | barra, cartão, ferramentas\n\n## Fundo vivo\n\n- Elipse lime desfocada de 1800×1040 que sobe de y 2350 para 1820 no começo (como a luz de lançamento de produto) e flutua em seno lento.\n\n- Brilho branco por cima, uma mancha lime clara no alto à direita e uma grade de pontos de 40 px a 4,5%, que some nas bordas.\n\n## Componentes\n\n- **Logo e nome:** ícone de 168 px revelado por varredura diagonal (máscara de gradiente a 141°, 0,75 s) e por uma faixa de luz lime de 70 px girada 28°, recortada pela silhueta do ícone. Depois gira −360°, encolhe para 82% e desliza para a esquerda, enquanto \"TDA Agent\" (Geist 600, 116 px, espaçamento −4) nasce letra por letra, 0,05 s entre elas, com desfoque 12 → 0 e cor lime → tinta.\n\n- **Arco que vira barra:** traço em degradê (transparente → oliva → lime → oliva → transparente) com brilho lime, desenhado do centro para os lados em 1,1 s; em 0,9 s vira o contorno da barra de prompt (940×170) e encolhe para um risco que corre pela borda e some.\n\n- **Barra de prompt:** branca a 94%, borda de 1,5 px a 7%; o \"+\", o texto de exemplo palavra por palavra, o microfone e o botão lime de 104 px sobem de dentro dela. A digitação leva 0,045 s por letra; cada letra nasce oliva com brilho lime que se apaga em 0,32 s; cursor lime piscando a 2,6 Hz. O texto vive num campo que termina antes do microfone e rola para a esquerda.\n\n- **Mão:** cursor de mão de 150 px, girado −6°, posicionado pela ponta do dedo; entra em 0,85 s e aperta junto com o botão (mão 0,78, botão 0,86).\n\n- **Forma única** (`formaEm`), estados em ordem:\n\n | \n\n | Estado\n | Tamanho\n | Raio\n | Fundo\n\n | botão\n | 104 px\n | círculo\n | lime\n\n | quadrado\n | 300 px\n | 84\n | lime\n\n | chat\n | 900×700\n | 52\n | bege do WhatsApp\n\n | agenda\n | 900×780\n | 44\n | branco\n\n | chat 2\n | 900×600\n | 52\n | bege\n\n | pílula\n | 600×150\n | 75\n | preto\n\n | leads\n | 920×720\n | 44\n | branco\n\n | hub\n | 250×250\n | 70\n | preto\n\nCada troca leva cerca de 0,45 s e começa 0,08 a 0,12 s antes da batida. A forma respira (±2,5% ao longo do compasso) e tem um brilho lime que se apaga 0,5 s depois do drop. O conteúdo de cada fase entra depois de a forma assentar e sai com desfoque 0,16 s antes da troca seguinte.\n- **Objetos 3D** gerados para o vídeo: lua (no chat de madrugada), sacola (na venda), fogo e gelo (nos leads); entram com pop e flutuam.\n- **Órbita:** seis ferramentas (WhatsApp, Google Agenda, Gmail, Instagram, Drive, Planilhas) em tiles brancos de 148 px, raio 40, a 340 px do hub e 60° entre si; entram com 0,11 s de diferença, ligadas por linhas pontilhadas oliva, e giram a 9°/s.\n- **Faixas:** três retângulos de 1600×2600 (lime, preto e off-white) com desfoque de 60 px sobem em 0,8 s, defasados 0,1 s; o fecho entra por baixo da faixa clara.\n\n## Curvas\n\n | \n\n | Nome\n | Curva\n | Uso\n\n | SAAS\n | `cubic-bezier(.86, 0, .07, 1)`\n | câmera e transformações da forma (influência 86/93 medida nos projetos do Mojtaba)\n\n | SUAVE\n | `cubic-bezier(.33, 0, .67, 1)`\n | troca de cor das letras, entradas suaves\n\n | POP\n | `cubic-bezier(.34, 1.56, .64, 1)`\n | balões, eventos da agenda, leads, ferramentas, objetos 3D\n\n | inflar\n | `Easing.out(Easing.back(1.4))`\n | botão → quadrado, com leve passada do ponto\n\n | saída rápida\n | `Easing.out(Easing.cubic)`\n | letras, itens que sobem da barra\n\n## Câmera\n\nNulls 2D encadeados, cada um com deslocamento e escala em torno do centro, todos com a curva SAAS:\n\n | \n\n | Tempo (s)\n | Movimento\n\n | 1,4 → 2,25\n | o logo assenta (escala 0,93)\n\n | 2,45 → 3,35\n | sobe para a barra (−170 px, escala 0,95)\n\n | 4,5 → 5,5\n | empurra até o botão (−300 px, escala 1,24)\n\n | 5,6 → 7,3\n | respiro lento até o clique (escala 1,04)\n\nNo drop, a forma nasce exatamente onde o botão está na tela, calculado com a câmera daquele instante.\n\n## Frases\n\n- Geist 600, 84 px, no máximo duas linhas, em y 300, espaçamento −3,5% do tamanho.\n\n- Uma palavra a cada 0,11 s (0,085 s no fecho). A palavra nasce oliva com brilho lime, vira tinta em 0,075 s e perde o desfoque de 6 px em 0,1 s.\n\n- A linha visível fica sempre centrada: quando entra uma palavra, ela salta para o novo centro, sem interpolar.\n\n- Um ponto lime vai à frente da última palavra e encolhe logo depois.\n\n- Saída: sobe 26 px com desfoque de 9 px em 0,22 s.\n\n## Trilha\n\n | \n\n | Item\n | Valor\n\n | Música\n | \"Paddling Out\" (Miike Snow)\n\n | Tratamento\n | remix cinematográfico: introdução tonal com sintetizador até o drop, depois a música inteira\n\n | Tom e tempo\n | Lá♯ menor, 127,8 BPM (batida de 0,4695 s, compasso de 1,878 s)\n\n | Drop\n | 7,512 s, no clique do botão\n\n | Fases\n | agenda em 10,33 s, cliente sumida em 12,21 s, leads em 14,09 s, ferramentas em 15,49 s, faixas em 16,9 s, batida final em 18,78 s\n\n | Saída\n | a trilha fica em volume 1 e some entre 19,3 e 20 s\n\nO comando do remix está no tutorial em `referencias/`.\n\n## Sound design\n\nUm efeito por ação, com o pico do arquivo no quadro do evento (`início = evento − pico`), volumes de 0,07 a 0,3:\n\n | \n\n | Ação\n | Efeito (volume)\n\n | Varredura do logo\n | whoosh mágico (0,12)\n\n | Arco\n | whoosh (0,10)\n\n | Nome\n | chiado rápido (0,12)\n\n | Barra e botão\n | pops (0,12 e 0,14)\n\n | Digitação\n | teclado, com a duração exata da digitação (0,10)\n\n | Empurrão da câmera\n | whoosh (0,10)\n\n | Clique\n | clique (0,20)\n\n | Drop, botão inflando\n | pop grande de transição (0,30)\n\n | Balões\n | pops (0,15)\n\n | Cada troca de fase\n | whoosh (0,11)\n\n | Horário confirmado\n | \"sucesso\" curto (0,07)\n\n | Venda\n | sininho de recompensa (0,20)\n\n | Lead\n | pop (0,12)\n\n | Ferramenta\n | clique (0,10)\n\n | Faixas\n | whoosh (0,14)\n\n | Batida final\n | golpe tonal Ping Boom em Lá♯ (0,28)\n\nFinal a −14,0 LUFS, com loudnorm em duas passagens.\n\n## O que é \"humano\" neste vídeo\n\n- A câmera respira até o clique em vez de parar.\n\n- A mão chega devagar, aperta junto com o botão e sai para baixo.\n\n- A forma respira com a música, e os objetos 3D flutuam.\n\n- O texto digitado rola como num campo de verdade, sem passar por baixo do microfone."
46
+ },
47
+ {
48
+ "titulo": "A montagem no Remotion",
49
+ "texto": "- **Instale o Node.js** e, dentro de `projeto/`, rode `npm install`. As fontes (Geist, Inter, Space Grotesk) vêm do pacote `@remotion/google-fonts`, sem instalar nada no sistema.\n\n- **Registre a composição** em `src/Root.tsx` (crie o arquivo se o seu projeto não tiver): `IntroTdaAgentV4`, 1080×1920, 30 qps, 600 quadros.\n\n- **Prévia:** `npx remotion studio`.\n\n- **Rascunho rápido:** `npx remotion render IntroTdaAgentV4 out/rascunho.mp4 --scale=0.5 --muted`.\n\n- **Render final:** `npx remotion render IntroTdaAgentV4 out/final.mp4` e normalize o áudio a −14 LUFS (loudnorm em duas passagens).\n\nO script do remix (`audio/lib/remix_cinematico.py`) é para estudar e reaproveitar: ele usa uma biblioteca de efeitos tonais que não vem no pacote. Algumas linhas apontam para pastas da máquina onde o vídeo foi feito; peça ao agente para trocar pelos caminhos da sua central."
50
+ },
51
+ {
52
+ "titulo": "As decisões de direção",
53
+ "texto": "- **Uma forma só atravessa o vídeo.** O ícone vira título, o arco vira a barra, o botão vira o cartão, e o cartão vira agenda, conversa, pílula de venda, quadro de leads e hub. O olho nunca precisa procurar onde está a ação.\n\n- **O clique cai no silêncio antes do drop.** O som do clique aparece sozinho, e a música volta junto com o botão inflando.\n\n- **O botão infla com pausa:** vai a um quadrado lime com uma leve passada do ponto, espera 0,08 s e só então abre no cartão. A pausa dá peso ao efeito.\n\n- **Cada função ganha uma tela real e uma frase de 3 a 5 palavras:** \"Responde no WhatsApp até de madrugada\", \"Agenda e confirma sozinho\", \"Chama de volta quem sumiu\", \"Separa quem quer comprar\", \"Com o que você já usa\".\n\n- **Toda troca cai num tempo da música:** as fases são contadas em batidas e compassos a partir do drop.\n\n- **O texto nasce lime e vira tinta,** e a linha se recentra em saltos quando entra cada palavra.\n\n- **O fecho repete a abertura,** mais rápido, e termina no logo na batida final.\n\n- **Modo claro e um elemento por vez:** a primeira versão, escura e cheia de elementos, foi refeita assim.\n\nDetalhes de cores, curvas e som: estilo.md. Roteiro visual por tempo: roteiro.md. Para fazer um vídeo no mesmo estilo: PROMPT.md."
54
+ },
55
+ {
56
+ "titulo": "As versões até o final",
57
+ "texto": "| \n\n | Versão\n | O que mudou\n\n | v1\n | escura, estilo startup, com \"Levels\" (Avicii) no remix; retorno: abertura sem sentido, elementos demais ao mesmo tempo, preferir modo claro, música batida demais\n\n | v2\n | rascunho claro com a câmera viajando entre cartões; ficaram cartões vazios no deslize\n\n | v3\n | refeita no método do Mojtaba Sorbi (uma forma que se transforma, câmera de nulls com a curva medida), trilha \"Paddling Out\"; retorno: \"exatamente o que eu queria\", com um ajuste\n\n | **v4**\n | o texto digitado passou a rolar dentro do campo, sem passar por baixo do microfone; aprovada e base dos vídeos de produto"
58
+ }
59
+ ],
60
+ "pacote": [
61
+ {
62
+ "pasta": "projeto/",
63
+ "conteudo": "o código (`src/tda-agent-intro/IntroTdaAgentV4.tsx` e os arquivos de que ele depende: cores e curvas em `src/tda-marina/MarinaV2.tsx`, a fonte Geist em `src/chatgpt-ads/legenda.tsx`), a pasta `public/` com as imagens (foto de perfil, objetos 3D, ícones dos apps, a mão do cursor), a marca em SVG, a trilha e os efeitos, mais `package.json`, `remotion.config.ts` e `tsconfig.json`"
64
+ },
65
+ {
66
+ "pasta": "audio/",
67
+ "conteudo": "a trilha remixada, os 17 efeitos usados e o script do remix (`lib/remix_cinematico.py`, com `tom.py` e `batida.py`)"
68
+ },
69
+ {
70
+ "pasta": "referencias/",
71
+ "conteudo": "o estudo do método do Mojtaba Sorbi (projetos do AE dissecados e a curva medida) e o tutorial completo da animação SaaS v4, com todos os componentes"
72
+ },
73
+ {
74
+ "pasta": "render/",
75
+ "conteudo": "`final.mp4`"
76
+ },
77
+ {
78
+ "pasta": "LogoTitulo",
79
+ "conteudo": "o ícone revelado por varredura diagonal, a luz que passa, o giro e o nome letra por letra; usado na abertura e no fecho"
80
+ },
81
+ {
82
+ "pasta": "Arco",
83
+ "conteudo": "o traço lime que se desenha e vira o contorno da barra de prompt"
84
+ },
85
+ {
86
+ "pasta": "Barra",
87
+ "conteudo": "a barra de prompt com \"+\", texto de exemplo, microfone, botão e a digitação"
88
+ },
89
+ {
90
+ "pasta": "Mao",
91
+ "conteudo": "a mão que entra e clica"
92
+ },
93
+ {
94
+ "pasta": "Frase",
95
+ "conteudo": "a frase palavra por palavra, com o ponto lime à frente"
96
+ },
97
+ {
98
+ "pasta": "Orbita",
99
+ "conteudo": "as seis ferramentas girando em volta do hub"
100
+ },
101
+ {
102
+ "pasta": "SFX",
103
+ "conteudo": "a lista de efeitos, cada um com o tempo do evento e o pico do arquivo"
104
+ }
105
+ ],
106
+ "prompt": "Quero fazer um vídeo de lançamento no mesmo estilo do projeto \"Apresentando o TDA Agent\", que está em 07-videos/projetos/agent/, com o meu produto.\n\nProduto: {{PRODUTO}}\nO que ele faz, em 4 a 6 funções: {{FUNCOES}}\nPrompt ou ação que abre o vídeo (o que a pessoa digita ou clica): {{PROMPT_INICIAL}}\nMarca (logo, cores) e frase do fecho: {{MARCA}} / {{FRASE_FINAL}}\nDuração aproximada: {{DURACAO}} (a referência tem 20 s)\n(Se algum desses estiver vazio ou com as chaves, me pergunte antes de começar.)\n\n1. Estude o projeto antes de propor qualquer coisa. Leia, nesta ordem: 07-videos/projetos/agent/LEIA-ME.md, estilo.md e roteiro.md, e o tutorial da animação SaaS em referencias/. Depois abra projeto/src/tda-agent-intro/IntroTdaAgentV4.tsx e me explique em poucas linhas como a câmera de nulls, a forma única (formaEm e Fase) e as fases contadas em batidas funcionam, e o que você vai reaproveitar.\n\n2. Siga o passo a passo de 9 etapas de 07-videos/_LEIA.md e os números de 07-videos/regras-vigentes.md. Crie o meu projeto em 07-videos/projetos/AAAA-MM-DD-tema/ a partir de 07-videos/projetos/_modelo/README.md e marque cada etapa no checklist. Não edite os arquivos do projeto agent: copie o arquivo para a pasta do meu vídeo e troque o conteúdo.\n\n3. Use as skills instaladas: animacao-saas (o método da forma que se transforma), video-referencias (telas e ícones reais), motion-app-ae (se eu pedir para levar ao After Effects) e better-portuguese (todo texto da tela).\n\n4. A ficha antes de animar: para cada função, uma tela real (WhatsApp, agenda, planilha, painel, o que for) e uma frase de 3 a 6 palavras com a palavra-chave no fim. Desenhe a cadeia de formas (botão → cartão → … → hub → logo), dizendo para cada troca \"esta forma vira aquela\". Me mostre a ficha e espere o meu ok.\n\n5. Trilha: escolha uma música real que eu ainda não usei, faça o remix cinematográfico com um drop claro (pode usar o remix_cinematico.py do pacote como modelo), meça o BPM e as batidas e monte os tempos P1…FIM em compassos e meias batidas a partir do drop. O clique tem que cair no silêncio logo antes do drop.\n\n6. Reaproveite o motor, troque o conteúdo. Mantenha deste projeto: a abertura (ícone por varredura com luz, nome letra por letra, arco que vira a barra, digitação com rastro, câmera que empurra até o botão, mão que clica), o botão que infla com pausa, a forma única com a curva cubic-bezier(.86,0,.07,1), o conteúdo de cada fase recortado pela forma, a frase palavra por palavra que nasce na cor de destaque e vira tinta, o ponto condutor, a órbita das ferramentas, as faixas desfocadas e o fecho que repete a abertura, um efeito por ação com o pico no quadro e o final a −14 LUFS. Troque: as cores (para as da minha marca), o prompt, os estados da forma, o conteúdo de cada fase, as ferramentas, os efeitos e a trilha.\n\n7. Texto digitado nunca passa por baixo de ícone ou botão, nenhuma fase fica com o cartão vazio na troca, e um elemento por vez. Se eu usar números ou conversas de exemplo, a legenda do post diz que são demonstração.\n\n8. Rascunho em meia resolução, sem som, e folha de contato a 3 quadros por segundo a cada rodada; procure quadros mortos, sobreposições e coisas aparecendo antes da hora. Em cada movimento, pergunte: está humano ou robotizado? Depois do render final, normalize o áudio e me entregue o vídeo, a legenda do post e a ficha atualizada. No fim, registre uma anotação em anotacoes/.",
107
+ "campos": [
108
+ "DURACAO",
109
+ "FRASE_FINAL",
110
+ "FUNCOES",
111
+ "MARCA",
112
+ "PRODUTO",
113
+ "PROMPT_INICIAL"
114
+ ],
115
+ "fonte": {
116
+ "nome": "Clube do Motion",
117
+ "url": "https://clubedomotion.com/projeto/?id=agent",
118
+ "uso": "liberado pelo dono do Clube do Motion em 18/10/2026 (docs/permissoes/clube-do-motion.md)"
119
+ }
120
+ }