# Atalho: estilos prontos

O jeito padrão da skill é a edição sob medida no HyperFrames, revista no estúdio (SKILL.md). Este atalho é o
motor antigo, que monta o final sozinho com estilos prontos de legenda, gancho, tela dividida, tela verde,
animações de modelo, efeitos e trilha (`helpers/compose_final.py`). Use quando a pessoa pedir algo rápido e
simples ("só legenda e gancho"), quando quiser um dos estilos que ela já conhece pelo nome (painel de
pedidos: `papelaria`, `impacto`, `manchete`...) ou quando o computador não tiver o Node para o HyperFrames.

O corte é o mesmo (`references/corte.md`): corte pela onda, conferido e aprovado no estúdio. Daqui para a
frente tudo é pela conversa: não existe mais a aba Estilo nem o botão de aprovar do preview antigo. Os campos
de cada escolha estão em `references/phase2.md`.

## Estilo

Com o corte aprovado:

1. Pense num gancho (seção "Gancho e chamada") e gere as amostras com uma frase real do corte:
   `uv run --directory '<SKILL>' python helpers/style_samples.py --edit-dir '<EDIT>' --text 'frase curta do vídeo' --hook-text 'Seu gancho *aqui*'`
   As amostras já saem fora do rosto e num quadro em que a pessoa aparece.
2. Mostre as imagens de `<EDIT>/samples/` (abra ou mande o arquivo) e, em lista numerada, 3 legendas e
   3 ganchos do catálogo (`label` e `desc` de `helpers/style_catalog.json`), com a sua recomendação.
   Pergunte numa mensagem só: tipo de edição, legenda, gancho, cor de destaque, animações (sim ou não e
   quantas), trilha (os humores que a biblioteca tem, veja "Trilha") e a limpeza de ruído, se o
   `noise_check.py` indicou. Se ela disser "decide você", decida e conte em uma linha.
3. Anote a escolha no `project.md`.

Tipos: `clean` (só a pessoa, tela cheia), `split_top` (imagem em cima nos trechos de prova),
`split_bottom` (imagem embaixo) e `tela_verde` (a pessoa recortada na frente e as imagens e vídeos da edição
no fundo, com a pessoa no canto esquerdo, no canto direito ou no meio; veja "Tela verde"). É um tipo ou outro:
nunca ofereça tela dividida junto com tela verde. Na tela verde, pergunte a posição (canto direito, canto
esquerdo ou centro). Se a pessoa trocar de "Imagem em cima" para "Tela verde", mantenha os inserts que já
estavam planejados: eles vão para o fundo sozinhos, sem nenhum passo a mais.
Como cada escolha vira campo: `references/phase2.md`.

## O final com estilos prontos

1. **Fala do corte.** Se o corte mudou depois da conferência, rode de novo o `conferir_corte.py` (`references/corte.md`, passo 6), que transcreve o `cut.mp4`.
2. **O que já está escrito na tela** (vale para qualquer vídeo, e é obrigatório quando o bruto já tem
   legenda gravada, print, painel ou motion com texto):
   `uv run --directory '<SKILL>' python helpers/texto_na_tela.py --video '<EDIT>/cut.mp4' --edit-dir '<EDIT>'
   --transcript '<EDIT>/transcripts/cut.json'`
   - Ele diz quantos trechos já têm legenda, quantos são gráfico de tela cheia e guarda o mapa em
     `texto_na_tela.json`. A legenda pula esses trechos sozinha e todos os textos desviam do que está
     desenhado. No Mac ele lê as palavras (Vision); nos outros sistemas só acha as manchas de texto.
3. **Legendas** no estilo escolhido. As palavras vêm das transcrições das fontes (com o `--prompt`
   certo), já no tempo do corte:
   `uv run --directory '<SKILL>' python helpers/captions.py --edit-dir '<EDIT>' --style impacto`
   - Estilos que escrevem a frase palavra por palavra: `papelaria` (fundo escuro ou vídeo),
     `papelaria_papel` (quando o fundo é claro) e `depoimento` (fala de outra pessoa).
   - A linha `pulei N legenda(s)` mostra o que ficou de fora por já estar escrito na tela.
   - Linhas `confira:` mostram onde as fontes e o corte ouviram palavras diferentes. Veja qual está
     certa e, se preciso, troque: `--replace '20.8=20,8'` (pode repetir; aceita várias palavras).
   - Palavra de marca errada: `--replace 'Cacto=Cakto'`. Mudou o estilo depois? Rode de novo.
   - O vídeo já tinha legenda escrita (`references/corte.md`, passo 2) e a pessoa não quis a sua: pule este passo.
4. **Imagens**, se o tipo for split ou tela verde, ou houver inserts (seção "Imagens"). Na tela verde,
   planeje as imagens e vídeos como inserts `split_top` normais: eles viram o fundo (seção "Tela verde").
5. **Animações (motion)**, se a pessoa quis animações no passo de estilo.
   São textos e números que se desenham na tela: lista com check, lista riscada, passo a passo, etiqueta de
   preço, contador, barra, gráfico, palavra de impacto, chamada para comentar, notificação, destaque
   desenhado, carimbo e selo de garantia. Vídeo feito com IA (Higgsfield, Kling) continua entrando como insert; a animação é para texto
   e número exatos, que a IA de vídeo não desenha.
   Com a quantidade e o visual que ela escolheu (ex.: poucas = `motion.quantidade` 3, visual papelaria =
   `motion.tema` "papelaria"), escreva `"motion": {"tema": ..., "quantidade": ..., "items": []}`
   com esses valores e rode:
   `uv run --directory '<SKILL>' python helpers/motion_sugerir.py --edit-dir '<EDIT>'`
   - Ele acha os momentos da fala e fica com os N mais fortes, um em cada parte do vídeo: lista, "você não
     precisa de...", passo a passo, preço, número, "comenta X", a oferta (grátis, liberado, bônus,
     garantia: `carimbo` ou `selo_garantia`), a virada da história ("o caminho que eu descobri", "mas...":
     `palavra_impacto`) e frase curta de impacto.
   - **Pontos pedidos pela pessoa** ("põe uma animação em 01:33"): ponha esse ponto como item de `motion`
     com a nota `PEDIDO:` e faça o que ela pediu, mesmo que troque o modelo.
   - **Reescreva o texto** de `palavra_impacto` e `carimbo`: o sugeridor acha ONDE, você decide O QUE
     escrever, com 1 a 3 palavras que resumem a ideia da frase (ex.: "Mas eu vou te contar o que eu fiz e
     o que funciona" → "O QUE *FUNCIONA*"). Mostre a lista final (tempo, modelo, texto) para a pessoa
     antes do render.
   - **Quando usar:** só onde a fala pede. No máximo uma animação a cada 6 s. Vídeo sem nenhum momento
     achado fica sem animação, e você diz isso.
   - **Nunca em cima do rosto:** deixe `"region": "auto"` (o compose acha o rosto e desvia). Nunca no
     gancho nem na chamada: comece depois do fim do gancho e termine antes da chamada.
   - Para ver um modelo antes: `motion_render.py --template checklist --params '{"items": ["Acesso na hora"]}'
     --out '<EDIT>/verify/motion'` e olhe o `checklist_folha.png`. `--list` mostra todos e `--describe ID`
     os campos. Campos, exemplos e regras: `references/phase2.md`, seção `motion`.
   - `animações: desligadas`: não escreva `motion`.
6. **Escreva `<EDIT>/edit_data.json`** seguindo `references/phase2.md` (leia na primeira vez da
   sessão). Seção que não está no arquivo fica desligada: escreva cada elemento escolhido.
   **Posição:** deixe `camera.focus_y` e os `center_y` de fora. O compose acha o rosto em cada
   trecho (`face_layout.py`) e põe cada texto no lugar livre mais perto do normal, sem cobrir o
   rosto nem outro texto. Só use número se a pessoa pedir outra altura.
   **Biblioteca de efeitos:** além dos 24 prontos (um som por nome, que repete), a pessoa pode ter uma
   biblioteca com centenas de sons por categoria (`~/.editor-video/efeitos`; `efeitos.py listar` mostra).
   No `sfx.events` use a categoria (`transicao`, `impacto`, `revelacao`, `interface`, `tecnologia`, `sucesso`,
   `erro`, `humor`): cada evento da mesma categoria toca uma versão diferente. Afine pelo tipo com
   `categoria:tipo` (`impacto:boom`, `impacto:punch`, `transicao:swish`, `transicao:swipe`, `revelacao:riser`,
   `humor:boing`, `humor:boom808`, `tecnologia:laser`, `tecnologia:glitch`, `sucesso:powerup`) ou um som
   exato (`humor-077`). Riser de revelação termina no `at` (o ponto forte é o fim). O relatório diz em
   `layers` qual som tocou (`effect`). Pessoa pediu para tirar um som: `efeitos.py remover ID`.
   **Efeitos pelo sentido:** escolha o som pelo que a fala diz, no segundo da palavra, com `sfx.events`
   (venda `cash` ou `notification`, erro `error`, número `count`, revelação `bass_drop`; a tabela com os
   24 e os nomes em português está em `references/phase2.md`, seção `sfx`).
   **Trilha:** use o humor ou o arquivo que ela escolheu. Se ela quis música mas não disse de onde,
   pergunte. Siga a seção "Trilha" antes de escrever `music`.
   **Ruído de fundo:** com o que foi combinado (`leve`, `forte` ou `desligado`), escreva `"audio": {"denoise": "leve"}` com o mesmo valor. O compose imprime
   `ruído de fundo: leve (fundo de -50 dB para -58 dB)`; leia os `aviso:` dessa parte
   (`references/phase2.md`, seção `audio`).
6. **Prévia e olho:**
   `uv run --directory '<SKILL>' python helpers/compose_final.py '<EDIT>/edit_data.json' --preview`
   `uv run --directory '<SKILL>' python helpers/contact_sheet.py '<EDIT>/final_preview.mp4' --times 0.3 2 4.5 9 14 20 -o '<EDIT>/verify/final_preview.png'`
   A prévia é só para você.
   Troque os tempos: início, gancho, a entrada de cada insert, o meio de cada animação, meio e o último
   segundo. Olhe e confira:
   - gancho legível; nenhum texto em cima do rosto, da boca ou de outro texto;
   - imagem e animação sem cobrir o rosto; nada cortado na borda; animação legível e com o texto certo;
   - **nenhuma legenda ou texto que já estava no vídeo aparecendo duplicado**;
   - **nenhum dado pessoal de outra pessoa na tela** (e-mail, telefone, CPF, cartão, conversa) sem borrão.

   Leia cada linha `aviso:` que o compose imprimir. Texto que ele não conseguiu tirar do rosto vem
   com a altura sugerida.
7. **Final:**
   `uv run --directory '<SKILL>' python helpers/compose_final.py '<EDIT>/edit_data.json'`
   Confira `<EDIT>/verify/final_report.json`: duração igual à do corte, loudness perto de -14,
   `warnings` vazio ou explicado, `face_checks` vazio. Faça a folha de quadros do `final.mp4` como
   no passo 6 e olhe de novo. Em `adjustments`, cada legenda que mudou de altura ou sumiu por causa de uma
   animação aparece com `"because": "motion"`.
8. **Aprovação final.** Conte em poucas linhas o que entrou (gancho, legenda, imagens, animações, chamada,
   aviso), mande o `final.mp4` e peça para assistir e dizer o que muda, com o tempo ("em 00:14 a legenda
   cobre o produto").
   - O tempo do final é o mesmo do corte (a duração é igual). Mudança visual: ajuste o `edit_data.json` e
     renderize. Mudança de fala: volte ao `edl_manual.json` (`references/corte.md`), refaça o corte, mostre
     de novo e refaça os passos 1, 2, 4, 6 e 7.
   - Aprovado no chat: diga onde está o `final.mp4`, anote no `project.md` e ofereça uma variação (outro
     gancho, versão mais curta: `references/variacoes.md`).

## Gancho e chamada

**Gancho** (texto grande nos primeiros 2 a 3 s):
- No máximo 2 linhas, de 4 a 9 palavras. Se o compose avisar "gancho longo demais", encurte.
- Curiosidade ou quebra de padrão: "Olha o que eu achei pra revender", "O erro que trava suas
  vendas no Instagram", "Ninguém me contou isso sobre fornecedor".
- Específico: nomeie o objeto, a situação ou o público ("Se você vende pelo Instagram, veja isso").
- Destaque de 1 a 3 palavras com asteriscos: `Você está *perdendo venda* assim`.
- Complementa a fala, não repete a primeira frase palavra por palavra.
- Sem gancho da pessoa? Ofereça 3 opções e recomende uma.

**Chamada (CTA)** no fim:
- Verbo de ação e destino: "Toque em Saiba Mais", "Clique no botão abaixo", "Chame no WhatsApp",
  "Assista à aula gratuita", "Veja como funciona", "Garanta sua vaga".
- Linha de apoio (`sub`) opcional, com um fato verdadeiro: "Acesso na hora", "Aula gratuita",
  "7 dias de garantia". Nada de "últimas vagas" ou "só hoje" se não for verdade.
- Combine com o que a pessoa fala no fim e com o botão do anúncio.

**Aviso de resultado:** desligado. Só entra se a pessoa pedir (`"disclaimer": {"enabled": true}`, campos em
`references/phase2.md`).

## Imagens

- **Busca livre (padrão, sem chave):**
  `uv run --directory '<SKILL>' python helpers/fetch_images.py 'leather handbag' --edit-dir '<EDIT>' --count 3 --orientation landscape`
  Busque em inglês, com 1 a 3 palavras simples ("laptop", "leather handbag"). Sem resultado,
  troque as palavras ou tire o `--orientation`. `landscape` para split e pip, `portrait` para
  `full`. As imagens vão para `<EDIT>/assets/`, com autor e licença em `assets/credits.json`.
  Abra e olhe cada imagem antes de usar: descarte marca d'água, texto, logo, pessoa famosa e
  baixa qualidade. Prefira licença sem atribuição obrigatória; se usar uma que pede crédito,
  avise que ele vai no texto do post.
- **Pexels:** o mesmo comando com `--source pexels`, se existir `PEXELS_API_KEY`. Sem a chave,
  o helper usa o Wikimedia sozinho.
- **Arquivo da pessoa** (print, foto do produto): copie para `<EDIT>/assets/`, nunca mova.
- **Imagem com IA (opcional, paga):** só quando a busca não servir e a pessoa topar. Primeiro
  `uv run --directory '<SKILL>' python helpers/gen_image.py 'descrição da cena' --edit-dir '<EDIT>' --size 1080x900 --dry-run`,
  depois o mesmo sem `--dry-run`. Sem chave, o helper sai explicando. Então peça para a pessoa
  colar a chave do OpenRouter aqui no chat e grave você mesmo a linha `OPENROUTER_API_KEY=...` em
  `<SKILL>/.env` com a ferramenta de arquivo (ela não precisa mexer em pasta escondida). Nunca
  repita a chave na conversa e nunca coloque em comando. Não gere pessoa real, marca ou produto de
  terceiro. Tamanhos: split 1080x900, full 1080x1920, pip 1080x1080.

## Tela verde

A pessoa aparece recortada, sem o fundo da gravação, na frente de uma imagem ou de um vídeo. Não precisa
de pano verde: o editor acha a pessoa sozinho em cada quadro.

**Quando oferecer** (no estilo, em uma frase, sem insistir):
- comentário sobre uma imagem, uma notícia ou um vídeo ("olha o que eu achei");
- reação a uma página, a um anúncio de concorrente ou a um print;
- mostrar um produto, um site ou um painel enquanto fala.
Vídeo em que a pessoa já mostra a tela (gravação de tela, mão apontando) não precisa: esses trechos já
aparecem como foram gravados.

**As imagens e vídeos são inserts normais.** Planeje como na tela dividida: um insert `split_top` por
momento da fala que pede prova ou imagem, com `start` e `end` no tempo do corte. Na tela verde eles não
aparecem divididos: cada um vira o fundo atrás da pessoa, no quadro exato em que começa e termina (com o
mesmo `sfx`, o mesmo `ken_burns` e os flashes de `transitions`). Não copie nada para `tela_verde.fundo`.
- `tela_verde.fundo` é só para fundo extra que não depende de um momento da fala: uma página rolando o vídeo
  todo, uma cor, o próprio vídeo desfocado (`"fundo_original_desfocado": true`). Os inserts ganham dele
  enquanto duram.
- Entre dois inserts (e depois do último) continua o fundo de antes: a imagem fica com o zoom lento ou
  parada, o vídeo continua repetindo sem pulo.
- `full` continua cobrindo a tela toda (corte para a imagem) e `pip` continua como cartão por cima, no canto
  longe do rosto.

**Pergunte de onde vêm as imagens e vídeos** (numere e recomende):
1. arquivos da própria pessoa (print da página, print do painel, foto do produto, vídeo dela): copie para
   `<EDIT>/assets/`, nunca mova;
2. clipes gerados com IA na conta dela (Higgsfield, Kling), com o ok dela para o custo;
3. imagens livres com o `fetch_images.py` (seção "Imagens"; `--orientation portrait` enche a tela,
   `landscape` fica inteira em cima da pessoa).

**Tempo:** o recorte leva uns 3 minutos por minuto de vídeo na primeira vez (no Mac com chip Apple,
menos). Avise antes. Ele fica guardado por trecho do corte: mudar fundo, posição, textos ou cortar outra
parte do vídeo não recorta de novo o que já foi feito. Para adiantar, logo que a pessoa escolher a tela
verde rode em segundo plano:
`uv run --directory '<SKILL>' python helpers/matte.py --edit-dir '<EDIT>'`
Erro dizendo que falta o onnxruntime ou o modelo: a instalação está incompleta (rode o instalador de novo).

**Como fica:**
- Posição: `direita` ou `esquerda` (canto, a pessoa com 55% da altura da tela) ou `centro` (75%). Pessoa
  gravada bem de perto fica menor no canto, para continuar parecendo canto.
- O lado que a câmera cortou (ombro, braço) encosta na borda da tela. Se o corte cair dentro da tela, só
  o pedaço do corpo que encosta ali some num degradê; o braço continua inteiro. Trecho em que o rosto sai da
  câmera por um lado fica encostado nesse lado, para o rosto nunca aparecer cortado no meio.
- Trecho em que a câmera corta os dois lados do corpo: no canto, a pessoa ocupa a largura toda da tela
  nesse trecho, com a cabeça na mesma altura (a parte de baixo da gravação sai da tela, no máximo 20%), e
  nenhum corte aparece no meio da tela. O compose avisa quais trechos; conte em uma frase, porque o tamanho da
  pessoa muda nesse corte.
- Se o compose avisar que a câmera corta o corpo do lado de dentro do canto, veja se há texto na roupa ou
  nos objetos que aparecem (sairia invertido). Sem texto e com o canto já escolhido pela pessoa, monte de novo
  com `"espelhar": true` antes de mostrar e conte em uma frase (ela pode pedir sem espelhar). Com texto,
  ofereça o que o aviso sugere: o outro canto ou o `centro`.
- Contorno branco de 8 px e sombra ligados por padrão. `zoom_cuts` e `push_in` aumentam a pessoa.
- Encaixe de cada imagem ou vídeo (`encaixe`, padrão `auto`): foto ou vídeo em pé (9:16) enche a tela
  (`cobrir`); print de celular ou de painel, foto deitada e clipe quadrado aparecem inteiros e nítidos
  (`inteiro`), na faixa acima da pessoa, sobre uma cópia desfocada e escura deles mesmos. Assim o valor do
  print não fica atrás da pessoa nem embaixo da legenda. Print que não cabe diminui (até metade da largura).
- Clipe de vídeo com borda lisa (estúdio, cor lisa, como os clipes de IA) fica largo (até 75% da largura,
  para sobrar a faixa da legenda acima da cabeça) e a borda dele continua até as beiradas: vira o cenário
  atrás da pessoa, sem caixa em volta. A parte principal (onde está a maior parte dos objetos do clipe)
  fica no alto; o resto passa para trás da legenda e da pessoa. Quadros vazios no começo ou no fim do clipe
  não aparecem sozinhos (o fundo de antes se dissolve nele enquanto os objetos entram), e um clipe que
  termina encolhendo até sumir para no último quadro cheio.
- Trecho em que o `face_layout.py` não acha rosto (gravação de tela, produto na mão) aparece como foi
  gravado, em tela cheia (`"sem_rosto": "original"`).
- Legenda, gancho, chamada e animações ficam fora do rosto e, quando cabe, acima da pessoa. A legenda também
  foge da parte principal da imagem inteira: fica entre a imagem e a cabeça quando cabe, senão abaixo do rosto
  e, sem espaço ali, por cima da parte de baixo da imagem.
  Um `center_y` escrito à mão que cairia no rosto (a pessoa mudou de lugar) vai para a altura livre mais
  perto, com aviso.
- Com a câmera parada (tripé), o editor aprende o cenário de cada tomada e tira do recorte o pedaço do
  cenário em que o modelo ficou em dúvida (névoa, mancha clara que pisca, franja clara ou azul na borda). O
  que o modelo toma por corpo com certeza e nunca viu como fundo (uma cadeira escura entre o braço e o
  corpo) continua: o relatório diz em `fundo_do_cenario` se a tomada teve o cenário aprendido.
- Na folha de quadros, confira: borda do cabelo e da mão sem pedaço do fundo antigo (o primeiro quadro, que
  vira capa, também), nada do cenário (estante, carro, cadeira) grudado na pessoa, e o fundo trocando no
  segundo certo. Se o recorte errar muito num trecho, troque o fundo por uma cor parecida com a gravação ou
  use outro tipo de edição nesse vídeo.
- Campos e exemplos: `references/phase2.md`, seção `tela_verde`.

## Trilha

Pergunte uma vez se a pessoa quer música de fundo (no estilo, ou antes do final se a opção de
trilha veio marcada). Ela pode ter uma **biblioteca de trilhas por humor**, que fica fora da skill
(`~/.editor-video/trilhas` no Mac, `%USERPROFILE%\.editor-video\trilhas` no Windows) e não se perde
quando a skill é instalada de novo. Veja o que tem nela:
`uv run --directory '<SKILL>' python helpers/trilhas.py humores`

**Humores:** `animada` (energia, oferta, novidade), `inspiradora` (conquista, virada de vida),
`triste` (dor, problema, desabafo), `tensa` (segredo, alerta, erro que as pessoas cometem), `calma`
(explicação, tutorial, confiança), `epica` (revelação, resultado, grande virada), `divertida`
(humor, bastidor, conteúdo leve) e `luxo` (produto premium). A pessoa pode criar humores dela.

**A pessoa disse "trilha triste"** (ou "trilha animada", "põe a épica") ou escolheu um humor no
estilo: use o humor, sem gerar nada:
`"music": {"enabled": true, "mood": "triste", "volume_db": -15, "duck": true, "fade_out": 1.5}`.
- O compose pega a favorita do humor. Sem favorita, pega a que cobre o corte sem repetir e tem menos
  energia na faixa da voz. Ele copia a música para `<EDIT>/assets/trilha_triste.<ext>`, anota a
  escolha em `assets/trilhas_escolhidas.json` e usa a mesma nas próximas montagens desta edição.
  Conte em uma linha qual entrou (a linha `trilha do humor ...` do compose diz qual e por quê).
- Trocar por outra do mesmo humor:
  `uv run --directory '<SKILL>' python helpers/trilhas.py escolher --humor triste --edit-dir '<EDIT>' --trocar`
  e monte de novo. Uma trilha certa: `--trilha triste-2` no lugar de `--trocar`.
- Humor vazio ou biblioteca que ainda não existe: o compose para e diz como encher. Ofereça os
  caminhos abaixo. Não invente arquivo.

**Sem humor definido, sugira um pelo trecho mais forte do anúncio:** PROBLEMA pede triste ou tensa;
VIRADA, inspiradora ou épica; PROVA e RESULTADO, épica ou calma; tutorial e PASSO, calma; oferta e
CHAMADA, animada; bastidor, divertida; produto caro, luxo. É uma música só para o vídeo inteiro:
escolha pelo clima que domina, diga o porquê em uma frase e confirme.

**De onde vem a trilha.** Dê os caminhos numerados:

1. **Da biblioteca**, pelo humor, se ela já tem trilha nele. Recomende este.
2. **Arquivo dela**, com direito de uso (música própria ou com licença comercial). Só para este
   vídeo: copie para `<EDIT>/assets/` (nunca mova) e use `"file": "assets/nome.mp3"` no `music`. Para
   guardar e usar sempre, ponha na biblioteca:
   `uv run --directory '<SKILL>' python helpers/trilhas.py adicionar '/caminho/da/musica.mp3' --humor animada --titulo 'Pop da oferta'`
   (`--favorita` marca como a preferida do humor). O helper copia (o original não sai do lugar),
   mede volume, duração e energia e anota tudo. Música que não é dela ou sem licença: não guarde.
3. **Gerar com IA na conta ElevenLabs dela** (opcional e pago). Usa a chave e o plano dela. Para
   anúncio, só com plano pago da ElevenLabs; no plano grátis o uso comercial não é permitido.
   Pessoa física: Starter ou maior. Empresa: Scale, Business ou Enterprise, conforme o número de
   funcionários (o `--dry-run` mostra a regra). Vale para internet, não para TV, rádio ou cinema.
   Com `--biblioteca` a trilha gerada entra na biblioteca e não precisa ser gerada de novo.
4. **Sem trilha** (padrão). Música da biblioteca do Gerenciador de Anúncios entra depois, na Meta.

Cuidar da biblioteca (sempre com o ok da pessoa):
- `trilhas.py listar` mostra as trilhas por humor, a favorita primeiro (★), com duração, volume e
  energia ("cheia desde o início" ou "começa baixa e cresce aos 8 s").
- `trilhas.py favorita triste-2` marca a preferida; `--tirar` desmarca.
- `trilhas.py remover triste-2` manda para a lixeira da biblioteca (`_lixeira`), sem apagar.
  `trilhas.py restaurar triste-2` traz de volta.
- `trilhas.py onde` mostra a pasta. Humor novo: `adicionar ... --humor 'Nome do humor'` (com
  `--quando 'quando usar'`); nome parecido com um que existe pede `--novo-humor`.

Para gerar (caminho 3):

- Com humor, o pedido em inglês já vem pronto:
  `uv run --directory '<SKILL>' python helpers/gen_music.py --humor triste --edit-dir '<EDIT>' --dry-run`
  Palavras a mais entram no fim do pedido pronto: `gen_music.py 'with soft rain' --humor triste ...`. Com
  `--biblioteca` cada versão também entra na biblioteca, com a origem e o pedido anotados. Sem
  `--edit-dir`, a trilha tem 60 s e vai só para a biblioteca:
  `uv run --directory '<SKILL>' python helpers/gen_music.py --humor animada --biblioteca --dry-run`
- Sem humor, escreva o pedido em inglês, nesta receita: instrumental, gênero, clima, faixa de bpm,
  `no vocals`, `leaves room for voice`. Oferta ou UGC: `upbeat modern pop instrumental, 110-120 bpm,
  positive and confident, light drums, no vocals, leaves room for voice`. Depoimento ou aula:
  `calm warm acoustic instrumental, 80-90 bpm, soft piano and guitar, hopeful, no vocals, leaves
  room for voice`.
- Nunca cite artista, banda, compositor, música, álbum, gravadora, filme ou marca ("estilo
  Anitta", "tipo Star Wars"), nem trecho de letra. O helper recusa os nomes mais conhecidos e a
  ElevenLabs recusa o resto (`bad_prompt`, com uma sugestão: mostre para a pessoa antes de usar).
- Sempre primeiro o `--dry-run`:
  `uv run --directory '<SKILL>' python helpers/gen_music.py 'upbeat modern pop instrumental, 110-120 bpm, positive, no vocals, leaves room for voice' --edit-dir '<EDIT>' --dry-run`
  Ele mostra a duração (o corte + 2 s; com `--biblioteca`, pelo menos 60 s), os arquivos e o custo
  estimado em créditos. Conte o custo e espere o ok da pessoa. Depois rode o mesmo sem `--dry-run`.
  `--variations 2` faz duas versões para ela escolher (cada uma é cobrada).
- Sem chave, o helper sai explicando. Peça para a pessoa colar a chave da ElevenLabs aqui no chat e
  grave você mesmo a linha `ELEVENLABS_API_KEY=...` em `<SKILL>/.env` com a ferramenta de arquivo.
  Nunca repita a chave na conversa e nunca coloque em comando.
- A trilha sai em `<EDIT>/assets/trilha_1.mp3`, com a origem em `assets/credits.json`. Nunca salve
  nem copie trilha gerada para a pasta da skill. O arquivo é só para os vídeos da pessoa: não junte
  trilhas ou efeitos gerados num pacote para outras pessoas, nem copie a biblioteca dela para
  ninguém.
- Erro (chave inválida, sem créditos, muitas requisições, serviço fora): conte em uma frase o que a
  mensagem diz e o que a pessoa precisa fazer. Não repita o comando sem mudar nada. Se a trilha foi
  gerada mas não entrou na biblioteca, a mensagem traz o comando para pôr sem gerar de novo.

No `edit_data.json`, pelo humor ou por um arquivo (arquivo ganha se vierem os dois):
`"music": {"enabled": true, "mood": "triste", "volume_db": -15, "duck": true, "fade_out": 1.5}` ou
`"music": {"enabled": true, "file": "assets/trilha_1.mp3", "volume_db": -15, "duck": true, "fade_out": 1.5}`.
Com fala o tempo todo, -15 deixa a música uns 19 dB abaixo da voz: dá para ouvir sem brigar. Mais
presença: -12. Mais baixa: -18. O antigo -22 quase some. Ouça o final: a trilha não pode brigar com
a voz.

**Efeito que os 24 prontos não têm** (opcional e pago, mesma conta e chave): veja antes se algum da
tabela de efeitos (`references/phase2.md`) não serve. Se não, com o ok da pessoa:
`uv run --directory '<SKILL>' python helpers/gen_sfx.py 'soft paper page flip' --edit-dir '<EDIT>' --seconds 1 --dry-run`
e depois sem `--dry-run`. Sai `assets/sfx_<nome>.mp3` (de 0,5 a 5 s), que entra pelo caminho em
`sfx.events` (`{"at": 7.3, "name": "assets/sfx_papel.mp3"}`) ou no `sfx` de um insert.

