Short-Form Vertical Video (Hyperframes)
Short-form = 1080x1920 vertical, 10–30s, talking-head face + motion-graphic scene overlays + karaoke captions. Everything in this skill is distilled from the May Shorts 19 iteration autopsy (v1 → v4) and should be applied on every new short.
Sempre invoque /hyperframes primeiro. Este skill fica sobre ele — não substitui as regras do framework (data-* attributes, window.__timelines, composition structure). Elas são inegociáveis, independentemente do formato.
Quando este skill é ativado
- "Make a short-form video", "TikTok post", "Reels", "Shorts", "vertical video"
- Qualquer construção a partir de uma gravação de talking-head + script/transcrição destinada a redes sociais
- Re-temporização, recorte ou re-sincronização de um short existente
- Adicionar legendas karaokê sincronizadas com uma narração
O playbook (alto nível)
- Áudio é a fonte da verdade. Edite o áudio PRIMEIRO (corte retakes, pausas). Salve como
<name>-edit.mp4. Meça a duração exata comffprobe— esta é adata-durationda composição. - Transcreva o áudio editado com
npx hyperframes transcribe <edit>.mp4 --model small.en --json, ou se estiver re-temporizando uma construção existente com uma funçãoshift()nas legendas, mantenha as legendas existentes e apenas desloque os inícios de cena. - Defina os limites de cena no tempo editado — NUNCA misture âncoras de tempo original e tempo editado no mesmo arquivo. Veja "Protocolo de sincronização de áudio" abaixo.
- Construa o andaime da composição (4 camadas: ambient-bg, seam-treatment, captions, face) — veja "Andaime da composição" abaixo.
- Crie cenas com deslocamentos LOCAIS relativos ao
data-startde cada cena. Cada cena é sua própria sub-composição emcompositions/scene<N>-<label>.html. - Lint → renderização de rascunho → verificação de quadro exato de palavra → renderização final. Este é o portão de verificação. Nunca pule o passo 3 (verificação de quadro).
Andaime da composição (as 4 camadas sempre ativas)
Cada short-form vertical tem estas quatro sub-composições em compositions/, carregadas em faixas compartilhadas:
index.html (raiz, 1080x1920, data-composition-id="main")
├── ambient-bg.html track-index="3" — gradiente radial + grade de deriva + partículas + vinheta
├── face-wrapper + <video> track-index="0" — talking head (veja coreografia de modo-rosto)
├── seam-treatment.html track-index="5" — penas na borda y=960 (apenas cenas da metade inferior)
├── scene1-<label>.html track-index="1" — sobreposições de cena (em sequência, sem lacunas)
├── scene2-<label>.html track-index="1"
├── …
└── captions.html track-index="2" — legendas karaokê, sincronizadas por palavra
data-durationé idêntica entre raiz, ambient-bg, seam-treatment, face-video, face-audio, captions. Apenas as sobreposições de cena mudam ao longo do tempo.<audio>para o rosto é um elemento SEPARADO (o mixer precisa dele), nunca use a própria faixa de áudio do vídeo.class="clip"vai em divs temporizadas — NUNCA em<video>ou<audio>.
Coreografia de modo-rosto (o movimento característico do short-form)
O rosto vive em um div wrapper dimensionado no paisagem nativo da fonte (1920x1080). O GSAP anima o WRAPPER (nunca o elemento de vídeo — animar dimensões de <video> congela quadros).
Dois modos:
const BOTTOM = { x: 0, y: 1136, scale: 0.5625 }; // metade inferior, paisagem completo visível
const FULLSCREEN = { x: -1166.5, y: 0, scale: 1.7778 }; // recortado para preencher, preenche 1080x1920
const MODE_DUR = 0.32;
BOTTOM renderiza a fonte 1920x1080 a 1080x607.5 centrada nos 960px inferiores. FULLSCREEN corta horizontalmente para preencher o quadro retrato.
Transição 0.15s ANTES do novo conteúdo da cena chegar, usando ease: "expo.inOut":
[
{ t: <scene-4-start>, mode: FULLSCREEN },
{ t: <scene-5-start>, mode: BOTTOM },
…
].forEach(({ t, mode }) => {
mainTl.to("#face-wrapper", { ...mode, duration: MODE_DUR, ease: "expo.inOut" }, t - 0.15);
});
Um rosto que muda de modo instantaneamente é o quadro mais chocante em um vídeo vertical. Sempre interpole.
Gradação de rosto (todo short, sem exceções)
#face-video {
filter: contrast(1.08) saturate(1.08) brightness(0.97);
}
Mais um zoom Ken Burns sutil de 1.00 → 1.025 ao longo da duração total (ease: "none") e um pseudo-elemento ::after de vinheta lateral para que o rosto se funda ao azul-marinho circundante, em vez de se chocar contra uma borda cortante.
Tratamento de emenda (obrigatório para cenas da metade inferior)
Uma faixa de gradiente azul-marinho→transparente (60–100px) em y=960 mais uma linha de varredura de acento de 2px com brilho suave. Desenhe DEPOIS do rosto para que fique por cima; cenas de tela cheia a cobrirão quando assumirem. Cortes nítidos em y=960 são o #2 sinal de conteúdo editado por IA (depois da planura do fundo).
Protocolo de sincronização de áudio (NÃO pule)
Problema: se o áudio for editado (retakes/pausas removidos), os timestamps na transcrição de origem não correspondem mais ao vídeo editado. Os inícios de cena criados no tempo original dispararão tarde.
A regra: TODOS os timings vivem no tempo editado. Nunca misture.
Procedimento de verificação para qualquer re-temporização de short-form:
- Meça ambos os arquivos de áudio:
Diferença = tempo total de corte.ffprobe -v error -show_entries format=duration -of csv=p=0 assets/original.mp4 ffprobe -v error -show_entries format=duration -of csv=p=0 assets/<name>-edit.mp4 - Se estiver usando uma função
shift()emcaptions.htmlpara mapear palavras da transcrição, trate-a como a fonte da verdade. O mapashift(originalTime) = editedTimese aplica a TODOdata-startde cena também. - Deslocamentos internos de cena (dentro de
compositions/sceneN.html) são LOCAIS relativos aodata-startda cena. Se odata-startpai de uma cena estiver correto no tempo editado, os deslocamentos internos permanecem corretos SEM modificação — A MENOS QUE uma cena atravesse um corte, caso em que tanto a duração pai quanto os deslocamentos internos mudam. - Os tempos do array de transição de modo-rosto DEVEM usar o tempo editado. Eles NÃO são deslocados automaticamente.
Formato do plano para re-temporizações (use esta estrutura de tabela toda vez):
| Cena | Início atual | Duração atual | Novo início | Nova duração | Justificativa |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |
Depois o array de modo-rosto, depois quaisquer alterações de deslocamento interno, depois a lista de verificação de quadro.
Criação de cena
Uma cena = um arquivo de sub-composição. As cenas ficam no mesmo data-track-index em sequência (sem lacunas). Dentro de cada cena:
data-durationcorresponde exatamente ao slot do pai- Todas as âncoras do GSAP são LOCAIS (baseadas em 0 a partir do início da cena)
- Use
tl.set({}, {}, <data-duration>)para preencher a timeline para quetl.duration()do GSAP corresponda adata-duration
Regras de ritmo de cena (dos 10 princípios)
- Sem quadros mortos. A cada 100ms há ≥1 elemento animando. Desloque a primeira entrada 0.1–0.3s, não t=0.
- Payoff ≥ 1s de espera. A "grande revelação" da cena (selo, trava de número, punchline) deve ter ≥1s na tela, idealmente 1.5s. Orce as cenas pelo tempo de revelação, não pelo tempo total.
- Movimento ao longo da duração total. Se as animações de entrada terminarem aos 2s locais de uma cena de 4s, adicione movimento secundário: varreduras de sublinhado, pops de marca de verificação, deriva ambiente em cartões, brilhos oscilantes pequenos em pílulas. Ritmo morto = deslize para longe.
- Varie as atenuações. Pelo menos 3 atenuações diferentes por cena entre as entradas.
- Um impacto por 5s de tempo de execução. Batida de tipografia, revelação glitch/cromática, whip-pan, batida sincronizada com áudio. Sem estes, o vídeo é lido como "talking head legendado" — correto, mas esquecível.
Legendas (estilo karaokê)
- Montserrat 900, 46–58px (para largura 1080), base 100% branca
- Palavra ativa: pop scale-1.08 + mudança de cor para acento (
#37bdf8para AIS, adapte à marca) - Traço via
text-shadowem camadas, NUNCA-webkit-text-stroke(renderiza inconsistentemente no renderizador Chromium) - Remova a pílula de fundo rgba — deixe o traço manter a legibilidade. As legendas devem parecer graffiti no quadro, não uma faixa de legenda.
- Para re-temporizações, use uma função
shift()dentro decaptions.htmlpara mapear timestamps de palavras da transcrição → tempo editado. Isso mantém o JSON da transcrição intacto e torna as re-temporizações mecânicas.
Veja references/captions.md em /hyperframes para a implementação completa do karaokê. Resumo: elementos <span> por palavra com data-word-start, tweens do GSAP com escopo em cada span, durações de pop curtas de 0.08–0.12s.
Fundo ambiente (nunca envie azul-marinho liso)
Pilha mínima de fundo viável:
- Base de gradiente radial (centro mais claro que as bordas em 15–20%)
- Sobreposição de ruído/grão animado a 8–12% de opacidade
- 4–8 pontos de partícula flutuantes ou traços de grade
- Vinheta sutil
background: #07121c sozinho é um placeholder, não um design. Para estética técnica/sala de controle, use a pilha de 6 camadas de feedback_techy_background_layers.md (grade HUD mascarada para vinheta + traços de circuito + nós de pulso + feixe de varredura + ticker de telemetria + etiquetas de canto mono).
Reatividade de áudio
- Manchetes pulsam 3–6% na batida. Fundos podem ir 10–30% no grave.
- Reatividade de texto mantida sutil (3–6%) para que as legendas permaneçam legíveis; fundos podem forçar mais.
- Use um analisador offline SEMEADO (pré-calcule a faixa de recurso de áudio) para que as renderizações sejam determinísticas. NÃO use
AnalyserNodeno caminho de renderização —Math.random()e nós de áudio em tempo real quebram o determinismo.
Transições
- Varie os sabores. Nenhuma duas transições consecutivas do mesmo tipo. Seis cortes secos seguidos são o #1 sinal de edição por IA.
- Transições de modo-rosto (
BOTTOM ↔ FULLSCREEN) funcionam como transições de cena quando o modo muda entre cenas. - Para transições puras de sobreposição de cena, instale do registro:
push-up,flash-through-white,sdf-iris, ou o pacote completo de shader-transitions.npx hyperframes catalog --type blockpara navegar.
A porta de verificação (obrigatório — NÃO envie sem)
Passar no lint não significa que o design funciona. Nunca relate uma renderização de short-form como concluída até que você tenha extraído quadros em timestamps exatos de palavras e LIDO cada PNG.
Passo 1 — Renderização de rascunho
cd video-projects/<slug>
npx hyperframes lint
npx hyperframes render --quality draft --output renders/<slug>-vN-draft.mp4
Passo 2 — Extração de quadro exato de palavra
Escolha 8–15 timestamps que cada um corresponda a uma PALAVRA FALADA onde um visual específico deve estar na tela. Não números redondos. Não meio de cena. A palavra exata.
mkdir -p renders/frames-vN
for pair in "<t>:<label>" "<t>:<label>" ...; do
t="${pair%%:*}"; label="${pair##*:}"
ffmpeg -y -ss "$t" -i renders/<slug>-vN-draft.mp4 \
-frames:v 1 -q:v 2 "renders/frames-vN/t${t}-${label}.png"
done
Passo 3 — Leia cada PNG
Chame Read em cada PNG para que a imagem seja carregada no contexto. NÃO liste apenas nomes de arquivos. Para cada quadro confirme:
- O visual esperado está na tela no momento esperado (não 1s atrasado, não adiantado)
- O rosto do falante não está cortado em nenhuma cena da metade inferior
- O modo de rosto tela cheia vs. metade inferior está correto para aquela cena
- As legendas estão na marca, legíveis, não transbordando
- Sem quadros em branco, sem sobreposição não intencional, sem texto fora da tela
Passo 4 — se algo falhar, corrija + re-verifique. Nunca envie quebrado.
Passo 5 — Renderização final
npx hyperframes render --quality standard --output renders/<slug>-vN.mp4
Verifique 3–4 quadros da renderização final (mesmos timestamps, pasta diferente frames-vN-final/) para confirmar que a codificação de qualidade padrão não mudou nada.
As 10 regras (checklist de qualidade — execute ANTES do primeiro rascunho)
Cada construção short-form. Execute esta lista durante a criação, não depois.
- Sem quadros mortos. A cada 100ms há um elemento animando.
- Payoff de cena ≥ 1s de espera. Orce pelo tempo de revelação, não pelo tempo total.
- Rosto é um personagem. Gradação + Ken Burns + vinheta lateral.
- Sem emendas duras. Penas em y=960 com gradiente + linha de varredura.
- Um impacto por 5s. Batida de tipografia, glitch, whip-pan, batida de áudio.
- Reatividade de áudio inegociável. 3–6% texto, 10–30% fundo.
- Varie os sabores de transição. Nenhuma duas consecutivas iguais.
- Legendas pop, não etiquetam educadamente. Traço, não pílula. Escala + cor na palavra ativa.
- Movimento ao longo da duração total da cena. Movimento secundário se as entradas terminarem cedo.
- Fundo é uma camada, não uma cor. Radial + ruído + partículas + vinheta mínimo.
- Sobreposições de impacto/selo chegam DEPOIS que o texto alvo está totalmente visível. Lógica de revelação > sincronia de palavra. Selo
t≥ alvo-visívelt+ 0.10–0.25s. Caso contrário, a punchline chega antes da configuração.
Estrutura do projeto (cada projeto short-form)
video-projects/<slug>/
├── hyperframes.json
├── meta.json (id, name, dimensions 1080x1920, fps 30)
├── index.html (composição raiz, o andaime de 4 camadas)
├── compositions/
│ ├── ambient-bg.html
│ ├── seam-treatment.html
│ ├── captions.html (com função shift() se re-temporizando)
│ ├── scene1-<label>.html
│ ├── scene2-<label>.html
│ └── ...
├── assets/
│ ├── <name>.mp4 (gravação original)
│ ├── <name>-edit.mp4 (editada — cortes removidos — esta é a que a composição usa)
│ ├── transcript.json (saída do whisper)
│ └── brand assets (logo, brand-tokens.css, música de fundo)
└── renders/
├── <slug>-v1-draft.mp4
├── frames-v1/
├── <slug>-v1.mp4
└── ...
Protocolo de re-temporização (quando o áudio é re-editado ou os timestamps derivam)
- Meça as durações de áudio editado antigo e novo com
ffprobe. Delta = tempo total de corte. - Identifique a(s) janela(s) de corte: quais segundos foram removidos, de onde.
- Escreva a tabela do Plano: cada
data-startde cena,data-duration, cada transição de modo-rostot, qualquer cena cujos deslocamentos internos atravessem um corte. - Para cada cena que atravessa um corte, ajuste seu
data-startedata-duratione também seus deslocamentos internos. Cenas que não atravessam cortes mantêm sua estrutura interna inalterada. - Atualize o array de modo-rosto com os novos tempos.
- Execute a verificação de quadro.