MÓDULO 2.1

🎬 Primeiro vídeo completo

Clonar o projeto claude-edit-intro, adaptar para sua marca e executar o loop completo: edit → lint → preview → draft → verify → final.

6
Tópicos
60
Minutos
Intermed.
Nível
Prática
Tipo
1

📋 As 11 regras do Render Contract

O Render Contract do CLAUDE.md lista 11 regras não-negociáveis para composições Hyperframes. Quebrar qualquer uma faz o render falhar ou sair com bug visual. É o equivalente a "tem que ter Doctype" no HTML.

📜 As 11 regras

  1. Root div precisa de id, data-composition-id, data-start="0", data-width, data-height
  2. Elementos visíveis temporizados precisam de class="clip" — exceto <video> e <audio>
  3. Todo elemento temporizado precisa de data-start, data-duration, data-track-index
  4. data-start pode referenciar outro clip: "intro + 2", "intro - 0.5"
  5. <video> deve ser muted; áudio vai em <audio> irmão
  6. Toda composição registra uma timeline GSAP pausada em window.__timelines
  7. Duração = tl.duration(). Se timeline < vídeo, o vídeo trunca
  8. Nunca .play(), .pause() ou set .currentTime manualmente em mídia
  9. Nunca animar width/height/top/left diretamente em <video> — wrap em <div>
  10. Sub-composições usam <template> com data-composition-src
  11. Determinismo: sem Date.now(), sem Math.random() unseeded, sem fetch de rede
2

⏱️ window.__timelines e GSAP

Cada composição registra uma GSAP timeline pausada em window.__timelines["composition-id"]. A chave deve bater exatamente com o data-composition-id.

📝 Pattern mínimo

<div id="my-scene" data-composition-id="my-scene" data-start="0" data-width="1920" data-height="1080">
  <h1 class="clip" data-start="0" data-duration="3" data-track-index="0">Olá</h1>
</div>

<script>
(function() {
  const tl = gsap.timeline({paused: true});
  tl.from("#my-scene h1", {opacity: 0, y: 40, duration: 0.6, ease: "expo.out"});
  tl.set({}, {}, 3); // estende duração para 3s
  window.__timelines = window.__timelines || {};
  window.__timelines["my-scene"] = tl;
})();
</script>
3

🎬 data-start, data-duration, data-track-index

Três atributos que definem quando um clip aparece, quanto dura e em qual track. Suportam timing relativo para composições ganharem legibilidade.

data-start

Quando o clip aparece. Pode ser número (2.5) ou referência a outro id ("intro + 2").

data-duration

Quanto tempo o clip fica visível. Em segundos (pode ter decimais).

data-track-index

Camada vertical. Clips no mesmo track não podem se sobrepor em tempo.

⚠️ Armadilha

Dois clips com data-track-index="0" sobrepostos em tempo = erro de lint. Use tracks diferentes (0, 1, 2...) ou ajuste timing.

4

📦 Sub-composições com template

Sub-composições são carregadas via <template> com data-composition-src. As timelines se linkam automaticamente ao parent.

📝 Como carregar sub-composição

<template data-composition-src="compositions/intro.html"
          data-start="0"
          data-duration="5"
          data-track-index="0"></template>

⚠️ Nunca

Não chame masterTL.add(childTL). O framework já faz isso automaticamente baseado no data-composition-src.

5

🎞️ Por que video não leva clip

Tags <video> e <audio> são a única exceção à regra de class="clip". Adicionar class="clip" em <video> quebra o elemento. Animar width/height diretamente congela frames.

✓ FAZER

  • <video muted> sem class="clip"
  • Áudio em <audio> irmão
  • data-start e data-duration normalmente
  • Wrap em <div> e animar o wrapper

✗ NÃO FAZER

  • class="clip" no <video>
  • Animar width/height no <video> direto
  • Chamar .play()/.pause() manualmente
  • Setar .currentTime no seu código

💡 data-has-audio

Se quiser que o áudio nativo do <video> entre no mixer, adicione data-has-audio="true". Por padrão o mixer ignora áudio de videos e usa apenas <audio> irmãos.

6

✅ Verificação visual de frames

Lint passar ≠ design funcionar. Um render "bem-sucedido" com rosto cortado, texto desalinhado ou cena na palavra errada é render quebrado — e lint não pega nada disso.

🔍 Protocolo de verificação

# 1. Render draft
npx hyperframes render --quality draft --output renders/draft.mp4

# 2. Puxar frame por cena (ajuste timestamps para suas cenas)
mkdir -p renders/frames
for t in 1 3 5 7 9 11; do
  ffmpeg -y -ss $t -i renders/draft.mp4 -frames:v 1 -q:v 2 "renders/frames/t${t}.png"
done

# 3. Abrir cada PNG e verificar:
# - Rostos não cortados
# - Texto alinhado e sem overlap
# - Cenas na palavra correta
# - Nenhum frame em branco

⚠️ Regra de ouro

Nunca entregue sem ter OLHADO cada frame-chave. Se encontrou bug, corrige, re-renderiza, re-verifica. Só então roda o --quality standard e entrega.

📋 Resumo do Módulo

11 regras do Render Contract decoradas — checkpoints obrigatórios
window.__timelines dominado — chave bate com data-composition-id
Atributos de timing aplicados — data-start, duration, track-index
Sub-composições funcionando — template + data-composition-src
Vídeo sem class="clip" corretamente — wrap em div para animar
Verificação visual de frames feita — lint + olho humano antes de entregar

Próximo Módulo:

2.2 - Pitch Deck + Vídeo Sizzle