# Enquadramento: pessoa, moldura, tela verde e planos

Você decide, trecho por trecho, como a pessoa aparece e quanto espaço ela divide com o que está sendo
explicado. O `build.py` do projeto-modelo faz a conta do enquadramento pelo rosto medido, anima a troca e põe a
legenda e as peças fora do rosto. O vídeo continua sendo o `cut.mp4` do corte; a voz nunca para.

## Como falar com a pessoa

- Português simples, frases curtas. Nada de código, JSON ou caminho comprido na conversa.
- Conte o plano em palavras do dia a dia, com o tempo em 00:12: "De 00:00 a 00:21 você em tela cheia. Em
  00:22 você vai para um quadrinho embaixo e a lista aparece em cima. Em 00:28 volta pra tela cheia."
- Autorização em camadas: se a pessoa já autorizou fazer tudo, conte e siga; se pediu para aprovar antes,
  espere. O teste de recorte é a exceção (seção "Portão do recorte").
- Uma decisão por vez. Se ela disser "decide você", decida e conte em uma linha.

## Antes de começar

Precisa existir, na pasta `edit` do corte (`<EDIT>`): `cut.mp4` aprovado, `cut_timeline.json`,
`transcripts/cut.json` (a transcrição do corte) e `face_layout.json`. Se faltar o `face_layout.json`:

`uv run --directory "<SKILL>" python helpers/face_layout.py --edit-dir '<EDIT>'`

(`<SKILL>` é a pasta desta skill.)

O projeto HyperFrames é uma cópia da pasta `modelo-projeto` desta skill (`<SKILL>/modelo-projeto`), feita
pelo próprio modelo, perto dos vídeos:

`python3 '<SKILL>/modelo-projeto/build.py' novo '<VIDEOS>/sala' --edit '<EDIT>'`

Ele anota no `projeto.json` a skill de onde o projeto veio (`"skill"`) e a pasta `edit`; as ferramentas do
projeto (recorte da pessoa, mãos) usam essa skill, e não outra instalada no computador. Nunca edite o modelo
original. O `LEIA.md` do modelo tem os campos.

## Primeiro, assista o trecho tocando

Um quadro solto não diz se o enquadramento aguenta a fala inteira. Antes de decidir, toque o trecho e procure:

- o ponto em que a cabeça mais tomba ou mais se afasta do centro;
- o gesto mais largo (mão que sai para o lado, objeto levantado);
- as trocas de tomada (o rosto muda de lugar em cada uma).

Depois marque as **regiões obrigatórias** de cada trecho: a cabeça inteira e o rosto, sempre; as mãos, o
objeto mostrado ou a postura, quando carregam informação ("olha esse pote", mão contando nos dedos, o celular
virado para a câmera). Nenhum recorte, moldura ou peça pode cortar uma região obrigatória.

O build ajuda a conferir: nos blocos com `"acompanhar": true` ele avisa quando a cabeça sai do quadro; com o
`assets/maos.json` (`ferramentas/rastrear_maos.py` do projeto) ele avisa, com o intervalo, quando uma mão que a
gravação mostra sai do quadro da moldura ou da tela por 0,2 s ou mais. O aviso não sabe se a mão mostra algo:
decida você (se mostra, aumente o quadro, diminua o zoom, use tela cheia ou `contida`).

O meio do quadro não é, necessariamente, onde a pessoa está. Mire o rosto no centro da área disponível, sem
perseguir cada micromovimento.

## Os jeitos de mostrar a pessoa

| cena | o que aparece | quando usar |
|---|---|---|
| `tela_cheia` | a pessoa ocupando a tela, zoom leve (1,08 a 1,12) com o rosto centralizado | gancho, opinião, história, desejo, chamada, demonstração feita com o corpo. O rosto vende. |
| `prova` | a prova em tela cheia: a própria gravação da tela (sem zoom) ou um print/vídeo (`arquivo`, a partir do segundo `inicio`), com rótulo em cima e zoom que anda até o que importa | tela do app, iPad, painel, página, print. É a prova real. |
| `moldura` | a pessoa num quadro arredondado embaixo e o papel quadriculado atrás (ou o próprio vídeo desfocado, `"fundo": "desfocado"`); a animação ocupa o alto | explicação que divide a tela: lista, passos, causa e efeito, diagrama, celular com notificação |
| `tela_verde` | a pessoa recortada num canto, com contorno branco, na frente de uma imagem ou vídeo (`fundo`) | comentário sobre algo que precisa ficar grande atrás dela: notícia, página, vídeo, produto |
| planos (2,5D) | a pessoa recortada no meio, uma palavra em parte atrás do corpo, um objeto à frente | palavra forte, lançamento, autoridade, explicação curta. Só com o teste de recorte aprovado. Seção "Composição em planos" |
| `contida` | a gravação inteira dentro da tela, com margem, sobre ela mesma desfocada (ou o papel, ou uma cor) | quando a região obrigatória não cabe no recorte (seção "Quando não cabe"), gravação em pé num 16:9, 4:5 ou 1:1 |
| `comparar` | dois arquivos (ou dois trechos) lado a lado ou alternando, na mesma escala e na mesma velocidade, com rótulos literais | antes e depois honesto, duas versões, duas soluções (seção "Comparar") |

## Regras de decisão

Tiradas das edições aprovadas. Siga na ordem.

1. **Comece em tela cheia.** Gancho e chamada ficam em tela cheia. O rosto prende e convence. Todo efeito
   começa e termina com a gravação cheia na tela.
2. **Prova real em tela cheia, com rótulo em cima.** Se a gravação mostra a tela do app ou o iPad, esse
   trecho é `prova` sem zoom: a prova aparece inteira. Print ou vídeo de tela da pessoa entra como `prova` com
   `arquivo`. O rótulo diz o que é ("Tela do app", "Pedido real"), curto. Painel pequeno e ilegível não
   prova nada: se a prova não se lê no celular, ela precisa de mais área.
3. **Moldura só quando a câmera volta pro rosto.** Moldura em cima da prova esconde a prova. Ela entra quando
   a pessoa volta a falar para a câmera e a explicação precisa de espaço.
4. **Quando encolher as duas coisas deixa tudo ilegível, a demonstração fica com a tela toda** e a voz conduz.
   A pessoa volta depois.
5. **A moldura entra e sai no corte.** O `build.py` encosta a borda do bloco no corte mais perto (até 0,35 s) e
   avisa. A troca no corte some no salto da imagem. Se não tem corte perto, a saída volta animando em 0,55 s.
6. **Moldura de 4 a 12 s.** Mais que isso cansa. Nada de moldura decorativa o vídeo inteiro, nem pessoa pequena
   num canto por padrão. Divida com um trecho de tela cheia no meio.
7. **Na moldura a legenda sai.** Quem explica ali é a animação. A legenda volta quando volta a tela cheia.
   (Dá para ligar com `"legenda": {"na_moldura": true}`, mas só faça se a pessoa pedir.)
8. **Tudo que está na moldura sai antes dela acabar.** O `build.py` corta a saída das peças 0,1 s antes do fim
   do bloco e avisa.
9. **Depois de cada inserção, volte à câmera com continuidade.** Mesmo lado, mesmo tamanho de rosto de antes.
10. **Tela verde é para o assunto ficar grande.** Pessoa comentando uma notícia, uma página, um vídeo de outra
    pessoa, um produto. Se a gravação já mostra a tela, não precisa. É uma coisa ou outra no mesmo trecho:
    nunca moldura e tela verde juntas.
11. **Dado privado não aparece.** Nome e telefone de cliente, e-mail, senha, chave, número de pedido de outra
    pessoa, conversa, nome de projeto na barra lateral: vai com `borrar`, com o tempo de cada caixa. O borrão é
    queimado no arquivo (seção "Borrão"), então nem quem recebe a pasta do projeto vê o dado.
12. **Rosto livre.** Nada cobre olhos e boca. A legenda fica no peito, a peça pequena em cima da cabeça, a peça
    grande na área livre da moldura. Legenda, informação e rosto em áreas separadas.
13. **Zona segura do Reels.** No 9:16, texto entre y 230 e 1530 e entre x 140 e 940 (a barra do topo, o botão
    do anúncio e a coluna de curtir cobrem o resto). O modelo já respeita.
14. **Moldura separa, não deforma.** Contorno, sombra e uma leve inclinação separam planos. Nunca esticar,
    espremer ou entortar a pessoa. Nada de zoom que não para nem reenquadramento agitado só para ocupar tempo.
15. **Visual.** `papelaria` é o padrão do modelo (no modo automático a skill usa `laranja`): papel quadriculado lilás, cartões brancos com base lilás, Montserrat 900
    e Caveat à mão. `noite` para marca escura (azul-marinho com pontinhos, cartões brancos). `laranja` para o visual escuro dos
    vídeos do André (fundo quase preto com grade e brilho laranja, cartões escuros com fio laranja, texto claro).

Quando uma animação grande (lista, passo a passo, diagrama, celular, fotos) cair num trecho de tela cheia e o
`build.py` avisar que não coube sem encostar no rosto, transforme esse trecho em moldura.

## No projeto.json

```json
"blocos": [
  {"cena": "tela_cheia", "de": 0, "ate": 14.4, "zoom": 1.1},
  {"cena": "prova", "de": 14.4, "ate": 18.3, "rotulo": "Tela do *app*"},
  {"cena": "moldura", "de": 18.3, "ate": 28.03},
  {"cena": "tela_verde", "de": 28.03, "ate": 32.3, "fundo": "assets/pagina.png", "posicao": "direita"},
  {"cena": "tela_cheia", "de": 32.3}
]
```

- `de` e `ate` em segundos do `cut.mp4` (ou a palavra, como nas animações). Buraco entre blocos vira tela cheia.
- `tela_cheia`: `zoom` (1,08 a 1,12), `zooms` (seção "Zoom na palavra"), `borrar`, `acompanhar` (seção
  "Acompanhar a pessoa dentro da tomada").
- `prova`: `arquivo` (imagem ou vídeo em `assets/`), `inicio` (o segundo do vídeo em que a prova começa; sem
  ele, do 0), `encaixe` (`cobrir` enche a tela; `inteiro` mostra tudo por cima de uma cópia borrada), `rotulo`,
  `borrar` (seção "Borrão"), `zoom` (padrão 1, a prova inteira), `zooms`. A entrada da prova é um corte seco:
  o `sons_sugeridos.json` pede um whoosh com o pico no quadro do corte, e o rótulo entra 0,62 s depois.
- `moldura`: `fundo` (`papel`, o padrão, ou `desfocado`: o próprio vídeo, desfocado e escurecido, atrás do
  quadro). A caixa padrão é x 520, y 980, 400 x 540 no 9:16 e x 1080, y 120, 720 x 840 no 16:9.
  Para mudar em todo o vídeo: `"moldura": {"caixa": [x, y, largura, altura]}` no topo do projeto. `acompanhar`
  também vale aqui.
- `contida`: `fundo` (`desfocado`, o padrão; `papel`; ou uma cor, `"#1b1830"`), `margem` (px, padrão 6% do lado
  menor), `raio`. Entra e sai no corte como a moldura.
- `comparar`: `a` e `b` (`arquivo`, `inicio`, `rotulo`), `modo`, `trocas`, `som` (seção "Comparar").
- `tela_verde`: `fundo` (imagem ou vídeo), `inicio` (do vídeo de fundo), `encaixe`, `posicao` (`direita`,
  `esquerda`, `centro`), `altura` (0,62 no canto e 0,8 no centro, fração da tela), `contorno` (`true`).
- `legenda` (`true` ou `false`) em qualquer bloco força ligar ou desligar a legenda ali. Desligada num bloco, a
  palavra que começa até 0,3 s antes dele também sai (não pisca antes da troca); a primeira palavra do bloco
  seguinte tem legenda normal.
- Os campos da composição em planos e das cenas próprias estão no `LEIA.md` do modelo-projeto.

## Zoom na palavra e zoom que anda até um ponto

Nos blocos `tela_cheia` e `prova`, `zooms` é uma lista; cada zoom entra numa palavra e volta no `ate`:

```json
{"cena": "prova", "de": 12.3, "ate": 19.8,
 "zooms": [{"em": "botão", "caixa": [0.52, 0.61, 0.30, 0.08], "ate": "clicou"},
           {"em": "resultado", "caixa": [0.1, 0.3, 0.8, 0.3], "duracao": 0.6}]},
{"cena": "tela_cheia", "de": 19.8, "zooms": [{"em": "nunca", "escala": 1.3, "ate": "vendi"}]}
```

- `caixa` `[x, y, largura, altura]` em fração do vídeo gravado (o `cut.mp4`, de 0 a 1; na prova com `arquivo`,
  do arquivo): a câmera anda até ela e a enquadra com uma folga (o "zoom no botão" da tela gravada). Olhe um
  quadro para achar a caixa. `escala` troca o quanto aproxima.
- Sem `caixa`: punch-in no rosto, com `escala` (padrão 1,3), em 0,2 s. Com `caixa`, o zoom anda em 0,45 s
  (`duracao`). A volta leva `duracao_volta` (padrão igual, no mínimo 0,35 s).
- `em` e `ate` em segundos ou a palavra. Sem `ate`, o zoom fica até o fim do bloco. Um zoom que começa antes
  do anterior voltar vai direto de um ponto ao outro.
- Corte no meio do zoom continua com o zoom (no rosto, o da tomada nova). As peças e a legenda desviam do rosto
  do jeito que ele está na tela, já com o zoom.
- Cada zoom pede um som (whoosh, no meio do movimento) no `sons_sugeridos.json`; `"som": false` tira.

## Borrão (dado privado)

`borrar` vale em qualquer bloco. Cada caixa é `[x, y, largura, altura]` (o bloco inteiro) ou tem o tempo
dela:

```json
"borrar": [[0.02, 0.10, 0.18, 0.80],
           {"caixa": [0.30, 0.05, 0.40, 0.04], "de": 14.2, "ate": "projeto"}]
```

- A caixa é em fração do vídeo gravado (o `cut.mp4`; na prova com `arquivo`, do arquivo), de 0 a 1. Não é
  fração da tela: por isso o borrão acompanha o zoom e a moldura sem conta nenhuma.
- O borrão é **queimado no arquivo**: o build grava o `assets/cut.mp4` do projeto com as caixas borradas (o
  original sem borrão fica no `edit/`). A prévia, o render e quem receber a pasta do projeto só veem o borrão.
  Na prova com `arquivo`, a página usa uma cópia borrada em `assets/gerado/` e o build avisa que o original
  continua em `assets/`: tire o original da pasta antes de mandar o projeto para alguém.
- Cada caixa entra um quadro antes do `de` e sai um quadro depois do `ate`. Numa imagem, o borrão vale o bloco
  todo.
- Coisas que aparecem e somem (um menu que abre, uma linha que muda de lugar) pedem uma caixa com o tempo de
  cada uma. Confira no arquivo exportado, quadro a quadro nos trechos de tela, com a conferência de dado pessoal
  de `references/revisao.md`: a folha de quadros sozinha deixa passar.

Detalhes da conta e do código: seção "Receitas", no fim desta página.

## Acompanhar a pessoa dentro da tomada

O `face_layout.json` mede o rosto por tomada: dentro de uma tomada o enquadramento fica parado. Quase sempre
basta. Não basta quando a pessoa anda, se inclina muito ou muda de lugar no meio da tomada, e o trecho está com
zoom (moldura, tela cheia a 1,15 ou mais, um punch-in): aí o rosto escorrega para a borda ou a testa é cortada.

Nesse trecho, ponha `"acompanhar": true` no bloco (vale em `tela_cheia` e `moldura`):

```json
{"cena": "moldura", "de": 7.07, "ate": 10.6, "acompanhar": true},
{"cena": "tela_cheia", "de": 14.0, "ate": 17.7, "zoom": 1.2, "acompanhar": true,
 "zooms": [{"em": "ééé", "escala": 1.35, "ate": "cortou"}]}
```

O que o build faz:

1. **Mede o rosto 10 vezes por segundo** no `cut.mp4`, com o detector YuNet da skill (o mesmo do
   `face_layout.py`), pelo `helpers/rastrear_rosto.py`, com o Python da skill. Grava `<EDIT>/rosto_trilha.json`,
   preso ao tempo do `cut.mp4`: refez o corte, ele mede de novo sozinho. Uns segundos por minuto de vídeo. À mão:
   `uv run --directory "<SKILL>" python helpers/rastrear_rosto.py '<EDIT>'`.
2. **Suaviza.** Mediana de 5 medidas seguidas. Zona morta: o enquadramento só se mexe quando o centro anda mais de
   3% da largura (ou o rosto muda mais de 12% de tamanho). Cada mudança vira um movimento de 0,5 s em
   `sine.inOut`, centrado nela: o caminho do rosto na tela é contínuo, sem pulo.
3. **Perdeu o rosto** (mão na frente, virou de lado): segura o último ponto bom. Depois de uma perda de 0,3 s ou
   mais, a medida nova só vale quando 2 das 3 seguintes também acham o rosto. Nunca salta para o meio da tela.
4. **Recomeça em cada tomada** do `cut_timeline.json`. Tomada sem rosto nenhum fica com o enquadramento dela (o
   build avisa).
5. **Anima quadro a quadro**, com a conta da Receita 2 em cada quadro, fora das transições animadas (dados e laço:
   o seek em qualquer ponto acerta). A pessoa recortada (`assets/pessoa.webm`) recebe a mesma transformação, e a
   transição da moldura já termina no rosto acompanhado. Na moldura o tamanho do rosto é o mediano da tomada (o
   quadro não "respira").
6. **Confere a cabeça** (rosto e cabelo) dentro do quadro, 10 vezes por segundo. Quando a pessoa vai para a borda
   da gravação e o enquadramento não tem mais para onde ir, o build avisa com o intervalo: não cabe. Diminua o
   zoom, troque para tela cheia ou use `contida` nesse trecho.

Em tela cheia a 1,08 sobra só 8% de margem: o acompanhamento aparece com zoom maior ou num punch-in. Numa cena
própria, use o mesmo `rosto_trilha.json` (`tomadas[].pontos`: `[t, cx, cy, largura, altura, medido]`, frações do
`cut.mp4`) e anime a caixa em volta do vídeo, nunca o `<video>`.

**Quando a janela muda de tamanho, lugar ou proporção**, o enquadramento de dentro é recalculado junto com a caixa
de fora, na mesma curva. Se só a caixa anda, o rosto desliza para fora do lugar ou a testa some no meio da troca. O
modelo já faz isso na moldura e na contida; numa cena própria, faça igual.

## Quando não cabe

Às vezes nenhuma posição mostra a região obrigatória inteira (gesto muito largo, pessoa filmada de lado, vídeo
horizontal indo para 9:16). Não force. Na ordem:

1. Diminua o zoom (o mínimo é o que enche a tela sem borda).
2. Mude o destino: tela cheia no lugar da moldura, moldura maior, outro lado.
3. Mostre a imagem inteira contida, com margem e um fundo de apoio: o bloco `{"cena": "contida"}` (a própria
   gravação desfocada atrás, o padrão; `"fundo": "papel"` ou uma cor).

**Vídeo gravado em pé que vai sair em 16:9** é o caso mais comum de "não cabe": o corte guarda só uma faixa da
altura (uns 32%) e amplia; a pessoa aparece em close, só a cabeça, e na moldura 16:9 ainda mais perto. O
`build.py` avisa. Antes de montar, proponha o 9:16; se o 16:9 for obrigatório, use a `contida` (item 3) nos
trechos em que o corpo ou as mãos importam. O build enquadra o rosto pelo retângulo que o vídeo ocupa de verdade
dentro da tela (um corte em pé num 16:9, 4:5 ou 1:1 passa da tela em cima e embaixo), então o rosto não se perde. Na moldura 16:9 a legenda (quando ligada com `na_moldura`) fica na
área livre ao lado do quadro, sem atravessar a borda dele.

Nunca esprema a largura da pessoa para caber. Nunca deixe faixa vazia ou preta fora da imagem.

A conta para encher a tela sem distorcer: fonte com W x H, alvo com w x h. O fator é
`k = max(w / W, h / H)`. Recorte na fonte uma janela de `w / k` por `h / k`, centrada na região obrigatória e sem
passar das bordas do vídeo original. Se a janela está se mexendo, faça a conta de novo em todo quadro.

## Composição em planos (2,5D)

Dá presença a uma palavra ou a um objeto em volta da pessoa. É o efeito que mais parece "edição cara", e o que
mais fica feio quando o recorte não aguenta. Só entra com o teste de recorte aprovado (próxima seção).

A peça pronta do texto atrás da pessoa está no `references/animacao-catalogo.md`. Aqui ficam as decisões.

- **Três planos.** Fundo: o cenário original, ou um cenário calmo. Meio: a pessoa, que é o destaque. Frente: um
  elemento de apoio, que só entra na hora em que serve.
- **A palavra atrás do corpo tem que ser lida.** Pode ficar em parte escondida pela pessoa, desde que sobrem
  letras à vista para reconstruir a palavra sem esforço (a primeira letra sempre à vista e mais da metade das
  letras inteiras). Se o corpo cobre demais quando ela se mexe, suba, desça ou troque o lado da palavra.
- **O objeto fica perto do que está sendo falado**, sem tampar olhos, boca e gestos: é o campo `frente` da peça
  (`references/animacao-catalogo.md`, peça 10), num canto de baixo, do lado oposto ao rosto; o build avisa se ele
  passar na frente do rosto.
- **Cada plano anda um pouco e numa medida diferente**, para revelar a profundidade: o de trás anda menos, o da
  frente anda mais. A peça `atras_da_pessoa` já faz: o fundo (a gravação, com a pessoa junto, porque saem do mesmo
  vídeo) se aproxima 1,5% e desliza 6 px, a palavra desliza 36 px e a `frente` (o objeto na frente da pessoa) 80 px,
  crescendo 4%. Sombras coerentes com a luz da gravação.
- **Cada elemento entra numa palavra**, e só um por vez. Passada a ênfase, tudo sai e a câmera original volta.
  Nada de pessoa recortada o vídeo inteiro.
- **Legenda numa faixa própria**, longe da palavra grande e da interface do Reels. Onde a palavra escreve a
  fala, a legenda sai.
- **Sem recorte utilizável:** componha nas áreas livres ao lado da pessoa e não prometa texto atrás do corpo.
- **Nome certo na entrega:** "composição 2,5D em camadas". Não é 3D.

Na amostra, mostre o efeito entrando, a pessoa se movendo com ele na tela e o efeito saindo. No arquivo exportado,
confira a borda do recorte, o sincronismo com a fala e se a pessoa continua no centro.

## Portão do recorte (teste de uns 5 s)

Recortar a pessoa do fundo é caro e pode falhar no cabelo, nos dedos e no movimento. Antes de rodar o recorte
num trecho longo, de trocar o cenário sem contorno ou de pôr qualquer coisa atrás da pessoa, faça um teste curto
e mostre. Este é um ponto em que você para e espera o ok mesmo com o resto autorizado. Só siga sem mostrar se a
pessoa disse com todas as letras que não quer ver o teste; mesmo assim ele roda e você confere pelos critérios.

Tela verde curta com o contorno branco aprovado: o próprio trecho é o teste. Confira pelos critérios e siga.

1. **Confira se o recorte roda neste computador** antes de prometer:
   `uv run --directory "<SKILL>" python helpers/matte.py --check`. Falhou: diga o que falta. Nada de serviço
   pago, envio do vídeo para fora ou modelo baixado sem a pessoa autorizar.
2. **Escolha uns 5 s difíceis**: cabelo solto contra o fundo, mãos se mexendo, a pessoa se movendo e, se houver,
   um objeto cruzando na frente dela.
3. **Recorte só esse trecho**, no tamanho de entrega e pelo mesmo caminho do final:
   `python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 12.0 --ate 17.0`
4. **Olhe a borda, não só se o fundo sumiu.** Monte a pessoa em cima de um fundo branco, de um preto e da camada
   que vai passar por trás. Para os dois primeiros:

   ```bash
   ffmpeg -f lavfi -i color=white:s=1080x1920:d=5 -f lavfi -i color=black:s=1080x1920:d=5 \
     -c:v libvpx-vp9 -i assets/pessoa.webm \
     -filter_complex "[2:v]split[p1][p2];[0:v][p1]overlay=shortest=1[a];[1:v][p2]overlay=shortest=1[b];[a][b]hstack" \
     -c:v libx264 -pix_fmt yuv420p quadros/teste_recorte.mp4
   ```

   A terceira é a própria amostra no estúdio. Toque as três em velocidade normal e depois quadro a quadro
   (`helpers/tira_de_quadros.py --fps 30`).
5. **Critérios.** Cabelo e dedos presentes. Ombros sem encolher nem sumir. Nenhum buraco no rosto ou no corpo.
   Sem borda dupla e sem pedaço do fundo antigo grudado. O contorno fica firme: não pulsa e não deixa rastro
   quando ela se mexe. O texto de trás desaparece atrás do corpo e volta a aparecer onde é fundo. Borda com a suavidade da imagem, sem aura clara.
6. **Confira a transparência abrindo o arquivo de verdade.** Nem o nome do codec nem o que o tocador mostra provam
   que ela existe. O
   ffmpeg só lê o alfa do VP9 com o decodificador `libvpx-vp9` pedido antes do `-i`; sem ele, o alfa sai cheio
   e parece que não tem transparência:

   ```bash
   ffmpeg -hide_banner -ss 2 -c:v libvpx-vp9 -i assets/pessoa.webm -frames:v 1 \
     -vf "alphaextract,signalstats,metadata=print:key=lavfi.signalstats.YMIN,metadata=print:key=lavfi.signalstats.YMAX" \
     -f null - 2>&1 | grep signalstats
   ```

   Tem que sair `YMIN=0` e `YMAX=255`: partes transparentes e partes cheias. Erro "Requested planes not
   available" quer dizer que o arquivo não tem canal de transparência.
7. **Mostre o teste**, com o que ele tem de limite, e espere.

**Não passou:** tente uma correção localizada e explique o motivo (recortar de novo o trecho, outro lado, outro
trecho de 5 s). Se continuar ruim, descarte o efeito para aquela composição, diga o limite e proponha a moldura
com o fundo original ou uma regravação (fundo liso e sem nada parecido com a pele ou o cabelo, luz de frente).
Nunca disfarce com brilho, desfoque pesado ou um retângulo por cima. Recorte exigido e impossível: diga, dê a
alternativa e não dê a tarefa como feita.

**Passou:** recorte o resto e reaproveite. O recorte fica guardado em `<EDIT>/renders/matte` e o
`assets/pessoa.json` diz que trecho ele cobre. Mudar só texto ou posição não pede recorte novo. Guarde a cópia
com transparência (`pessoa.webm`) separada da peça final já montada.

Três coisas diferentes, que só se trocam montando de novo: um vídeo que já tem a transparência dentro (o
`pessoa.webm`), uma pasta de imagens PNG transparentes e um vídeo preto e branco que serve de máscara. MP4 comum (H.264) não guarda transparência. Máscara
geométrica (retângulo, oval) não é recorte de fundo, e você não chama de recorte.

## Comparar (antes e depois)

Mostra uma diferença de verdade, sem truque de montagem:

```json
{"cena": "comparar", "de": 10.6, "ate": 14.0, "modo": "alternando", "trocas": ["palavra"], "som": "igualado",
 "a": {"arquivo": "assets/cru.mp4", "inicio": 15.0, "rotulo": "Gravação crua"},
 "b": {"arquivo": "corte", "inicio": 10.6, "rotulo": "Corte da skill"}}
```

- **A mesma situação dos dois lados.** Antes de montar, confira que os dois pedaços mostram o mesmo momento; se não
  mostram, diga e não monte como confronto. Dois trechos do mesmo arquivo (`inicio` diferente) ou do próprio corte
  (`"arquivo": "corte"`) também valem.
- **Mesma escala e mesma velocidade.** Os dois aparecem inteiros, do mesmo tamanho, tocando juntos. Proporção ou
  resolução diferente vem do arquivo, e o build avisa (nada é esticado nem piorado de propósito).
- **`modo`**: `lado_a_lado` (em linha ou empilhado, o que deixar a imagem maior; pode passar da zona segura dos
  lados, porque não é texto) ou `alternando` (no mesmo lugar, trocando nas `trocas`, pelo menos 0,8 s cada).
- **Rótulo literal**, obrigatório: o que o lado é, sem opinião. "Melhor", "perfeito", "ruim" geram aviso.
- **Som**: `voz` (o padrão: a fala continua, os lados mudos); `a` ou `b` (só aquele lado; a voz do corte sai do
  trecho e o build avisa a fala que fica muda: deixe esse espaço no corte); `igualado` (alternando: o som do lado
  que está na tela, os dois no mesmo volume percebido, medido; o mais alto desce, nenhum sobe).
- A legenda sai no bloco. Não ponha texto por cima do detalhe que se compara.
- Na entrega, diga o que a comparação mostra e o que ela não prova.

## Mudar o formato de uma edição aprovada

Levar um vídeo aprovado de 9:16 para 16:9 (ou para 4:5, 1:1) sem perder nada. O projeto aceita os quatro
(`"formato"`: `9:16`, `16:9`, `4:5` com 1080x1350, `1:1` com 1080x1080).

1. **Versão separada.** Copie a pasta do projeto (`sala` para `sala-16x9`) e troque o `formato`. A aprovada não
   é tocada. O nome do arquivo novo diz o formato. Gravação em pé indo para 16:9 vira close (seção "Quando não
   cabe").
2. **Fica igual:** a duração, a ordem dos blocos, a fala, a oferta e os textos aprovados.
3. **Recomponha, não encolha.** Pessoa centralizada em cada recorte, acompanhando o movimento (seções acima).
   Títulos e legendas reorganizados para o espaço novo. Tela e produto continuam legíveis. Imagem que não cabe
   sem perder informação ganha outro arranjo com o mesmo material (contida, tela dividida).
4. **Margens da rede de destino.** Reels 9:16 é conhecida: texto em y 230 a 1530 e x 140 a 940. O 4:5 (x 100 a
   960, y 110 a 1220) e o 1:1 (x 90 a 970, y 90 a 980) do projeto são margens folgadas, **a conferir na rede**: o
   build avisa em todo build e a entrega diz que alguém ainda precisa conferir na rede. Para outra rede, deixe
   margens folgadas (texto longe das bordas, sobretudo embaixo e à direita no vertical) e anote o mesmo.
5. **Amostras** nos pontos em que a proporção nova mais aperta e nas passagens de um arranjo para outro. Espere
   só se a pessoa pediu para aprovar.

## Tela verde: o recorte da pessoa

O recorte vem desta skill (modelo selfie_multiclass, com fluxo óptico e filtro guiado), feito trecho por trecho
do `cut_timeline.json`: o filtro recomeça em cada corte e a forma da tomada anterior não vaza. Não use o
`npx hyperframes remove-background` para isso: ele deixa halo no cabelo e a cor do fundo antigo na borda.

1. Avise: "O recorte leva uns 3 minutos por minuto de vídeo na primeira vez" (num Mac com chip Apple livre; com
   o computador ocupado pode passar de 10 minutos por minuto). Rode em segundo plano.
2. No projeto, só o trecho da tela verde:
   `python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 28.03 --ate 32.3`
   A ferramenta usa a skill anotada no `projeto.json` (`"skill"`) e diz na primeira linha qual usou; confira
   que é esta skill (outra instalada no computador pode ser uma versão antiga). `--skill '<SKILL>'` força.
   Sem `--de/--ate` monta o vídeo todo, o que demora bem mais. Trecho longo: passe antes pelo portão do recorte.
3. Sai `assets/pessoa.webm` (fundo transparente) e `assets/pessoa.json` (o trecho que ele cobre e onde a pessoa
   encosta na borda em cada tomada). O recorte fica guardado em `<EDIT>/renders/matte`: mudar o trecho depois é
   rápido. Tela verde fora do trecho montado: o `build.py` para e diz o comando certo.
4. O `cut.mp4` da pasta edit tem que ser o arquivo de verdade, nunca um atalho (a ferramenta recusa).
5. Erro falando de onnxruntime ou do modelo: a instalação da skill está incompleta. Peça para rodar o instalador
   dela de novo.

O `build.py` usa o `pessoa.json` para o lado que a câmera cortou (ombro, braço) encostar na borda da tela. Se
ele avisar que a câmera corta o corpo do lado de dentro, troque de lado ou use `centro`.

## Passo a passo

1. Leia a fala com `python3 build.py palavras` (mostra palavras, tempos e os cortes) e marque: gancho, prova,
   explicação, chamada. Toque os trechos e marque as regiões obrigatórias.
2. Conte o plano de blocos para a pessoa (regras acima; autorização em camadas).
3. Escreva os `blocos`. As animações de cada bloco seguem `references/animacao.md`.
4. Amostra do trecho mais difícil, 8 a 15 s: a troca de cena mais exigente, o gesto mais largo e a volta à
   pessoa. `python3 build.py amostra 17.9 27.9`, depois `python3 build.py hf lint` e `python3 build.py hf check`.
5. Abra no estúdio (`references/estudio.md`). Sem render. Toque com som no tamanho do celular e passe a agulha
   quadro a quadro em cada troca.
6. Com a amostra certa: `python3 build.py completo`, `check`, estúdio, e o render só no fim (`--quality delivery`).
7. Confira o arquivo exportado nas trocas, com a tira de quadros a 30 qps.

## O que conferir (tocando, e depois no arquivo exportado)

Vários quadros bonitos podem esconder um caminho ruim entre eles. Toque primeiro; depois olhe as passagens em
sequência densa de quadros. Anote o intervalo que você olhou.

- **Em qualquer momento:** a cabeça e os gestos que importam cabem. O rosto não salta de lugar na troca. A voz
  continua casada com a boca.
- **Moldura:** o rosto inteiro dentro do quadro, olhando para dentro dele, sem mostrar só o peito; o papel
  quadriculado (ou o vídeo desfocado) atrás; a borda lilás só depois que o quadro fechou; nenhuma peça na frente
  do rosto enquanto o quadro fecha; a troca acontecendo no corte.
- **Tela cheia:** legenda no peito, sem tocar no queixo; peça em cima da cabeça sem cortar a testa.
- **Prova:** o rótulo legível, o dado privado borrado, a prova inteira à vista e legível no celular.
- **Tela verde e planos:** borda do cabelo e das mãos sem pedaço do fundo antigo; nada do cenário grudado na
  pessoa (estante, banco do carro); o lado cortado encostado na borda; o fundo trocando no segundo certo; a
  palavra atrás do corpo legível enquanto a pessoa se mexe; a frente sem tampar o rosto.
- **Acompanhar:** o rosto no lugar do começo ao fim da tomada, sem tremer nem dar pulo; nenhum aviso de cabeça
  fora do quadro sem resposta.
- **Contida e comparar:** a gravação inteira à vista, com margem igual; os dois lados do mesmo tamanho, no mesmo
  momento, com o rótulo certo; o som de um lado só (ou os dois no mesmo volume).
- Nada cortado na borda da tela, nada fora da zona segura, nenhuma faixa vazia.

## Pegadinhas que já custaram retrabalho

- **Corte dentro da transição da moldura usa o enquadramento da moldura.** Se a câmera troca de tomada enquanto o
  quadro ainda está fechando, o `tl.set` de tela cheia vence a animação e a moldura mostra o peito. O modelo já
  trata; se escrever à mão, cada corte usa o enquadramento do bloco onde ele cai.
- **Corte arredondado pega o rosto da tomada errada.** O tempo do corte com 3 casas (21,933) fica antes do
  começo do trecho novo (21,9333). O modelo procura o rosto com 2 ms de folga para o lado da tomada nova.
- **Anime clip-path e transform, nunca left/top/width/height.** A moldura é um `clip-path: inset(...)` no
  `#frame` do tamanho da tela e um `x, y, scale` no `#inner`. left/top travam no pixel inteiro e o lint reclama.
- **Vídeo com tempo não se anima.** O `<video>` com `data-start` fica parado; o que mexe é a caixa em volta
  (`#inner`, `.pw`, `.pw2`). E nunca ponha `data-start` numa caixa que tem um `<video data-start>` dentro.
- **Estado do quadro 0 com um fromTo curto**, não com `tl.set(..., 0)`: o set em 0 pode sumir quando o seek
  volta ao começo.
- **Recorte feito sem o cut_timeline** carrega a forma da tomada anterior por uns 4 quadros depois de cada corte.
  Rode sempre pelo `pessoa_recortada.py` (ele usa o timeline).
- **Tela verde precisa do mesmo tempo do corte.** O `pessoa.webm` tem os mesmos quadros do `cut.mp4`; o bloco
  usa `data-media-start` igual ao início do bloco. Cortou de novo? Rode o recorte de novo.
- **Alfa do VP9 no ffmpeg:** sem `-c:v libvpx-vp9` antes do `-i`, o ffmpeg lê o `pessoa.webm` sem transparência.
- **O estúdio pode piscar a camada de baixo numa emenda.** No arquivo exportado não aparece. O arquivo é a
  referência.

## Erros comuns

- Moldura em cima da prova (a prova some num quadrinho).
- Moldura longa demais, decorativa o vídeo inteiro, ou entrando no meio de uma frase sem corte.
- Legenda ligada na moldura junto com a animação (duas coisas para ler).
- Print com dado privado de outra pessoa sem borrão.
- Tela verde sem avisar que o recorte demora, ou com moldura junto.
- Texto atrás da pessoa sem teste de recorte, ou chamado de 3D.
- Enquadramento conferido num quadro parado só.
- Mudar de formato por cima da versão aprovada.

## Receitas: enquadramento, moldura, prova e tela verde

O `build.py` do projeto-modelo já faz tudo isto. Use esta página para entender o que ele fez, conferir um
quadro estranho ou escrever uma cena sob medida à mão.

### 1. Onde está o rosto

Esta skill mede o rosto com o YuNet em até 40 quadros de cada trecho do corte e grava
`<EDIT>/face_layout.json`:

```json
{"segments": [{"id": "r06", "start": 18.633333, "end": 21.933333,
  "face": {"x0": 0.2017, "y0": 0.3629, "x1": 0.3598, "y1": 0.4864, "eyes_y": 0.4096, "mouth_y": 0.455}}]}
```

Coordenadas em fração do quadro do `cut.mp4` (0 a 1). Um trecho = uma tomada, então o rosto só muda de
lugar num corte. Trecho sem rosto (`"face": null`, gravação de tela) usa o último rosto visto.

Comando, se faltar: `uv run --directory "<SKILL>" python helpers/face_layout.py --edit-dir '<EDIT>'`.
Ele também imprime uma sugestão de altura para gancho, legenda e chamada.

**Pegadinha do arredondamento:** o corte em 21,933 (3 casas) cai 0,3 ms ANTES do trecho novo (21,9333) e
pegaria o rosto da tomada anterior. Procure o rosto com folga para o lado novo:
`s.start - 0.002 <= t < s.end - 0.002`.

### 2. Enquadrar pelo rosto (tela cheia e moldura)

O vídeo inteiro fica dentro de `#inner` (1080 x 1920, `transform-origin: 0 0`) e a caixa visível é o
`clip-path` do `#frame`. Para uma caixa `(bx, by, bw, bh)` e o rosto `(cx, cy)` = centro, `fw` = largura:

```python
if caixa == tela_inteira:
    z = zoom                                   # 1,08 a 1,12 na tela cheia; 1 na prova
else:                                          # moldura: rosto com uns 40% da largura da caixa
    z = max(0.40 * bw / (fw * W), bw / W, bh / H)
x = clamp(bw / 2 - z * cx * W, bw - z * W, 0)  # rosto no meio da largura, sem mostrar borda preta
y = clamp(0.42 * bh - z * cy * H, bh - z * H, 0)  # rosto a 42% da altura da caixa
inner = {"x": x + bx, "y": y + by, "scale": z}
```

Com `zoom` 1 na tela cheia o `x` trava em 0 (o vídeo já tem a largura da tela): o rosto não centraliza.
Por isso a tela cheia usa 1,08 a 1,12. A prova fica em 1 de propósito: a prova aparece inteira.

### 3. A moldura

```css
#bg{position:absolute;inset:0;opacity:0;background-color:#fffdfd;
  background-image:linear-gradient(#e6ddf8 2px,transparent 2px),linear-gradient(90deg,#e6ddf8 2px,transparent 2px);background-size:60px 60px}
#borda{position:absolute;left:520px;top:980px;width:400px;height:540px;border-radius:40px;opacity:0;
  box-shadow:0 0 0 6px #c7b7ef,0 16px 0 2px #665080,0 30px 50px rgba(53,44,64,.35)}
#frame{position:absolute;left:0;top:0;width:1080px;height:1920px;overflow:hidden}
#inner{position:absolute;left:0;top:0;width:1080px;height:1920px;transform-origin:0 0}
```

Ordem das camadas: `#bg` (papel), `#borda` (o aro fica por baixo do quadro e aparece em volta), `#frame`.

Entrada (no corte em 21,933 de uma amostra que começa em 17,9, então 4,033 na timeline):

```js
tl.set("#inner",{x:0,y:-78.2,scale:1.1},4.033);                                   // tela cheia da tomada nova
tl.fromTo("#frame",{clipPath:"inset(0px 0px 0px 0px round 0px)"},
  {clipPath:"inset(980px 160px 400px 520px round 40px)",duration:0.7,ease:"power3.inOut",immediateRender:false},4.033);
tl.fromTo("#inner",{x:0,y:-78.2,scale:1.1},{x:435.9,y:442.8,scale:0.9371,duration:0.7,ease:"power3.inOut",immediateRender:false},4.033);
tl.fromTo("#borda",{opacity:0},{opacity:1,duration:0.25,immediateRender:false},4.583);   // aro só quando o quadro fechou
tl.fromTo("#bg",{opacity:0},{opacity:1,duration:0.6,immediateRender:false},4.033);
```

O `inset` é `top right bottom left round raio`: `inset(y, W - x - w, H - y - h, x)`. O quadro e o vídeo
andam juntos na mesma curva (`power3.inOut`, 0,7 s), então a pessoa "encolhe para dentro" do quadro.

Saída no corte (troca seca, o corte esconde o salto):
```js
tl.to("#bg",{opacity:0,duration:0.2,immediateRender:false},t - 0.05);
tl.set("#borda",{opacity:0},t);
tl.set("#frame",{clipPath:"inset(0px 0px 0px 0px round 0px)"},t);
tl.set("#inner",{/* tela cheia da tomada nova */},t);
```
Saída fora de corte: o mesmo caminho da entrada ao contrário, em 0,55 s, e o papel some 0,4 s depois.

**O que vence nos 0,7 s em que o quadro fecha: o quadro.** Peça do catálogo cuja palavra cai nesse tempo entra
quando ele termina de fechar (o build avisa com o tempo novo); cena própria recebe
`window.__cenas[...].moldura.fechada_em` e o build avisa quando ela começa antes. A peça chega uns 0,3 a 0,6 s
depois da palavra, o que é melhor que passar na frente do rosto ainda grande.

**Fundo desfocado** (`"fundo": "desfocado"` no bloco): o build grava `assets/gerado/cut_fundo.mp4` (o corte
pequeno, desfocado e sem som) e põe atrás do quadro, no tempo do corte, entrando junto com o papel. É outro
arquivo, então o lint não acusa mídia repetida. Painel de vidro fosco ou outro arranjo continua sendo cena
própria.

Cada corte dentro do bloco troca o enquadramento com um `tl.set("#inner", ...)` no quadro do corte, usando
a caixa do bloco onde o corte cai. **Corte no meio da transição de entrada usa a moldura** (se usar a tela
cheia, o set vence o tween e o quadro mostra o peito).

No 16:9 a caixa padrão é x 1080, y 120, 720 x 840 (à direita) e a área livre fica à esquerda (x 100 a 1020).

### 4. A prova

Gravação que já mostra a tela (câmera filmando o iPad): bloco `prova` sem `arquivo`, zoom 1, a imagem
inteira. Print ou vídeo de tela da pessoa: `arquivo`.

```html
<div class="pvw" id="pvw1">   <!-- caixa sem tempo: é ela que o zoom mexe -->
  <video id="pr1" class="midia" src="assets/reel.mp4" muted playsinline data-start="10.133" data-duration="2.734"
         data-media-start="9.9" data-track-index="41"></video>
</div>
```
```css
.midia{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover}
.midia.borrada{filter:blur(30px) brightness(.55)}      /* encaixe "inteiro": cópia borrada atrás */
.midia.inteira{object-fit:contain}
.pvw{position:absolute;inset:0;transform-origin:0 0}
```

A imagem ou o vídeo com `data-start` é um clip: o HyperFrames mostra e esconde sozinho no tempo certo. O
`data-media-start` é o `inicio` do bloco (e anda junto quando a amostra começa no meio da prova). O rótulo em
cima vem do campo `rotulo` do bloco (um `rotulo` do catálogo em y 250). O borrão não é mais uma camada por cima:
é queimado no arquivo (seção "Borrão").

### 5. A tela verde

**O recorte.** `python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 28 --ate 32.3` roda o `helpers/matte.py` desta
skill (selfie_multiclass em ONNX, fluxo óptico entre quadros, filtro guiado na borda, um trecho por
tomada do `cut_timeline.json`) e junta os recortes com a cor do `cut.mp4`:

```
ffmpeg -i cut.mp4 -f concat -safe 0 -i mattes.txt \
  -filter_complex "[0:v]setpts=N/(30*TB),format=rgba[c];[1:v]setpts=N/(30*TB),format=gray,scale=1080:1920[m];[c][m]alphamerge,format=yuva420p[v]" \
  -map "[v]" -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -crf 20 -auto-alt-ref 0 -metadata:s:v:0 alpha_mode=1 assets/pessoa.webm
```

O `cut.mp4` da pasta edit tem que ser o arquivo de verdade (atalho faz o matte.py ignorar o timeline e
recortar tudo como um trecho só, e a forma da tomada anterior vaza na seguinte). O `hyperframes
remove-background` não serve: deixou halo no cabelo e a faixa de luz do fundo entre a barba e o pescoço.

**A cena.** (bloco de 28,033 a 32,3 s, `posicao: "esquerda"`, pessoa que a câmera corta à esquerda)
```html
<video id="tv4" class="midia" src="assets/fundo.mp4" muted playsinline data-start="28.033" data-duration="4.267" data-media-start="0" data-track-index="1"></video>
<div class="pw" style="transform:translate(0px,729.6px) scale(0.62)">
  <div class="pw2" id="pw4" style="filter:drop-shadow(8.1px 0px 0 #fff) drop-shadow(-8.1px 0px 0 #fff) drop-shadow(0px 8.1px 0 #fff)
       drop-shadow(0px -8.1px 0 #fff) drop-shadow(5.6px 5.6px 0 #fff) (...as outras 3 diagonais...) drop-shadow(0 23px 29px rgba(0,0,0,.45))">
    <video id="pessoa4" src="assets/pessoa.webm" muted playsinline data-start="28.033" data-duration="4.267" data-media-start="28.033" data-track-index="2"></video>
  </div></div>
```
```js
tl.fromTo("#bg",{opacity:0},{opacity:1,duration:0.3,immediateRender:false},28.033);
tl.to("#frame",{opacity:0,duration:0.25,immediateRender:false},28.033);     // o vídeo com o fundo antigo some
tl.fromTo("#pw4",{opacity:0,y:40},{opacity:1,y:0,duration:0.3,ease:"power3.out",immediateRender:false},28.033);
```
Da tela verde para a moldura, o quadro já nasce no lugar da moldura e aparece (0,25 s), sem passar pela tela
cheia. Se o `pessoa.webm` foi montado só de um trecho (`--de/--ate`), o `data-media-start` desconta o
`inicio` gravado no `pessoa.json`.

- `.pw` é uma caixa SEM tempo com a posição fixa (pode ter `transform` no CSS porque o GSAP não mexe nela);
  `.pw2` é quem o GSAP anima; o `<video>` com tempo fica quieto dentro. `data-media-start` do `pessoa.webm`
  é o início do bloco no tempo do corte (os dois vídeos têm os mesmos quadros).
- Posição: escala `altura` (0,62 no canto, 0,8 no centro), pés na borda de baixo (`ty = H - s*H`) e o
  centro do rosto em 70% (direita), 30% (esquerda) ou 50% (centro) da largura.
- Lado cortado pela câmera: o `pessoa.json` diz em quantos quadros a pessoa encosta na esquerda e na
  direita do quadro (`touch_left`, `touch_right`). Pessoa no canto direito que encosta na direita: a borda
  direita do vídeo encosta na borda da tela (o ombro cortado some na borda). Encosta do lado de dentro:
  aparece um corte reto no meio da tela, então o `build.py` avisa para trocar de lado ou usar `centro`.
- Contorno branco: 8 `drop-shadow` sem desfoque em volta (5 px na tela, dividido pela escala) e uma sombra
  suave embaixo. Esconde a franja fina que o recorte deixa na borda.
- O fundo pode ser imagem ou vídeo; `encaixe: "inteiro"` mostra o print inteiro por cima de uma cópia
  borrada e escura dele mesmo.

### 6. Legenda em cada cena

- Tela cheia e prova: uma linha, no máximo 3 palavras (`max_palavras`) e 14 letras (`max_letras`), nunca
  duas na tela, quebra em vírgula, ponto ou pausa de 0,6 s. Legenda de uma palavra só que ficaria menos de
  0,3 s na tela junta com a vizinha. Altura: 300 px abaixo do queixo, entre y 1100 e 1400 (no peito).
  Mesma altura enquanto a diferença for menor que 40 px (sem tremida entre uma legenda e a próxima).
- Estilo (`legenda.estilo`): `padrao` é caixa alta, Montserrat 900 60 px branca com contorno de 10 px
  (`-webkit-text-stroke` + `paint-order: stroke fill`); `discreta` é menor (44 px), sem caixa alta, peso 700,
  num fundo escuro leve arredondado, até 22 letras. Legenda escrita à mão (papelaria), manchete ou impacto é
  cena própria.
- Moldura: sem legenda (a animação explica). Palavra a menos de 0,3 s antes da troca também sai, para a legenda
  não piscar antes da transição. Com `na_moldura`, no 9:16 a legenda fica logo acima do quadro e no 16:9 na
  área livre ao lado dele, sem atravessar a borda.
- Tela verde: legenda no peito da pessoa recortada.
- Peça ocupando o lugar da legenda: a legenda desce para 1420 ou sobe para 1120.
