# Animação no momento da fala

Você decide ONDE a fala pede uma animação, QUE relação ela mostra e COMO a peça se transforma. O `build.py`
do projeto-modelo acha o tempo da palavra na transcrição do corte, põe a peça fora do rosto, escreve o HTML e
a timeline do GSAP e lista o som que cada animação pede. O catálogo com o código de cada peça pronta está em
`references/animacao-catalogo.md`. O que o catálogo não tem, você escreve como cena própria (fim desta página).

## Como falar com a pessoa

- Português simples, frases curtas. Nada de código, JSON ou caminho comprido na conversa.
- Conte o que vai aparecer, uma linha por peça, com o tempo em 00:12:
  "00:20 · rótulo 'Produto digital' em cima da sua cabeça", "00:24 a 00:27 · a lista vai riscando Espaço,
  Estoque e Frete".
- Autorização em camadas. Se a pessoa já autorizou fazer tudo, conte a lista e siga. Se ela pediu para
  aprovar antes, espere. Nunca peça de novo o que ela já autorizou.
- Uma decisão por vez. Ao dar opções, numere e diga qual recomenda. "Decide você": decida e conte em uma linha.

## Antes de começar

- Corte aprovado. Na pasta `edit` dele (`<EDIT>`): `cut.mp4`, `cut_timeline.json`, `transcripts/cut.json`
  e `face_layout.json`. A transcrição tem que ser do CORTE. Tempo do vídeo bruto não serve.
- Projeto HyperFrames: cópia da pasta `modelo-projeto` desta skill (`<SKILL>/modelo-projeto`), com
  `"edit": "../edit"` no `projeto.json`. Nunca edite o modelo original.
- Onde a pessoa fica em cada trecho (tela cheia, prova, moldura, tela verde, planos) é de
  `references/enquadramento.md`. O plano em blocos (`references/direcao-por-blocos.md`) vem antes das animações.

## Quando animar e quando não

1. **Uma ideia por vez.** Uma peça em destaque de cada vez. A próxima entra quando a anterior já saiu ou
   já parou.
2. **Anime o que muda.** A animação existe para mostrar uma relação ou uma mudança que a fala afirma. Se a
   ideia não tem nada mudando, uma imagem bem resolvida basta, ou nada.
3. **Nada de enfeite.** Estrela, confete, seta sem motivo, ícone parado que só cresce: não. Se tirar a peça
   e a fala continuar igual de clara, a peça não precisava existir.
4. **Ritmo.** No máximo uma peça NOVA a cada 4 a 6 s; dentro dela, cada item entra na sua palavra. Vídeo de
   30 a 60 s fica com 3 a 8 peças. Trecho que não pede nada fica limpo.
5. **Texto curto.** 1 a 4 palavras por linha. A peça resume, a fala explica. `*palavra*` destaca uma parte.
   Hierarquia e encaixe de texto: `references/lettering.md`.
6. **Peça grande pede espaço.** Lista, passo a passo, diagrama, celular e fotos entram na moldura ou na tela
   verde. Em tela cheia só peça pequena: rótulo, carimbo, contador curto, objeto na mão.
7. **Gancho e chamada.** No gancho só entra peça que É o gancho; se já tem título de gancho, não empilhe. Na
   chamada, só o botão ou o cartão final, com o texto inteiro legível antes de sair.
8. **Só o que existe.** Nunca desenhe clique, tela de sucesso, maquete de produto, reação, número, selo ou
   função que não esteja nos arquivos ou na fala. Faltou material: a peça fica mais simples ou não entra, e
   você diz o que faltou.

## Escolha a peça pela relação

Não comece pelo nome da peça. Primeiro conte o momento como uma cena de três quadros: como a tela está quando a
frase começa, o que se mexe no meio e como ela fica quando a frase termina; junto, anote o detalhe que quem assiste
tem que seguir enxergando durante a troca. Exemplo, na frase "a IA tira todos os respiros": abre com a onda da voz
cheia de buracos, os buracos fecham um por um, fecha com a onda emendada, e a voz nunca some da faixa no meio do
caminho. Com a cena escrita, vá à tabela abaixo: quem escolhe a linha é o tipo de ligação que a frase faz (ordem,
causa, comparação, parte e todo), e não o tema do vídeo.

| a fala afirma | mostre | evite |
|---|---|---|
| uma sequência de etapas | o MESMO objeto atravessando as fases e mudando a cada uma (o vídeo bruto vira uma faixa, a faixa perde os silêncios, os pedaços se juntam): `k2d_arquivo`; quando as etapas são coisas diferentes, `k2d_esquema` | três cartões iguais lado a lado |
| causa e efeito | a ação primeiro, o resultado depois, com um vínculo visível entre os dois (um empurra o outro, uma linha liga): `k2d_esquema` com `forma: "causa"` | resultado aparecendo sozinho, sem de onde veio |
| comparação | os dois lados na mesma escala, mesma base e mesmo enquadramento; só a diferença ganha cor: `k2d_antes_depois` (desenho) ou o bloco `comparar` (dois vídeos) | lados com tamanhos ou pontos de partida diferentes |
| um conjunto e suas partes | as mesmas peças se separam e se juntam de novo, cada uma no seu lugar | trocar as peças por outras no meio |
| onde as coisas ficam, o que tampa o quê, distância | profundidade (planos ou 3D), só se isso for parte da explicação | perspectiva só para parecer caro |
| uma lista de coisas soltas | `lista_check` do catálogo, item a item na palavra | lista para algo que é sequência ou causa |
| um número importante que foi dito | `contador`, termina no valor falado e para | número que ninguém disse |
| um nome, uma marca, um termo | `rotulo` em cima da cabeça | rótulo repetindo a legenda |

Correlação não vira causa. Ilustração não vira dado. Se a fala diz "quem faz X costuma ter Y", o desenho não
pode insinuar que X provoca Y.

## Peças que mudam de estado

O que eleva a edição é a transformação contínua: a peça que já está na tela vira a próxima, em vez de sumir
e dar lugar a outra.

- **O objeto fica, o estado muda.** Mesmo desenho, mesma cor base, mesmo canto da tela. Muda o que a fala
  mudou: o selo, a barra, o texto de uma linha, a posição de uma parte.
- **A peça seguinte nasce da anterior.** O item riscado encolhe e abre espaço para o novo; o cartão da etapa 1
  gira e mostra a etapa 2 no verso; a caixa que era um bloco se divide nas três partes explicadas.
- **Nunca troque o desenho para esconder uma falha.** Se a peça pula de posição ou muda de forma no meio, o
  olho perde o fio. Arrume o movimento.
- **Ícone faz alguma coisa.** Conecta, percorre, seleciona, enche, esvazia. Ícone parado que só aumenta não
  explica nada.
- **Transformação sem sentido vira corte seco.** Se a passagem não acrescenta nada, troque direto.

Pronto para adaptar: `k2d_arquivo` (um arquivo de vídeo que fica limpo), `k2d_conversa` (um celular com a conversa
que anda), `k2d_comando` (a barra que digita o pedido que a pessoa faz para a IA), `k2d_medidor` (a agulha que sobe
e desce numa escala), `k2d_busca` (a barra de busca com o resultado e a chamada) e `k2d_notas` (o bloco de notas em que
a lista se escreve e se conclui), no "Kit 2D" mais abaixo.

A primeira leitura do `k2d_medidor` só acontece uns 1,5 s depois do começo da cena (o cartão leva 0,9 s para entrar e a `pausa` é de 0,6 s). Comece a cena uns 1,5 s antes da palavra da primeira leitura, ou ponha `entrada` 0 e `pausa` 0,4 no PARAM; senão o `check` avisa que a ação entrou depois da palavra.


## Coreografia

1. Apresente o objeto parado antes de transformá-lo (0,4 a 0,8 s bastam).
2. A mudança acontece na frase que fala dela, não antes.
3. Terminou uma ação, congele tudo por 0,6 a 1,2 s: é o tempo de quem assiste registrar o resultado. Só então
   vem a próxima.
4. Um só movimento em destaque por vez. Enquanto ele acontece, o resto fica parado e o que já foi explicado
   perde força (fica menor, mais claro ou mais transparente).
5. Início, mudança e resultado aparecem no vídeo final. Nenhum corte esconde a etapa difícil.
6. A explicação termina antes da fala mudar de assunto. Se não termina, encurte a animação, não a fala.
7. Sem clarão: nada de tela branca piscando ou brilho estourado na troca.

## Diagrama que cresce com a fala

Para aula, explicação longa e VSL. Um diagrama só, que vai ganhando partes enquanto a pessoa explica.

- Desenhe a estrutura que a própria fala tem (etapas, grupos, causa e efeito). Falou de dois itens, são dois, não
  três.
- O primeiro elemento aparece quando é citado. Cada elemento novo entra quando é explicado. Os anteriores ficam
  PARADOS no mesmo lugar.
- Cor tem função fixa do começo ao fim (ex.: lilás é o que a pessoa faz, amarelo é o resultado). Não troque a
  cor de um elemento no meio.
- Rótulos curtos, 1 a 3 palavras. Seta só onde a relação foi dita.
- No exemplo, acenda o caminho que importa dentro do MESMO diagrama. Não abra um segundo diagrama.
- No fim, a estrutura inteira fica à vista por uns 2 s, sem elemento novo.
- Reserve o espaço final desde o começo: o primeiro elemento já nasce no lugar onde vai ficar quando o diagrama
  estiver completo. Nada se reorganiza depois.
- Em 9:16, o diagrama cabe na área livre da moldura ou em tela cheia com a pessoa em quadrinho. Em 16:9, do
  lado livre.
- Pronto para adaptar: `k2d_esquema`, no "Kit 2D" mais abaixo (etapas, grupos ou causa e efeito).

## Números, gráficos e escalas

- Valor, eixo, escala e legenda de gráfico só com número confirmado (dito na fala ou em material que a pessoa
  mandou). Sem número, o desenho é qualitativo: barras sem valor, sem eixo, e você avisa a pessoa quando ele
  parecer medição.

## Profundidade: 2D, 2,5D e 3D

- O que é plano se faz plano: vetor, formas simples, composição plana. É o padrão.
- Perspectiva e paralaxe organizam camadas. Isso é 2,5D, e é assim que você chama na entrega. Não é 3D.
- Volume de verdade (laterais, espessura, interior, câmera que gira) é cena 3D em Three.js no HyperFrames, com
  teste de uns 5 s antes: `references/3d.md` e a receita "Explicação espacial em 3D" em `references/modelos.md`.
  O kit já vem no projeto: `compositions/cenas/3d/` (motor e quatro cenas `k3d_*.html`) e o three.js em
  `assets/three`.
- Nunca entregue 2D como se fosse o 3D que a pessoa pediu. Se a técnica pedida não roda, pare e pergunte.

## Como achar o tempo da palavra

1. No projeto: `python3 build.py palavras 17 28` mostra cada palavra com início e fim, e os cortes, no tempo
   do `cut.mp4`.
2. No `projeto.json`, marque pela palavra: `"em": "produtos", "depois_de": 20` (a primeira "produtos" depois
   de 20 s; duas palavras também valem: `"em": "vender produtos"`). Número também vale: `"em": 20.49`.
3. A peça entra 0,1 s antes da palavra (o olho chega junto com o ouvido). Nunca mais de 0,15 s antes. Item de
   lista, passo, notificação e foto entram cada um na sua palavra.
4. A saída também pode ser palavra: `"sai": "Produtos", "sai_depois_de": 21.5` (sai 0,05 s antes dela).
5. Palavra que o Whisper escreveu errado: `"correcoes": {"S&A...": "essa IA"}` no topo do projeto.
6. O Whisper erra o tempo em 0,1 a 0,3 s às vezes. Confira a entrada tocando, com som.

## Duração, entrada e saída

| momento | como | quanto |
|---|---|---|
| cartão, rótulo, celular | pop: sobe com `back.out`, sem escala | 0,35 a 0,5 s |
| item de lista ou passo | desliza da esquerda | 0,3 s; a marca (check ou X) bate 0,25 s depois |
| carimbo | cai de cima e bate (`power4.in`), a tela treme | 0,28 s |
| foto | cai girando (`back.out(1.7)`) | 0,4 s |
| mudança de estado | a parte que muda anda com `power2.inOut`; o resto parado | 0,4 a 0,7 s |
| elemento novo de diagrama | aparece no lugar final (sobe um pouco e opacidade) | 0,35 s |
| fica na tela | até a ideia acabar, pelo menos 1,2 s depois da última palavra que ela mostra | |
| entra na moldura | depois do quadro fechar (0,7 s depois da troca): o build empurra e avisa | |
| saída | sobe um pouco e some (`power3.in`) | 0,2 a 0,3 s, antes da próxima ideia |

Tudo nasce invisível (`opacity: 0` no CSS) e aparece por um `fromTo`. As peças da moldura saem antes dela
acabar: o `build.py` corta e avisa.

**No fim do vídeo, o tempo de leitura vence.** O corte continua seco (nada de silêncio deixado de propósito) e
o `"segura_fim": 1.2` no `projeto.json` segura o último quadro parado, com a voz já terminada, enquanto a peça
ou a cena termina: a síntese que é a última palavra, o diagrama inteiro à vista por uns 2 s, o carimbo que
acabou de bater. As peças e cenas podem ter o `sai`/`ate` dentro desse tempo.

## Som de cada animação

O André quer som casado com cada animação que importa. O som é de `references/som-e-trilha.md`; aqui você só
marca o tipo e o momento. Todo `build.py` grava `sons_sugeridos.json` com um evento por movimento: `pop`
(cartão pousa), `whoosh` (moldura entra, celular sobe), `tique` (check), `risco` (item riscado), `impacto`
(carimbo bate, número pousa), `ding` (primeira notificação), `clique` (passo, troca do painel), `camera`
(polaroide), `contagem`, `sucesso` (painel concluído). O tempo (`em`) já é o do PICO: o quadro em que a
animação bate. Pequenos a -16 dBFS, momentos chave a -11.

O `sons_sugeridos.json` também traz o whoosh de cada zoom (no meio do movimento) e o da entrada da prova (no
quadro do corte). Cena própria não entra sozinha nele: anote você o quadro em que cada mudança de estado pousa
num `eventos.json` na pasta do projeto (`[{"t": 12.4, "tipo": "pop"}]`). O `plano_sfx.py --projeto` lê os dois
e escreve os sons no `projeto.json` (`references/som-e-trilha.md`).

Sons a menos de 0,65 s um do outro viram barulho: o plano fica com o mais forte. Fora isso, cada animação tem
o seu som (o plano não corta por quantidade no vídeo com animação).

## Passo a passo

1. `python3 build.py palavras` e leia a fala inteira. Marque os momentos e a relação de cada um (tabela acima).
2. Escreva as `animacoes` no `projeto.json` (campos de cada tipo no catálogo). Onde o catálogo não mostra a
   relação, adapte uma cena do kit 2D (ou do 3D) e, se nenhuma servir, escreva uma cena própria. Conte a lista
   para a pessoa (autorização em camadas).
3. Monte a amostra do trecho mais difícil, 8 a 15 s: `python3 build.py amostra 17.9 27.9`. Leia os `aviso:`.
4. `python3 build.py hf lint` e `python3 build.py hf check` (o `hf` usa a versão do `package.json`, a mesma do
   estúdio). Os dois têm que sair sem erro.
5. Abra a amostra no estúdio (`references/estudio.md`). Sem render. Toque em velocidade normal, com som, no
   tamanho de um celular. Depois passe a agulha quadro a quadro em cada entrada, mudança e saída.
6. Corrija no `projeto.json` ou na cena e veja de novo no estúdio. Com a amostra certa, o vídeo inteiro:
   `python3 build.py completo`, `check`, estúdio de novo.
7. Sons (`references/som-e-trilha.md`) e render só no fim:
   `python3 build.py hf render --quality delivery --output renders/final.mp4`.
8. Confira o ARQUIVO exportado, não só o estúdio (o estúdio pode piscar uma camada numa emenda; o arquivo é a
   referência). Para cada transformação, uma tira quadro a quadro:
   `uv run --directory "<SKILL>" python helpers/tira_de_quadros.py renders/final.mp4 21.8 22.9 --fps 30 --saida quadros/t22.jpg`

## O que conferir (em movimento, não em quadro parado)

Um quadro parado confere posição. Ele não prova sincronia, transição nem trajetória. Por isso:

- Toque o trecho inteiro com som antes de olhar quadros.
- Toda transformação e toda troca de cena conferida numa sequência densa (a tira a 30 qps), não em 3 ou 4
  quadros soltos. A peça não pode pular de lugar, trocar de desenho ou sumir por um quadro.
- Anote o intervalo que você olhou de verdade. Na entrega, diga esse intervalo ("olhei quadro a quadro de 00:17
  a 00:29 e as 6 transições").
- Nada em cima de olhos e boca. Rótulo em cima da cabeça sem cortar a testa.
- Texto certo, com acento, sem palavra grudada ("Produtodigital" é bug de espaço).
- A peça conclui a explicação antes da fala mudar de assunto e some antes da troca de cena.
- Legenda sem encostar na peça (o `build.py` desvia a legenda, confira).
- Nada cortado na borda. No 9:16, texto entre y 230 e 1530 e entre x 140 e 940.
- Número contando termina no valor certo e fica parado.
- O arquivo exportado repete o que o estúdio mostrou: sem quadro vazio, sem pulo, sem animação faltando.

## Kit 2D: cenas prontas para adaptar

Oito cenas em `compositions/cenas/2d/` do projeto cobrem as relações que mais aparecem em vídeo falado e que o
catálogo não tem. Elas seguem o molde do kit 3D: tudo o que muda de um vídeo para outro está no `const PARAM` do
topo, comentado; cada tempo sai de uma palavra da fala; uma ação acontece por vez e depois tudo fica parado
`pausa` segundos; o lugar final de cada coisa é calculado antes da primeira ação, então nada pula de posição nem
troca de desenho no meio.

| cena | use quando a fala | o que aparece |
|---|---|---|
| `k2d_arquivo` | conta que o mesmo arquivo mudou: tirou os respiros, cortou os erros, ficou mais curto | um arquivo de vídeo com a faixa da gravação; os respiros acendem em vermelho, somem e a fala se junta no mesmo lugar, o relógio desce até a duração nova e o selo troca de texto e de cor |
| `k2d_conversa` | conta uma conversa que andou: perguntaram, ela respondeu, o pedido fechou | um celular com a conversa; cada balão novo cai no espaço que já era dele (com os três pontinhos antes, se quiser) e o selo do topo muda de estado |
| `k2d_esquema` | explica etapas, grupos ou causas que levam a um efeito | caixas que entram uma por vez, cor por função, seta só na palavra da ligação, um caminho que acende no exemplo e apaga, e o esquema inteiro parado no fim |
| `k2d_antes_depois` | compara duas situações que dá para desenhar | os dois lados na mesma escala, alinhados pela mesma borda, com rótulos literais; o que mudou acende só no fim (faixas de tempo, ou duas imagens do projeto com um anel no mesmo lugar) |
| `k2d_comando` | a pessoa fala o pedido que faz para a IA ("edita esse vídeo pra mim", "corta os erros") e o resultado vem logo depois | uma barra de pedido que digita o texto letra por letra junto com a fala, com o cursor colado na última letra; texto comprido quebra e a barra cresce para baixo; depois da última letra o botão de enviar dá um toque, três anéis acendem e o selo de resultado entra na palavra dita |
| `k2d_medidor` | põe uma coisa numa escala: custo mínimo, risco alto, nível, nota | um medidor de meia volta com o arco em zonas coloridas; a agulha dá um pequeno vai e volta, gira até o valor novo e a leitura de baixo troca de texto, com a cor da zona onde a agulha parou; várias ações em sequência fazem a agulha subir e descer conforme a fala |
| `k2d_busca` | a pessoa fala o que se busca ("pesquisa como organizar as tarefas") e termina chamando para uma ação ("comenta a palavra") | uma barra de busca que digita o termo letra por letra junto com a fala, com o cursor colado na última letra; na palavra do envio a lupa dá um toque, três anéis acendem e um cartão de resultado sai de trás da barra (o título numa faixa na cor de destaque do estilo e uma linha curta embaixo); por último o selo da chamada ("Comenta [PALAVRA]") entra na palavra dita |
| `k2d_notas` | lista pontos que a pessoa vai dizendo e concluindo ("primeiro isso, depois aquilo, pronto") | um bloco de notas com título e linhas pautadas; cada item é escrito na palavra dita, da esquerda para a direita, com uma bolinha vazia; na palavra do check a bolinha vira check verde e o texto escurece; o último item pode ficar em destaque na cor do estilo; texto longo quebra e o cartão inteiro continua dentro da área |

Dois vídeos lado a lado são o bloco `comparar` (`references/enquadramento.md`), não esta cena. Volume de verdade
é o kit 3D (`references/3d.md`).

**O que a cena não prova.** O desenho conta o que a pessoa disse, não mede nada.
- `k2d_comando`: o texto digitado e o selo "pronto em minutos" não provam que a IA fez o pedido nem em quanto
  tempo. Não é uma gravação de tela. Só vale com o tempo ou o resultado que o vídeo mostra ou mede de verdade;
  sem isso, deixe `selo: null`.
- `k2d_medidor`: a posição da agulha e o texto de leitura são desenho do que foi dito, não uma medida. Valor e
  leitura só os que a fala ou um dado do projeto trazem; a cena não inventa número nem faz conta sozinha.
- `k2d_busca`: o termo digitado, o cartão de resultado e o selo da chamada são desenho do que foi dito. Não é uma
  busca de verdade e não prova que o resultado existe nem que a chamada leva a algo. `resultado` só com o título e a
  linha que a fala diz (ou `null`), e a chamada só se a pessoa de fato chamou para a ação.
- `k2d_notas`: o item escrito e o check são desenho do que foi dito. Só os itens que a pessoa fala, e o check só na
  palavra em que ela diz que concluiu; sem essa palavra, a bolinha fica aberta.

**Como usar**

1. Copie a cena para `compositions/cenas/<nome>.html` (ex.: `s04_limpeza.html`) e troque, em todo o arquivo, o
   nome da cena (`k2d_arquivo`, no template, na raiz, no `ID` e na timeline) pelo nome do arquivo, e o prefixo
   dos ids (`k2da-` no arquivo, `k2dc-` na conversa, `k2dq-` no esquema, `k2dd-` no antes e depois, `k2dm-` no comando,
   `k2dg-` no medidor, `k2db-` na busca, `k2dn-` nas notas: está no começo do arquivo) por um seu (`s04-`). A cena do kit é o modelo: não ligue ela direto no projeto.
2. Mude só o `PARAM`. Rótulo, mensagem e selo com as palavras que a pessoa disse ou mandou; número (duração,
   valor) só medido. Sem medida, deixe o campo `null` e o desenho fica qualitativo.
3. Tempo de cada ação: `em: { palavra: "cortou", padrao: 2.6 }`. Uma palavra só, procurada no trecho da cena
   sem acento e pelo começo ("cort" acha "cortou"); `depois` pula as repetições de antes; `padrao` (segundos da
   cena) vale quando a palavra some da transcrição. Com o `palavras_onda.json` na pasta `edit`
   (`helpers/palavras_na_onda.py`), o tempo da palavra que a cena recebe já é o medido na onda; sem ele é o do
   Whisper, que adianta até 0,3 s. Número direto também vale, em segundos da cena (tempo do corte menos o `de`).
4. Ligue no `projeto.json`:

   ```json
   "cenas_proprias": [
     {"arquivo": "compositions/cenas/s02_limpeza.html", "de": "eu", "ate": "porque", "nome": "Cena · arquivo limpo"},
     {"arquivo": "compositions/cenas/s05_etapas.html", "de": "primeiro", "ate": 24.4, "nome": "Cena · o que a IA fez"},
     {"arquivo": "compositions/cenas/s07_pedido.html", "de": 12.9, "ate": 21.3, "nome": "Cena · o pedido"}
   ]
   ```

   Exemplo do pedido digitado (`k2d_comando`, copiado como `s07_pedido`): a cena começa uns 1,3 s antes da palavra
   do início (a barra entra e fica parada uma pausa antes da primeira letra) e a palavra do envio fica pelo menos
   0,8 s depois da última letra digitada. No `PARAM` da cópia:

   ```js
   texto: "corta os erros e as pausas",
   inicio: { palavra: "achou" },
   fim: { palavra: "cortou" },
   envio: { palavra: "frase" },
   selo: "pronto em minutos",
   ```

   Exemplo do medidor (`k2d_medidor`, copiado como `s08_custo`): cada ação é uma palavra da fala e um valor de 0 a 1.

   ```js
   rotulo: "CUSTO",
   inicio: 0.84,
   acoes: [{ valor: 0.12, leitura: "MÍNIMO", em: { palavra: "minimo", padrao: 2.2 } }],
   ```

   Exemplo da busca (`k2d_busca`, copiado como `s09_busca`): a cena começa uns 1,3 s antes da palavra do início (a barra
   entra e fica parada uma pausa antes da primeira letra); o cartão de resultado e o selo levam uns 0,8 s cada, então a
   palavra da chamada fica pelo menos 1,5 s depois da palavra do envio. No `PARAM` da cópia:

   ```js
   termo: "como organizar as tarefas",
   inicio: { palavra: "como" },
   envio: { palavra: "resultado" },
   resultado: { titulo: "Guia passo a passo", linha: "um jeito simples de começar" },
   chamada: { texto: "Comenta GUIA", em: { palavra: "comenta" } },
   ```

   Exemplo das notas (`k2d_notas`, copiado como `s10_lista`): cada item é uma palavra falada (a escrita começa 0,1 s antes
   dela e leva 0,5 s) e o check vem pelo menos 0,5 s depois do item. Com `pausa` 0,4, deixe uns 1 s entre uma ação e a
   seguinte (escrever um item ou marcar um check). No `PARAM` da cópia:

   ```js
   titulo: "Hoje",
   itens: [
     { texto: "revisar o texto", palavra: "revisar", check: { palavra: "pronto" } },
     { texto: "ajustar as cores", palavra: "ajustar", check: { palavra: "feito" } },
     { texto: "publicar o vídeo", palavra: "publicar", destaque: true },
   ],
   ```

5. Formato: a raiz das cenas vem em 1080 x 1920. Em 16:9 troque na raiz para `data-width="1920"
   data-height="1080"` (o mesmo vale para outra proporção): o `check` acusa `a raiz da cena tem 1080 x 1920 e o
   vídeo 1920 x 1080` quando esquece, porque a cena sairia cortada.
6. `python3 build.py amostra <de> <ate>`, `python3 build.py hf lint` e `python3 build.py hf check`. O kit fala
   pelo check, como `console_warning`:
   - `uma ação entrou 0.52 s depois da palavra`: duas ações perto demais (a segunda esperou a primeira parar).
     Tire uma ação, use outra palavra ou diminua a `pausa` (não abaixo de 0,4);
   - `o esquema completo fica parado só 1.20 s no fim` ou `a última ação termina a 0.30 s do fim da cena`:
     estenda o `ate` da cena, ou use `segura_fim` quando é o fim do vídeo.
7. Estúdio e, no fim, o render com a tira de quadros a 30 qps em cada ação (`helpers/tira_de_quadros.py`):
   cada estado legível, nada pulando, o esquema completo e parado no fim.

**Onde a cena fica** (`fundo: "auto"` e `area: null` resolvem sozinhos)

- **Tela cheia:** fundo de papel quadriculado nas cores do estilo; a pessoa sai de cena e a voz continua. Com
  `legenda: true` a cena usa os 70% de cima da zona segura e a legenda da fala fica embaixo, na faixa dela. Para
  a cena ocupar a zona segura inteira: `legenda: false` na cena e `"esconde_legenda": true` no `cenas_proprias`.
- **Moldura:** com a cena dentro de um bloco `moldura`, ela fica na área livre acima do quadro da pessoa, com fundo
  transparente, e a primeira ação espera o quadro fechar. O celular e o esquema de muitas partes ficam pequenos
  ali: prefira tela cheia. Comece a cena por uma palavra, não pelo segundo exato em que a moldura acaba: no mesmo
  instante o build ainda entrega os dados da moldura e a cena fica transparente em cima do vídeo.
- **Outro lugar:** `area: [x0, y0, x1, y1]` em px e `fundo: null` ou uma cor.
- **Por cima da pessoa (o jeito normal nos anúncios):** a pessoa fala em tela cheia e a cena é um cartão pequeno
  acima da cabeça, sem fundo. Na cena (`k2d_medidor`, `k2d_comando`, `k2d_busca` e `k2d_notas`): `area: "acima_do_rosto"`.
  A área vira do topo da zona segura (mais 20 px) até 40 px abaixo do `rosto.topo` do `window.__cenas`, o fundo `"auto"`
  vira transparente e a cena se ajusta à altura que sobra (o medidor deita: arco à esquerda, texto à direita; a
  barra de comando, a busca e as notas usam a largura toda). Cena aberta sozinha, sem rosto, usa a faixa de cima da
  zona segura (25%).

  **Tamanho do cartão.** O `rosto.topo` é uma estimativa com folga: fica uns 80 a 100 px acima do cabelo de verdade (em
  alguns rostos, mais). Por isso o limite de baixo da área é `rosto.topo + 40`, e não acima dele: 40 px abaixo da
  estimativa o cartão ainda termina acima do cabelo, e a letra fica o maior possível. O cartão cresce até caber nessa
  altura, com no mínimo 200 px de altura quando há espaço; com menos de 200 px a cena avisa (abaixo) e desenha com o que
  sobra. Quanto mais itens, linhas de texto ou peças empilhadas (a busca tem barra, resultado e selo; as notas, um item
  por linha), menor fica a letra: com pouca altura, tire o título das notas ou o selo, ou use tela cheia.
  No projeto, marque a cena com `"sobre_a_pessoa": true`: a câmera viva fica em zoom 1,0 nesse trecho e não
  aproxima, senão a cabeça sobe e passa para baixo do cartão.

  ```json
  "cenas_proprias": [
    {"arquivo": "compositions/cenas/2d/k2d_comando.html", "de": "olha", "ate": "pausa", "sobre_a_pessoa": true}
  ]
  ```

  Rode `helpers/camera_viva.py` de novo depois de marcar (o `de` e o `ate` podem ser segundos ou palavra; sem `ate`
  vale até o fim). A pessoa fica na tela: o cartão não é cena de tela cheia. O que a cena avisa de fato (no
  `hf check`, como `console_warning`; o build não olha o rosto das cenas do kit):
  - `não há espaço acima do rosto (só N px livres...)`: sobram menos de 200 px. A cena desenha o cartão mesmo assim,
    com o que sobra (no mínimo 160 px), na zona segura de cima. Nesse trecho é melhor tela cheia com fundo ou
    moldura. Acontece em vídeo muito fechado no rosto e em 4:5, onde a cabeça fica perto do topo;
  - `o cartão cobre o rosto: use area: "acima_do_rosto" ou desça/suba a area`: vale com o fundo transparente e uma
    `area` escrita à mão (ou a padrão) que encosta na cabeça ou no rosto, com 20 px de folga.

  Não há aviso para a mão: olhe um quadro da amostra com a mão levantada. O topo da cabeça em `rosto.topo` é uma
  estimativa com folga (uns 80 a 100 px acima do cabelo num rosto fechado). O `"acima_do_rosto"` é só do medidor,
  do comando, da busca e das notas; o selo do `k2d_arquivo` e o celular do `k2d_conversa` aceitam só `area` em px, sem esse aviso do
  rosto: ponha a `area` à mão e olhe o quadro. Esquema de muitas partes e antes e depois ficam grandes demais: ali use tela cheia com fundo.

**O que ajustar em cada uma**

- `k2d_arquivo`: `nome` (o nome do arquivo), `falas` e `respiros` (tamanhos relativos da faixa: é desenho, não
  medida), `duracao` (`antes` e `depois`, medidos), `selo` (textos e cores) e `acoes`, na ordem da fala: `marca`
  (o que vai sair acende), `fecha` (sai e a fala se junta), `selo` (troca o estado). Dá para usar só uma ou duas.
- `k2d_conversa`: `contato` (nome neutro sem autorização), `status` do começo, `mensagens` que já estão na tela
  e `acoes`: `mensagem` (`de: "ela"` à esquerda ou `"voce"` à direita, `texto`, `digitando: true`) e `status`
  (novo texto e cor). O texto de cada balão é o do print ou o da fala, sem melhorar.
- `k2d_esquema`: `forma` (`etapas`, `grupos` ou `causa`), `titulo` (ou `null`), `partes` (rótulo de 1 a 3
  palavras, `funcao`, `em`, `seta`), `funcoes` (a cor de cada função, fixa), `exemplo` (`caminho` com os índices
  das partes, `em`, `ate` ou `aceso`), `final` (segundos parado no fim, uns 2) e `direcao` nas etapas. No
  `causa`, o efeito é a última parte (ou `efeito: <índice>`) e ganha letra maior.
- `k2d_antes_depois`: `tipo` (`faixa` ou `imagem`), `antes` e `depois` (`rotulo` literal, `detalhe`, `valor`
  medido, `em`, e `trechos` na faixa ou `arquivo` na imagem), `proporcao` das imagens (as duas iguais) e
  `diferenca` (`em`; na imagem, `caixa` de 0 a 1 para o anel).
- `k2d_comando`: `texto` (o pedido, do jeito que a pessoa falou), `inicio` e `fim` (as palavras faladas em que a
  digitação começa e termina; sem `fim`, ela vai até a palavra do envio), `envio` (a palavra em que o botão envia
  e o selo entra; `null` envia logo depois da última letra), `selo` (o resultado, ou `null` sem selo),
  `rotulo_topo` (o rótulo pequeno em cima, `null` sem rótulo) e `icone` (uma letra ou símbolo simples no círculo;
  `""` círculo liso, `null` sem círculo). Cada palavra do texto cai dentro da palavra falada que a chama; com
  mais palavras no texto do que faladas, elas dividem o tempo da falada. Texto longo quebra em até 4 linhas.
- `k2d_medidor`: `rotulo` (o texto do topo), `zonas` (o arco da esquerda para a direita: cada zona vai até `ate`,
  de 0 a 1, com `cor` do estilo ou `#rrggbb`), `inicio` (onde a agulha está quando o medidor aparece), `leitura`
  (texto já na tela no começo, ou `null`), `selo` (`{ texto, cor, em }` depois da última ação, ou `null`) e
  `acoes`, na ordem da fala: `valor` (0 a 1), `leitura` (o texto de baixo, com a cor da zona onde a agulha para)
  e `em` (a palavra). O arco e o cartão nunca mudam de desenho nem de lugar: só a agulha e a leitura.
- `k2d_busca`: `termo` (o que a barra digita, do jeito que a pessoa falou), `inicio` (a palavra falada em que a 1ª letra
  aparece; a digitação vai até a palavra do envio, no máximo uma palavra falada por palavra do termo), `envio` (a
  palavra em que a lupa dá o toque e o cartão de resultado sai de trás da barra; `null` envia logo depois da última
  letra), `resultado` (`{ titulo, linha }`: o título vai na faixa de destaque, `linha: null` deixa só o título,
  `resultado: null` tira o cartão) e `chamada` (`{ texto, em }`: o selo, "Comenta [PALAVRA]" é o padrão, `em` é a
  palavra falada em que ele entra; pode ser só o texto, e então ele entra na primeira palavra do texto; `null` sem
  selo). Termo comprido quebra em até 2 linhas e a barra já nasce com a altura das linhas que o termo faz.
- `k2d_notas`: `titulo` (o título do bloco, ou `null` para o cartão ficar menor e a letra maior) e `itens`, na ordem
  da fala: `texto` (o que é escrito; quebra em mais linhas se for longo), `palavra` (a palavra em que ele é escrito, da
  esquerda para a direita), `check` (`{ palavra }`: a palavra em que a bolinha vira check verde; sem `check` a bolinha
  fica aberta; `true` marca logo depois de escrito) e `destaque: true` (pinta a linha na cor de destaque do estilo,
  em geral só a do último item). Um check nunca vem antes do item estar escrito.

**Som:** as cenas não entram no `sons_sugeridos.json`. No `eventos.json` do projeto, cada ação vai no tempo da
palavra dela somado ao `de` da cena (mais o atraso, quando o check avisou): objeto ou parte que entra `pop`,
respiro ou diferença que acende `risco`, faixa que fecha `whoosh`, selo ou status que muda `sucesso`, balão novo
`pop` (o primeiro, `ding`), seta `clique`, toque do botão de enviar ou da lupa `clique`, agulha que gira `whoosh` curto e
leitura nova `pop`, resultado da busca que sai de trás da barra `pop`, selo da chamada `ding`, item escrito `pop` e check
`sucesso`. Letra digitada não leva som: seriam dezenas de sons por frase.

## Cena própria (sub-composição)

Quando a relação pede algo que o catálogo e os kits não têm (um objeto que muda de estado de outro jeito, um
diagrama com outra forma, um 3D fora das cenas do kit), você escreve uma sub-composição HyperFrames e liga no
projeto pelo campo `cenas_proprias` do `projeto.json` (campos no `LEIA.md` do modelo-projeto). A regra do HyperFrames está na skill `hyperframes-core`
(`references/sub-compositions.md`). O essencial:

- Um arquivo em `compositions/`, com tudo dentro do `<template>`: estilo, HTML e script. O que fica fora do
  `<template>` é descartado.
- A raiz tem `data-composition-id` igual ao do projeto, e o tamanho do vídeo (1080 x 1920 ou 1920 x 1080).
  Estilo pela raiz com `#id`, nunca por classe.
- Uma timeline `gsap.timeline({ paused: true })`, registrada em `window.__timelines["<id>"]` só DEPOIS de
  montada.
- Todo estado é função do tempo. Nada de animação ou transição CSS, `setTimeout`, `requestAnimationFrame`,
  `Date.now()` ou `Math.random()` sem semente. Nada que dependa de os quadros anteriores terem tocado. Assim o
  estúdio e o render mostram a mesma coisa.
- Fontes em arquivo com `@font-face` dentro do `<template>` (as do modelo estão em `assets/fontes/`).
- Tempo pela palavra: pegue com `build.py palavras` e escreva os tempos relativos ao início da cena.
- Fora do rosto e dentro da zona segura, igual às peças do catálogo.
- `python3 build.py hf lint` e `hf check` sem erro antes de abrir no estúdio.
- A lista `palavras` de `window.__cenas` pode mudar quando o corte é conferido de novo (o Whisper junta ou
  separa palavras). Procure pela palavra, nunca pela posição, e deixe o desenho aguentar uma palavra a mais.
- Na moldura, o primeiro elemento entra depois de `window.__cenas[...].moldura.fechada_em`.
- Pegadinhas que o `check` pega e o olho não: espaço entre palavras em spans separados some (use margem em
  px), risco por cima do texto reprova (`text_occluded`: ponha o risco por baixo das letras) e dois textos se
  cruzando numa troca de estado reprovam (`content_overlap`: o velho sai antes do novo entrar). O código certo
  está no `LEIA.md` de `compositions/cenas/`.
- O estúdio carimba `data-hf-id` nos elementos da cena quando abre o projeto: leia o arquivo de novo antes de
  editar e não conte com o texto exato das tags.

## Pegadinhas (as que já custaram retrabalho)

Resumo. O porquê e o código certo estão no fim do `references/animacao-catalogo.md`.

- Nenhum tween em tempo negativo: um só em -0,05 empurra a timeline inteira 0,05 s e tudo fica atrasado.
- Texto que muda (`textContent`) nunca nasce vazio no HTML: set que parte de "" não volta no seek.
- Número com zero na frente ('01') vira 1 no GSAP: prefixe com o espaço de largura zero (`​`).
- Estado do quadro 0 com `fromTo` curto, não com `tl.set(..., 0)`.
- Depois do primeiro tween de um elemento, `immediateRender: false` em todos.
- Mova com `x`, `y`, `scale` e `clip-path`; nunca anime `left`, `top`, `width`, `height`.
- Fonte sempre em arquivo com `@font-face` (inclusive a mono do painel): fonte do sistema não carrega no
  navegador do render.
- Texto solto dentro de caixa `flex` perde o espaço antes do destaque: envolva num `<span>`.
- Cada `<audio>` com `id` e `data-track-index` próprios.
- Com `data-automation` de volume, o `data-volume` é ignorado: o ganho vai nos pontos da curva.
- Espaço entre palavras em elementos separados some: o HyperFrames descarta o texto que é só espaço entre dois
  elementos. Use `margin-left` em px (em `em`, num span sem `font-size`, mede pelos 16 px da raiz).
- Risco em cima de texto reprova o `check` (`text_occluded`); o risco vai por baixo das letras.
- Troca de estado com os dois textos cruzando reprova (`content_overlap`): o velho sai antes do novo entrar.
- Peça que entra enquanto a moldura fecha passa na frente do rosto: o quadro vence (o build empurra a peça).
- Em cena própria, prefira entrar com deslocamento, opacidade e `clip-path`. Depois de uma animação de escala
  (`scale`, `scaleX`) o Chrome segura por um tempo o desenho feito na escala antiga, e com a máquina ocupada dois
  renders do mesmo projeto saem com bordas diferentes. Medido no kit 2D: com escala, de 56 a 449 quadros
  diferentes entre dois renders; sem escala, nenhum em três renders. O kit também usa sombra dura, sem desfoque,
  como o kit 3D.

## Erros comuns

- Animar tudo o que a pessoa fala (vira ruído) ou enfeitar sem motivo.
- Cartões aparecendo e sumindo onde a fala descreve uma transformação.
- Diagrama que se reorganiza a cada elemento novo, ou um segundo diagrama no exemplo.
- Peça grande em tela cheia em cima do rosto: mude o trecho para moldura.
- Usar tempo do vídeo bruto em vez do tempo do corte.
- Desenhar um resultado, um número ou uma tela que não existe no material.
- Chamar de 3D o que é camada plana inclinada.
- Conferir só quadros parados, ou só o estúdio sem o arquivo exportado.
