HyperFrames
Primeira vez? Execute a verificação de ambiente antes de começar:
python3 /var/minis/skills/hyperframes-cli/scripts/check-env.pyIsso verifica se
minis-browser-use,ffmpege as skills necessárias estão instalados. Se a skillhyperframes-cliestiver faltando, instale-a:python3 /var/minis/skills/hyperframes-cli/scripts/install-skill.py \ hyperframes-cli --repo heygen-com/hyperframes --subdir skills
O HTML é a fonte da verdade para o vídeo. Uma composição é um arquivo HTML com atributos data-* para temporização, uma timeline GSAP para animação e CSS para aparência. O framework gerencia a visibilidade dos clipes, a reprodução de mídia e a sincronização da timeline.
Abordagem
Antes de escrever HTML, pense em alto nível:
- O quê — o que o espectador deve experimentar? Identifique o arco narrativo, os momentos-chave e os pontos emocionais.
- Estrutura — quantas composições, quais são sub-composições versus inline, quais faixas carregam o quê (vídeo, áudio, sobreposições, legendas).
- Temporização — quais clipes definem a duração, onde ocorrem as transições, qual é o ritmo.
- Layout — construa o estado final primeiro. Veja "Layout Antes da Animação" abaixo.
- Animar — depois adicione movimento usando as regras abaixo.
Para pequenas edições (corrigir uma cor, ajustar temporização, adicionar um elemento), vá direto para as regras.
Portão de Identidade Visual
Verifique nesta ordem:
- Existe um DESIGN.md no projeto? → Leia-o. Use suas cores exatas, fontes, regras de movimento e restrições de "O que NÃO Fazer".
- Existe um visual-style.md? → Leia-o. Aplique seu
style_prompt_fulle campos estruturados. (Nota:visual-style.mdé um arquivo específico do projeto.visual-styles.mdé a biblioteca de estilos com 8 presets nomeados — arquivos diferentes.) - O usuário nomeou um estilo (ex.: "Swiss Pulse", "dark and techy", "luxury brand")? → Leia visual-styles.md para os 8 presets nomeados. Gere um DESIGN.md mínimo com:
## Style Prompt(um parágrafo),## Colors(3-5 valores hex com funções),## Typography(1-2 famílias de fontes),## What NOT to Do(3-5 anti-padrões). - Nenhum dos anteriores? → Faça 3 perguntas antes de escrever qualquer HTML:
- Qual é o clima? (explosivo / cinematográfico / fluido / técnico / caótico / acolhedor)
- Tela clara ou escura?
- Alguma cor, fonte ou referência visual específica da marca? Em seguida, gere um DESIGN.md mínimo a partir das respostas.
Cada composição deve ter sua paleta e tipografia vinculadas a um DESIGN.md, visual-style.md ou direção explícita do usuário. Se você está usando #333, #3b82f6 ou Roboto — você pulou esta etapa.
Para padrões de movimento, dimensionamento, padrões de entrada e easing — siga house-style.md. O estilo da casa lida com COMO as coisas se movem. O DESIGN.md lida com a APARÊNCIA das coisas.
Layout Antes da Animação
Posicione cada elemento onde ele deve estar no seu momento mais visível — o quadro em que ele entrou completamente, está corretamente posicionado e ainda não está saindo. Escreva isso como HTML+CSS estático primeiro. Nada de GSAP ainda.
Por que isso é importante: Se você posicionar os elementos em seu estado inicial animado (fora da tela, escalados para 0, opacidade 0) e fizer a transição para onde você acha que devem estar, você está adivinhando o layout final. Sobreposições ficam invisíveis até o vídeo ser renderizado. Ao construir o estado final primeiro, você pode ver e corrigir problemas de layout antes de adicionar qualquer movimento.
O processo
- Identifique o quadro principal de cada cena — o momento em que o maior número de elementos está simultaneamente visível. Este é o layout que você constrói.
- Escreva CSS estático para esse quadro. O container
.scene-contentDEVE preencher a cena inteira usandowidth: 100%; height: 100%; padding: Npx;comdisplay: flex; flex-direction: column; gap: Npx; box-sizing: border-box. Use padding para empurrar o conteúdo para dentro — NUNCA useposition: absolute; top: Npxem um container de conteúdo. Containers de conteúdo com posicionamento absoluto transbordam quando o conteúdo é mais alto que o espaço restante. Reserveposition: absoluteapenas para elementos decorativos. - Adicione entradas com
gsap.from()— anime DE fora da tela/invisível PARA a posição do CSS. A posição CSS é a verdade absoluta; o tween descreve a jornada para chegar lá. - Adicione saídas com
gsap.to()— anime PARA fora da tela/invisível DA posição do CSS.
Exemplo
/* scene-content preenche a cena, padding posiciona o conteúdo */
.scene-content {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 100%;
padding: 120px 160px;
gap: 24px;
box-sizing: border-box;
}
.title {
font-size: 120px;
}
.subtitle {
font-size: 42px;
}
/* O container preenche qualquer tamanho de cena (1920x1080, 1080x1920, etc.).
O padding posiciona o conteúdo. Flex + gap lidam com o espaçamento. */
ERRADO — dimensões fixas e posicionamento absoluto:
.scene-content {
position: absolute;
top: 200px;
left: 160px;
width: 1920px;
height: 1080px;
display: flex; /* ... */
}
// Etapa 3: Anime PARA essas posições
tl.from(".title", { y: 60, opacity: 0, duration: 0.6, ease: "power3.out" }, 0);
tl.from(".subtitle", { y: 40, opacity: 0, duration: 0.5, ease: "power3.out" }, 0.2);
tl.from(".logo", { scale: 0.8, opacity: 0, duration: 0.4, ease: "power2.out" }, 0.3);
// Etapa 4: Anime PARA FORA dessas posições
tl.to(".title", { y: -40, opacity: 0, duration: 0.4, ease: "power2.in" }, 3);
tl.to(".subtitle", { y: -30, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.1);
tl.to(".logo", { scale: 0.9, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.2);
Composições multicena: um container por cena
Quando uma composição tem múltiplas cenas que aparecem sequencialmente (A sai, depois B entra), nunca coloque todos os elementos de todas as cenas em um único container flex compartilhado. Mesmo que cada elemento comece com opacity: 0, o flex ainda aloca altura para cada filho. Com conteúdo de 5 cenas em um container, a altura total do container excede em muito a altura do palco — o flex justify-content: center então centraliza o conteúdo em relação a esse container superdimensionado, empurrando o conteúdo visível para fora do corte da captura de tela.
ERRADO — todas as cenas em um container flex:
<div class="scene-content"> <!-- flex column, height:100% -->
<!-- Elementos da Cena A -->
<div id="title-a" style="opacity:0">Título A</div>
<div id="body-a" style="opacity:0">Corpo A</div>
<!-- Elementos da Cena B — também ocupam altura flex mesmo quando invisíveis -->
<div id="title-b" style="opacity:0">Título B</div>
<div id="body-b" style="opacity:0">Corpo B</div>
<!-- Cena C ... -->
</div>
CERTO — cada cena é sua própria camada absoluta:
<!-- Cena A -->
<div class="scene" id="scene-a">
<div id="title-a" style="opacity:0">Título A</div>
<div id="body-a" style="opacity:0">Corpo A</div>
</div>
<!-- Cena B — sem impacto na altura da Cena A -->
<div class="scene" id="scene-b">
<div id="title-b" style="opacity:0">Título B</div>
<div id="body-b" style="opacity:0">Corpo B</div>
</div>
/* Cada cena preenche o palco independentemente */
.scene {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 80px 120px;
box-sizing: border-box;
z-index: 2;
gap: 24px;
}
Este é o único padrão correto para cenas sequenciais. O position: absolute; inset: 0 em cada container de cena NÃO entra em conflito com a diretriz "Layout Antes da Animação" — essa diretriz proíbe o posicionamento absoluto de elementos de conteúdo (títulos, cards, estatísticas) com deslocamentos em pixels fixos. Containers de cena que preenchem o palco inteiro via inset: 0 estão corretos e são obrigatórios.
Quando elementos compartilham espaço ao longo do tempo
Se o elemento A sai antes do elemento B entrar na mesma área, ambos devem ter posições CSS corretas para seus respectivos quadros principais. A ordenação da timeline garante que eles nunca coexistam visualmente — mas se você pular a etapa de layout, não perceberá o caso em que eles acidentalmente se sobrepõem devido a um erro de temporização.
O que conta como sobreposição intencional
Efeitos em camadas (brilho atrás do texto, elementos de sombra, padrões de fundo) e designs empilhados (pilhas de cards, camadas de profundidade) são intencionais. A etapa de layout serve para detectar sobreposições não intencionais — dois títulos caindo um sobre o outro, uma estatística cobrindo um rótulo, conteúdo vazando para fora do quadro.
Atributos de Dados
Todos os Clipes
| Atributo | Obrigatório | Valores |
|---|---|---|
id | Sim | Identificador único |
data-start | Sim | Segundos ou referência de ID do clipe ("el-1", "intro + 2") |
data-duration | Obrigatório para img/div/compos | Segundos. Vídeo/áudio usa por padrão a duração da mídia. |
data-track-index | Sim | Inteiro. Clipes na mesma faixa não podem se sobrepor. |
data-media-start | Não | Deslocamento de corte na origem (segundos) |
data-volume | Não | 0-1 (padrão 1) |
data-track-index NÃO afeta a camada visual — use CSS z-index.
Clipes de Composição
| Atributo | Obrigatório | Valores |
|---|---|---|
data-composition-id | Sim | ID único da composição |
data-start | Sim | Tempo de início (composição raiz: use "0") |
data-duration | Sim | Tem precedência sobre a duração da timeline GSAP |
data-width / data-height | Sim | Dimensões em pixels (1920x1080 ou 1080x1920) |
data-composition-src | Não | Caminho para arquivo HTML externo |
Estrutura da Composição
Sub-composições carregadas via data-composition-src usam um invólucro <template>. Composições independentes (o index.html principal) NÃO usam <template> — elas colocam o div data-composition-id diretamente no <body>. Usar <template> em um arquivo independente esconde todo o conteúdo do navegador e quebra a renderização.
Estrutura da sub-composição:
<template id="my-comp-template">
<div data-composition-id="my-comp" data-width="1920" data-height="1080">
<!-- conteúdo -->
<style>
[data-composition-id="my-comp"] {
/* estilos escopados */
}
</style>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>
window.__timelines = window.__timelines || {};
const tl =