primocode 8.40.0 → 8.42.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 (43) hide show
  1. package/README.md +34 -5
  2. package/bin/primocode.js +90 -0
  3. package/lib/acervo.js +391 -0
  4. package/lib/act.js +96 -0
  5. package/lib/audio-livre.js +6 -1
  6. package/lib/boas-vindas.js +80 -21
  7. package/lib/catalogo.js +24 -0
  8. package/lib/conta.js +24 -3
  9. package/lib/diretor.js +309 -0
  10. package/lib/tools.js +43 -0
  11. package/lib/ui.js +3 -2
  12. package/package.json +2 -2
  13. package/studio/__pycache__/edge.cpython-311.pyc +0 -0
  14. package/studio/__pycache__/elevenlabs.cpython-311.pyc +0 -0
  15. package/studio/__pycache__/voz.cpython-311.pyc +0 -0
  16. package/studio/arquivos/corte-teste-de-camera-fb823.json +57 -0
  17. package/studio/ferramentas/corte.md +42 -0
  18. package/studio/studio.log +39 -10
  19. package/studio/web/core.css +178 -0
  20. package/studio/web/home.html +91 -24
  21. package/studio/web/js/editor.js +17 -0
  22. package/studio/web/js/render.js +155 -15
  23. package/studio/web/render.css +18 -0
  24. package/studio/arquivos/corte-estatico-corte-a5bab.json +0 -150
  25. package/studio/arquivos/corte-founders-ai-teste-do-player-2de1d.json +0 -65
  26. package/studio/arquivos/corte-legado-teste.json +0 -1
  27. package/studio/arquivos/corte-legado2.json +0 -1
  28. package/studio/arquivos/corte-minimo-2a829.json +0 -24
  29. package/studio/arquivos/corte-ok-00a3b.json +0 -18
  30. package/studio/arquivos/corte-ok-1270e.json +0 -22
  31. package/studio/arquivos/corte-sweep-corte-cfb29.json +0 -147
  32. package/studio/arquivos/corte-visual-completo-78f50.json +0 -35
  33. package/studio/arquivos/grade-sweep-grade-0c2f1.json +0 -119
  34. package/studio/arquivos/prisma-estatico-prisma-d8740.json +0 -182
  35. package/studio/arquivos/prisma-sweep-prisma-4c58c.json +0 -166
  36. package/studio/arquivos/prisma-y-b0785.json +0 -52
  37. package/studio/arquivos/prosa-sweep-prosa-f29cf.json +0 -80
  38. package/studio/arquivos/tela-estatico-tela-c7daf.json +0 -90
  39. package/studio/arquivos/tela-motion-3ecaa.json +0 -135
  40. package/studio/arquivos/tela-motion-d6150.json +0 -135
  41. package/studio/arquivos/tela-sweep-tela-0d2bf.json +0 -84
  42. package/studio/arquivos/traco-estatico-traco-25872.json +0 -113
  43. package/studio/arquivos/traco-sweep-traco-0bcf4.json +0 -102
@@ -296,6 +296,23 @@ function aplicarChaves(no, e, ctx) {
296
296
  herdado[c] = NEUTRO[c];
297
297
  });
298
298
 
299
+ // Quais campos esta animação USA. Decidido UMA vez, ANTES das chaves, e é
300
+ // o que faz o navegador interpolar: a lista de `transform` precisa ter as
301
+ // MESMAS funções, na mesma ordem, em toda chave. Emitir só o que é
302
+ // diferente de zero deixava a chave do meio de `giroY: -90 → 0 → 12` sem
303
+ // perspective/rotateY — listas incompatíveis, o navegador desiste da
304
+ // interpolação por função e cai na matriz, e a perspectiva se perde no meio
305
+ // do giro. Vale igual para `rotate(0deg)` e para o blur.
306
+ var usado = {};
307
+ CAMPOS.forEach(function (c) {
308
+ usado[c] = herdado[c] !== NEUTRO[c] || chaves.some(function (k) {
309
+ return typeof k[c] === "number" && isFinite(k[c]) && k[c] !== NEUTRO[c];
310
+ });
311
+ });
312
+ // O MESMO juiz que decide o preserve-3d (linha do `transformStyle`): se os
313
+ // dois discordarem, sobra elemento achatado com perspectiva ou o contrário.
314
+ var tem3d = tem3dEm(chaves);
315
+
299
316
  var nome = "ch" + (++_nChave);
300
317
  var passos = chaves.map(function (k) {
301
318
  CAMPOS.forEach(function (c) {
@@ -307,23 +324,21 @@ function aplicarChaves(no, e, ctx) {
307
324
  // Assim a chave continua valendo se a pessoa arrastar o elemento no
308
325
  // palco depois — o contrário obrigaria a refazer todas as chaves.
309
326
  var dx = herdado.x, dy = herdado.y;
310
- var tem3d = herdado.giroX || herdado.giroY || herdado.prof;
311
327
  // A perspectiva vai NA transformação, não no pai: o pai é a cena, e uma
312
- // perspectiva lá mudaria todos os elementos. Constante em todas as
313
- // chaves, para o navegador interpolar só o que muda.
328
+ // perspectiva lá mudaria todos os elementos.
314
329
  if (tem3d) mov.push("perspective(1200px)");
315
- if (dx || dy) mov.push("translate(" + dx + "px," + dy + "px)");
316
- if (herdado.prof) mov.push("translateZ(" + herdado.prof + "px)");
317
- if (herdado.escala !== 1) mov.push("scale(" + herdado.escala + ")");
318
- if (herdado.escalaX !== 1 || herdado.escalaY !== 1) mov.push("scale(" + herdado.escalaX + "," + herdado.escalaY + ")");
319
- if (herdado.giroX) mov.push("rotateX(" + herdado.giroX + "deg)");
320
- if (herdado.giroY) mov.push("rotateY(" + herdado.giroY + "deg)");
321
- if (herdado.giro) mov.push("rotate(" + herdado.giro + "deg)");
330
+ if (usado.x || usado.y) mov.push("translate(" + dx + "px," + dy + "px)");
331
+ if (usado.prof) mov.push("translateZ(" + herdado.prof + "px)");
332
+ if (usado.escala) mov.push("scale(" + herdado.escala + ")");
333
+ if (usado.escalaX || usado.escalaY) mov.push("scale(" + herdado.escalaX + "," + herdado.escalaY + ")");
334
+ if (usado.giroX) mov.push("rotateX(" + herdado.giroX + "deg)");
335
+ if (usado.giroY) mov.push("rotateY(" + herdado.giroY + "deg)");
336
+ if (usado.giro) mov.push("rotate(" + herdado.giro + "deg)");
322
337
 
323
338
  var linhas = ["transform:" + (mov.length ? mov.join(" ") : "none")];
324
339
  linhas.push("opacity:" + herdado.opacidade);
325
- if (herdado.desfoque > 0) {
326
- linhas.push("filter:blur(" + herdado.desfoque + "px)");
340
+ if (usado.desfoque) {
341
+ linhas.push("filter:blur(" + Math.max(0, herdado.desfoque) + "px)");
327
342
  }
328
343
  return pct.toFixed(3) + "%{" + linhas.join(";") + "}";
329
344
  }).join("");
@@ -575,6 +590,11 @@ function renderElemento(e, ctx) {
575
590
  atrás, com bisel de luz em cima e o reflexo diagonal. Vale em QUALQUER
576
591
  elemento (texto, forma, ícone, imagem, lista, cartões), por isso mora
577
592
  aqui e não num tipo. O CSS faz o resto por `data-material`. */
593
+ /* A profundidade do elemento na cena: quanto ele acompanha a câmera.
594
+ >1 vem à frente (anda mais), <1 fica ao fundo (anda menos). É o que
595
+ transforma um zoom num plano com camadas. */
596
+ if (e.paralaxe != null && isFinite(Number(e.paralaxe))) no.dataset.paralaxe = Number(e.paralaxe);
597
+
578
598
  if (e.material) {
579
599
  no.dataset.material = e.material;
580
600
  if (e.raio != null) no.style.borderRadius = _px(e.raio);
@@ -944,7 +964,11 @@ function renderElemento(e, ctx) {
944
964
  }
945
965
  if (e.borda) no.style.border = (e.borda.largura || 2) + "px solid " + (e.borda.cor || "var(--c-linha)");
946
966
  if (f === "circulo") no.style.borderRadius = "999px";
947
- else no.style.borderRadius = _px(e.raio != null ? e.raio : 0);
967
+ // Sem `raio`, o vidro fica com o 28px da folha — escrever 0px inline
968
+ // aqui vencia o CSS e o painel de vidro saía de canto reto, contra o
969
+ // "padrão 28" que a spec promete. Forma comum segue quadrada.
970
+ else if (e.raio != null) no.style.borderRadius = _px(e.raio);
971
+ else if (e.material !== "vidro") no.style.borderRadius = "0px";
948
972
  if (f === "triangulo") { no.style.clipPath = "polygon(50% 0,100% 100%,0 100%)"; }
949
973
  if (f === "linha") { no.style.height = _px(e.espessura || 3); no.style.borderRadius = "999px"; }
950
974
  if (f === "seta") {
@@ -1448,7 +1472,7 @@ function desenharConectores(cena, elementos, W, H) {
1448
1472
 
1449
1473
  /* ------------------------------------------------------------------ cena */
1450
1474
 
1451
- function renderCena(cena, doc, op) {
1475
+ function renderCenaBase(cena, doc, op) {
1452
1476
  op = op || {};
1453
1477
  cena = cena || {};
1454
1478
  var W = doc.largura || 1920, H = doc.altura || 1080;
@@ -1709,4 +1733,120 @@ function comporCabecaCorpo(fluxo, layout, nCabeca, nCorpo) {
1709
1733
  filhos[filhos.length - 1].classList.add("corpo-fim");
1710
1734
  }
1711
1735
 
1712
- if (typeof module !== "undefined" && module.exports) module.exports = { renderCena: renderCena };
1736
+
1737
+ /* ══ A CÂMERA DA CENA ══════════════════════════════════════════════════════
1738
+ *
1739
+ * `chaves` move UM elemento. O que faltava era mover o QUADRO: a cena inteira
1740
+ * se aproximando enquanto o texto entra, a panorâmica que atravessa a arte, o
1741
+ * leve giro que tira a cara de página parada. É a câmera do After Effects, e
1742
+ * sem ela todo movimento nasce preso ao elemento — o vídeo parece um slide com
1743
+ * animação, que é exatamente a reclamação.
1744
+ *
1745
+ * COMO FUNCIONA: o conteúdo da cena vai para dentro de um `.palco`, e a câmera
1746
+ * anima o palco com a mesma máquina de chaves dos elementos (mesma curva,
1747
+ * mesma interpolação, mesma conta de duração). O FUNDO fica onde está, na raiz
1748
+ * da cena: é o que dá profundidade de graça — o quadro anda sobre o fundo em
1749
+ * vez de arrastar tudo junto, que é como um zoom de câmera se comporta.
1750
+ *
1751
+ * PARALAXE: um elemento com `paralaxe` anda MAIS (>1, perto da câmera) ou
1752
+ * MENOS (<1, ao longe) que o palco. Como ele já pode ter as próprias chaves, a
1753
+ * diferença vai num embrulho em volta dele — duas animações no mesmo nó
1754
+ * disputariam a mesma propriedade `transform`, e a segunda ganharia calada.
1755
+ */
1756
+
1757
+ // Movimentos com NOME, porque quem escreve o documento não quer pensar em
1758
+ // chave: são os quatro que aparecem em toda peça de motion.
1759
+ var CAMERAS = {
1760
+ aproximar: [{ t: 0, escala: 1 }, { t: 1, escala: 1.12 }],
1761
+ afastar: [{ t: 0, escala: 1.12 }, { t: 1, escala: 1 }],
1762
+ "pan-direita": [{ t: 0, x: -70 }, { t: 1, x: 70 }],
1763
+ "pan-esquerda": [{ t: 0, x: 70 }, { t: 1, x: -70 }],
1764
+ subir: [{ t: 0, y: 60 }, { t: 1, y: -60 }],
1765
+ descer: [{ t: 0, y: -60 }, { t: 1, y: 60 }],
1766
+ // O "empurrão" é o zoom com um grau de giro: é o que dá mão humana ao quadro.
1767
+ empurrar: [{ t: 0, escala: 1.02, giro: -0.6 }, { t: 1, escala: 1.14, giro: 0.3 }],
1768
+ balanco: [{ t: 0, x: -18, giro: -0.5 }, { t: 0.5, x: 12, giro: 0.4 }, { t: 1, x: -6, giro: -0.2 }],
1769
+ };
1770
+
1771
+ function chavesDaCamera(camera) {
1772
+ if (!camera) return null;
1773
+ if (typeof camera === "string") return CAMERAS[camera] ? CAMERAS[camera].slice() : null;
1774
+ if (Array.isArray(camera)) return camera.slice();
1775
+ if (camera.chaves && camera.chaves.length) return camera.chaves.slice();
1776
+ if (camera.movimento && CAMERAS[camera.movimento]) return CAMERAS[camera.movimento].slice();
1777
+ return null;
1778
+ }
1779
+
1780
+ /* A chave do elemento de paralaxe: a da câmera, menos a que o palco já deu.
1781
+ Fator 0 devolve nada (anda com o palco, que é o padrão). */
1782
+ function chavesDeParalaxe(chaves, fator) {
1783
+ var f = fator - 1;
1784
+ if (!f) return null;
1785
+ return chaves.map(function (k) {
1786
+ var nova = { t: _numero(k.t, 0) };
1787
+ if (typeof k.x === "number") nova.x = k.x * f;
1788
+ if (typeof k.y === "number") nova.y = k.y * f;
1789
+ if (typeof k.escala === "number") nova.escala = 1 + (k.escala - 1) * f;
1790
+ return nova;
1791
+ });
1792
+ }
1793
+
1794
+ function aplicarCamera(no, cena, op) {
1795
+ var chaves = chavesDaCamera(cena.camera);
1796
+ if (!chaves || !chaves.length || !op.animar) return no;
1797
+
1798
+ var palco = document.createElement("div");
1799
+ palco.className = "palco";
1800
+ while (no.firstChild) palco.appendChild(no.firstChild);
1801
+ no.appendChild(palco);
1802
+
1803
+ var ctx = { raiz: no, duracao: cena.duracao || 4, animar: true };
1804
+ aplicarChaves(palco, {
1805
+ chaves: chaves,
1806
+ suavizar: (cena.camera && cena.camera.suavizar) || "suave",
1807
+ }, ctx);
1808
+
1809
+ /* PARALAXE — e o cuidado que decide se isto funciona ou quebra o layout.
1810
+ · Elemento SEM animação própria recebe a diferença direto: é o caso
1811
+ comum, e assim nada muda no DOM.
1812
+ · Elemento que JÁ anima (tem chaves suas) precisa de um embrulho —
1813
+ duas animações no mesmo nó disputam `transform` e a segunda ganha
1814
+ calada. Embrulhar só é seguro quando ele está posicionado em
1815
+ absoluto; no fluxo, o embrulho viraria um filho a mais no flex e
1816
+ mudaria o espaçamento da cena. Nesse caso a paralaxe é ignorada, e
1817
+ vale a animação do elemento, que é a mais específica. */
1818
+ var comProfundidade = palco.querySelectorAll("[data-paralaxe]");
1819
+ Array.prototype.forEach.call(comProfundidade, function (el) {
1820
+ var fator = parseFloat(el.getAttribute("data-paralaxe"));
1821
+ if (!isFinite(fator) || fator === 1) return;
1822
+ var extras = chavesDeParalaxe(chaves, fator);
1823
+ if (!extras) return;
1824
+ var suave = (cena.camera && cena.camera.suavizar) || "suave";
1825
+
1826
+ if (!el.style.animationName) {
1827
+ aplicarChaves(el, { chaves: extras, suavizar: suave }, ctx);
1828
+ return;
1829
+ }
1830
+ if (el.style.position !== "absolute") return;
1831
+
1832
+ var capa = document.createElement("div");
1833
+ capa.className = "paralaxe";
1834
+ capa.style.position = "absolute";
1835
+ ["left", "top", "right", "bottom", "width", "height"].forEach(function (k) {
1836
+ capa.style[k] = el.style[k];
1837
+ el.style[k] = "";
1838
+ });
1839
+ el.style.position = "relative";
1840
+ el.parentNode.insertBefore(capa, el);
1841
+ capa.appendChild(el);
1842
+ aplicarChaves(capa, { chaves: extras, suavizar: suave }, ctx);
1843
+ });
1844
+ return no;
1845
+ }
1846
+
1847
+ function renderCena(cena, doc, op) {
1848
+ var no = renderCenaBase(cena, doc, op);
1849
+ return aplicarCamera(no, cena || {}, op || {});
1850
+ }
1851
+
1852
+ if (typeof module !== "undefined" && module.exports) module.exports = { renderCena: renderCena, CAMERAS: CAMERAS };
@@ -1332,3 +1332,21 @@
1332
1332
  column-gap: calc(var(--u, 19px) * 3);
1333
1333
  }
1334
1334
  .cena .fluxo[data-composicao="cabeca-corpo"] .el.numeros .num b { white-space: nowrap; }
1335
+
1336
+ /* ─────────────────────────────────────────────────────────── câmera ────
1337
+ O palco é o conteúdo da cena; a câmera anima ele. O FUNDO fica na raiz
1338
+ de propósito: o quadro anda sobre o fundo, como faz uma câmera, em vez
1339
+ de arrastar tudo junto — é daí que vem a profundidade sem custo.
1340
+
1341
+ `inset: 0` repete a geometria que o `.fluxo` já tinha, para o embrulho
1342
+ não mudar uma única posição de elemento quando a cena não tem câmera. */
1343
+ .cena > .palco {
1344
+ position: absolute;
1345
+ inset: 0;
1346
+ z-index: 1;
1347
+ transform-origin: 50% 50%;
1348
+ will-change: transform;
1349
+ }
1350
+ /* O embrulho de paralaxe só existe em volta de elemento posicionado, e
1351
+ herda a caixa dele — ver o comentário em render.js. */
1352
+ .cena .paralaxe { transform-origin: 50% 50%; will-change: transform; }
@@ -1,150 +0,0 @@
1
- {
2
- "id": "corte-estatico-corte-a5bab",
3
- "ferramenta": "corte",
4
- "titulo": "estatico-corte",
5
- "doc": {
6
- "tema": "brasa",
7
- "largura": 1080,
8
- "altura": 1920,
9
- "acabamento": "grao",
10
- "trilha": {
11
- "tipo": "gerada",
12
- "estilo": "pulso",
13
- "volume": 0.7
14
- },
15
- "cenas": [
16
- {
17
- "layout": "centro",
18
- "duracao": 3,
19
- "fundo": "aurora",
20
- "transicao": "flash",
21
- "elementos": [
22
- {
23
- "tipo": "texto",
24
- "papel": "titulo",
25
- "texto": "Sua conta subiu\nde novo.",
26
- "tamanho": 124,
27
- "estilo": "gradiente",
28
- "anim": "nenhuma"
29
- }
30
- ]
31
- },
32
- {
33
- "layout": "centro",
34
- "duracao": 3,
35
- "fundo": "vinheta",
36
- "transicao": "limpar",
37
- "elementos": [
38
- {
39
- "tipo": "texto",
40
- "papel": "titulo",
41
- "texto": "E não foi o seu chuveiro.",
42
- "tamanho": 78,
43
- "estilo": "marcador",
44
- "anim": "nenhuma"
45
- }
46
- ]
47
- },
48
- {
49
- "layout": "centro",
50
- "duracao": 4,
51
- "transicao": "zoom",
52
- "acabamento": "vinheta",
53
- "fundo": {
54
- "imagem": "/midia/torre.jpg",
55
- "escurecer": 0.5
56
- },
57
- "elementos": [
58
- {
59
- "tipo": "numeros",
60
- "contar": true,
61
- "anim": "nenhuma",
62
- "tamanho": 180,
63
- "itens": [
64
- "+38% | bandeira tarifária em 12 meses"
65
- ]
66
- }
67
- ]
68
- },
69
- {
70
- "layout": "livre",
71
- "duracao": 4,
72
- "transicao": "deslizar",
73
- "elementos": [
74
- {
75
- "tipo": "imagem",
76
- "src": "/midia/campo.jpg",
77
- "x": 0,
78
- "y": 0,
79
- "l": 1080,
80
- "a": 1920,
81
- "raio": 0,
82
- "movimento": "aproximar",
83
- "filtro": "contraste",
84
- "anim": "nenhuma"
85
- },
86
- {
87
- "tipo": "forma",
88
- "forma": "retangulo",
89
- "x": 0,
90
- "y": 1180,
91
- "l": 1080,
92
- "a": 740,
93
- "preenchimento": "rgba(10,5,6,.72)",
94
- "anim": "nenhuma"
95
- },
96
- {
97
- "tipo": "texto",
98
- "x": 90,
99
- "y": 1320,
100
- "l": 900,
101
- "a": 420,
102
- "texto": "O custo está\nna transmissão",
103
- "tamanho": 104,
104
- "peso": 750,
105
- "estilo": "sombra",
106
- "anim": "nenhuma"
107
- }
108
- ]
109
- },
110
- {
111
- "layout": "centro",
112
- "duracao": 5,
113
- "fundo": "raios",
114
- "transicao": "subir",
115
- "elementos": [
116
- {
117
- "tipo": "lista",
118
- "revelar": true,
119
- "tamanho": 52,
120
- "intervalo": 0.9,
121
- "itens": [
122
- "Linhas saturadas no Nordeste",
123
- "Usina gerando sem escoar",
124
- "A conta chega em quem consome"
125
- ],
126
- "anim": "nenhuma"
127
- }
128
- ]
129
- },
130
- {
131
- "layout": "centro",
132
- "duracao": 3,
133
- "fundo": "brilho",
134
- "transicao": "fade",
135
- "acabamento": "luz",
136
- "elementos": [
137
- {
138
- "tipo": "texto",
139
- "papel": "titulo",
140
- "texto": "Segue para\nentender a próxima.",
141
- "tamanho": 96,
142
- "estilo": "contorno-tom",
143
- "anim": "nenhuma"
144
- }
145
- ]
146
- }
147
- ]
148
- },
149
- "atualizado": "2026-08-16T15:08:28+00:00"
150
- }
@@ -1,65 +0,0 @@
1
- {
2
- "id": "corte-founders-ai-teste-do-player-2de1d",
3
- "ferramenta": "corte",
4
- "titulo": "Founders AI — teste do player",
5
- "doc": {
6
- "tema": "brasa",
7
- "largura": 1080,
8
- "altura": 1920,
9
- "acabamento": "grao",
10
- "trilha": {
11
- "tipo": "gerada",
12
- "estilo": "pulso",
13
- "volume": 0.7
14
- },
15
- "cenas": [
16
- {
17
- "layout": "centro",
18
- "duracao": 3,
19
- "fundo": "aurora",
20
- "transicao": "flash",
21
- "elementos": [
22
- {
23
- "tipo": "texto",
24
- "papel": "titulo",
25
- "texto": "Imersão\nFounders AI",
26
- "tamanho": 124,
27
- "estilo": "gradiente",
28
- "anim": "desfoque"
29
- }
30
- ]
31
- },
32
- {
33
- "layout": "centro",
34
- "duracao": 3,
35
- "fundo": "vinheta",
36
- "elementos": [
37
- {
38
- "tipo": "texto",
39
- "papel": "titulo",
40
- "texto": "Paris Group · Chapecó",
41
- "tamanho": 78,
42
- "estilo": "marcador",
43
- "anim": "palavra"
44
- }
45
- ]
46
- },
47
- {
48
- "layout": "centro",
49
- "duracao": 4,
50
- "fundo": "raios",
51
- "elementos": [
52
- {
53
- "tipo": "numeros",
54
- "contar": true,
55
- "tamanho": 180,
56
- "itens": [
57
- "20 | empresários por turma"
58
- ]
59
- }
60
- ]
61
- }
62
- ]
63
- },
64
- "atualizado": "2026-08-16T14:55:24+00:00"
65
- }
@@ -1 +0,0 @@
1
- {"id": "corte-legado-teste", "ferramenta": "corte", "titulo": "legado", "doc": {"tema": "meia-noite", "largura": 1080, "altura": 1920, "cenas": [{"duracao": "4s", "fundo": "aurora", "elementos": [{"tipo": "titulo", "texto": "Imersão Founders AI"}, {"tipo": "subtitulo", "conteudo": "Paris Group · Chapecó"}]}]}}
@@ -1 +0,0 @@
1
- {"id": "corte-legado2", "ferramenta": "corte", "titulo": "legado2", "doc": {"tema": "meia-noite", "largura": 1080, "altura": 1920, "cenas": [{"duracao": "4s", "fundo": "aurora", "elementos": [{"tipo": "titulo", "texto": "Imersão Founders AI", "anim": "nenhuma"}, {"tipo": "subtitulo", "conteudo": "Paris Group · Chapecó", "anim": "nenhuma"}]}]}}
@@ -1,24 +0,0 @@
1
- {
2
- "id": "corte-minimo-2a829",
3
- "ferramenta": "corte",
4
- "titulo": "minimo",
5
- "doc": {
6
- "tema": "claro",
7
- "largura": 1080,
8
- "altura": 1920,
9
- "cenas": [
10
- {
11
- "layout": "centro",
12
- "duracao": 5,
13
- "elementos": [
14
- {
15
- "tipo": "texto",
16
- "texto": "TESTE VISIVEL",
17
- "tamanho": 120
18
- }
19
- ]
20
- }
21
- ]
22
- },
23
- "atualizado": "2026-08-16T14:57:24+00:00"
24
- }
@@ -1,18 +0,0 @@
1
- {
2
- "id": "corte-ok-00a3b",
3
- "ferramenta": "corte",
4
- "titulo": "ok",
5
- "doc": {
6
- "cenas": [
7
- {
8
- "elementos": [
9
- {
10
- "tipo": "texto",
11
- "texto": "oi"
12
- }
13
- ]
14
- }
15
- ]
16
- },
17
- "atualizado": "2026-08-16T15:05:32+00:00"
18
- }
@@ -1,22 +0,0 @@
1
- {
2
- "id": "corte-ok-1270e",
3
- "ferramenta": "corte",
4
- "titulo": "ok",
5
- "doc": {
6
- "tema": "brasa",
7
- "cenas": [
8
- {
9
- "duracao": 3,
10
- "elementos": [
11
- {
12
- "tipo": "texto",
13
- "papel": "titulo",
14
- "texto": "Founders AI",
15
- "anim": "nenhuma"
16
- }
17
- ]
18
- }
19
- ]
20
- },
21
- "atualizado": "2026-08-16T17:50:21+00:00"
22
- }
@@ -1,147 +0,0 @@
1
- {
2
- "id": "corte-sweep-corte-cfb29",
3
- "ferramenta": "corte",
4
- "titulo": "sweep-corte",
5
- "doc": {
6
- "tema": "brasa",
7
- "largura": 1080,
8
- "altura": 1920,
9
- "acabamento": "grao",
10
- "trilha": {
11
- "tipo": "gerada",
12
- "estilo": "pulso",
13
- "volume": 0.7
14
- },
15
- "cenas": [
16
- {
17
- "layout": "centro",
18
- "duracao": 3,
19
- "fundo": "aurora",
20
- "transicao": "flash",
21
- "elementos": [
22
- {
23
- "tipo": "texto",
24
- "papel": "titulo",
25
- "texto": "Sua conta subiu\nde novo.",
26
- "tamanho": 124,
27
- "estilo": "gradiente",
28
- "anim": "desfoque"
29
- }
30
- ]
31
- },
32
- {
33
- "layout": "centro",
34
- "duracao": 3,
35
- "fundo": "vinheta",
36
- "transicao": "limpar",
37
- "elementos": [
38
- {
39
- "tipo": "texto",
40
- "papel": "titulo",
41
- "texto": "E não foi o seu chuveiro.",
42
- "tamanho": 78,
43
- "estilo": "marcador",
44
- "anim": "palavra"
45
- }
46
- ]
47
- },
48
- {
49
- "layout": "centro",
50
- "duracao": 4,
51
- "transicao": "zoom",
52
- "acabamento": "vinheta",
53
- "fundo": {
54
- "imagem": "/midia/torre.jpg",
55
- "escurecer": 0.5
56
- },
57
- "elementos": [
58
- {
59
- "tipo": "numeros",
60
- "contar": true,
61
- "anim": "saltar",
62
- "tamanho": 180,
63
- "itens": [
64
- "+38% | bandeira tarifária em 12 meses"
65
- ]
66
- }
67
- ]
68
- },
69
- {
70
- "layout": "livre",
71
- "duracao": 4,
72
- "transicao": "deslizar",
73
- "elementos": [
74
- {
75
- "tipo": "imagem",
76
- "src": "/midia/campo.jpg",
77
- "x": 0,
78
- "y": 0,
79
- "l": 1080,
80
- "a": 1920,
81
- "raio": 0,
82
- "movimento": "aproximar",
83
- "filtro": "contraste"
84
- },
85
- {
86
- "tipo": "forma",
87
- "forma": "retangulo",
88
- "x": 0,
89
- "y": 1180,
90
- "l": 1080,
91
- "a": 740,
92
- "preenchimento": "rgba(10,5,6,.72)"
93
- },
94
- {
95
- "tipo": "texto",
96
- "x": 90,
97
- "y": 1320,
98
- "l": 900,
99
- "a": 420,
100
- "texto": "O custo está\nna transmissão",
101
- "tamanho": 104,
102
- "peso": 750,
103
- "estilo": "sombra",
104
- "anim": "cortina"
105
- }
106
- ]
107
- },
108
- {
109
- "layout": "centro",
110
- "duracao": 5,
111
- "fundo": "raios",
112
- "transicao": "subir",
113
- "elementos": [
114
- {
115
- "tipo": "lista",
116
- "revelar": true,
117
- "tamanho": 52,
118
- "intervalo": 0.9,
119
- "itens": [
120
- "Linhas saturadas no Nordeste",
121
- "Usina gerando sem escoar",
122
- "A conta chega em quem consome"
123
- ]
124
- }
125
- ]
126
- },
127
- {
128
- "layout": "centro",
129
- "duracao": 3,
130
- "fundo": "brilho",
131
- "transicao": "fade",
132
- "acabamento": "luz",
133
- "elementos": [
134
- {
135
- "tipo": "texto",
136
- "papel": "titulo",
137
- "texto": "Segue para\nentender a próxima.",
138
- "tamanho": 96,
139
- "estilo": "contorno-tom",
140
- "anim": "elastico"
141
- }
142
- ]
143
- }
144
- ]
145
- },
146
- "atualizado": "2026-08-16T15:07:33+00:00"
147
- }