Communitygithub.com

alecramos-sudo/hyperframes-skill

Crie composições de vídeo, animações, cartelas, sobreposições, legendas, narrações, visuais reativos a áudio e transições de cena em HyperFrames HTML.

O que é hyperframes-skill?

Esta skill capacita o agente a atuar como um compositor de vídeo baseado em HTML, utilizando o framework HyperFrames. Ela permite criar desde composições simples até produções complexas com múltiplas cenas, animações sincronizadas, legendas automáticas e efeitos visuais reativos ao áudio, como batidas e pulsos. A skill é útil para desenvolvedores e criadores que desejam um controle preciso sobre cada frame do vídeo, usando HTML, CSS e JavaScript como fonte única da verdade. Ela suporta plataformas como Claude Code, Cursor e Codex, e seu fluxo de trabalho inclui a definição de uma identidade visual antes de qualquer codificação, a construção do layout final antes da animação, e regras rigorosas para transições de cena e sincronismo de timeline. A documentação completa (SKILL.md) detalha atributos data-*, estrutura de subcomposições, manipulação de mídia e contratos de timeline com GSAP, garantindo composições determinísticas e sem bugs comuns como loops infinitos ou animações assíncronas.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add alecramos-sudo/hyperframes-skill

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Prévia

Do README da skill

Documentação

HyperFrames

HTML é a fonte única da verdade para 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:

  1. O quê — o que o espectador deve experimentar? Identifique o arco narrativo, os momentos-chave e os batimentos emocionais.
  2. Estrutura — quantas composições, quais são subcomposições vs inline, quais trilhas carregam o quê (vídeo, áudio, sobreposições, legendas).
  3. Temporização — quais clipes determinam a duração, onde as transições ocorrem, qual é o ritmo.
  4. Layout — construa o estado final primeiro. Veja "Layout Antes da Animação" abaixo.
  5. Animar — então 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:

  1. Existe DESIGN.md no projeto? → Leia-o. Use suas cores exatas, fontes, regras de movimento e restrições do "O que NÃO Fazer".
  2. Existe visual-style.md? → Leia-o. Aplique seu style_prompt_full e 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.)
  3. O usuário nomeou um estilo (ex.: "Swiss Pulse", "escuro e tecnológico", "marca de luxo")? → Leia visual-styles.md para os 8 presets nomeados. Gere um DESIGN.md mínimo com: ## Prompt de Estilo (um parágrafo), ## Cores (3-5 valores hex com funções), ## Tipografia (1-2 famílias de fontes), ## O que NÃO Fazer (3-5 anti-padrões).
  4. Nenhum dos acima? → 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 de marca, fonte ou referência visual específica? Em seguida, gere um DESIGN.md mínimo a partir das respostas.

Cada composição deve traçar sua paleta e tipografia de volta a um DESIGN.md, visual-style.md ou direção explícita do usuário. Se você estiver recorrendo a #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 house style 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 em 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. Ainda sem GSAP.

Por que isso importa: Se você posicionar os elementos em seu estado inicial animado (fora da tela, escalados para 0, opacidade 0) e os tween para onde você acha que devem chegar, você está adivinhando o layout final. Sobreposições ficam invisíveis até o vídeo ser renderizado. Construindo o estado final primeiro, você pode ver e corrigir problemas de layout antes de adicionar qualquer movimento.

O processo

  1. Identifique o quadro herói para cada cena — o momento em que o maior número de elementos está simultaneamente visível. Este é o layout que você constrói.
  2. Escreva CSS estático para esse quadro. O contêiner .scene-content DEVE preencher toda a cena usando width: 100%; height: 100%; padding: Npx; com display: flex; flex-direction: column; gap: Npx; box-sizing: border-box. Use padding para empurrar o conteúdo para dentro — NUNCA use position: absolute; top: Npx em um contêiner de conteúdo. Contêineres de conteúdo com posicionamento absoluto transbordam quando o conteúdo é mais alto que o espaço restante. Reserve position: absolute apenas para elementos decorativos.
  3. Adicione entradas com gsap.from() — anime DE fora da tela/invisível PARA a posição CSS. A posição CSS é a verdade absoluta; o tween descreve a jornada para chegar lá.
  4. Adicione saídas com gsap.to() — anime PARA fora da tela/invisível A PARTIR da posição 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 contêiner preenche qualquer tamanho de cena (1920x1080, 1080x1920, etc.).
   O padding posiciona o conteúdo. Flex + gap lida 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);

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 herói. 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 em z (pilhas de cartões, camadas de profundidade) são intencionais. A etapa de layout é para detectar sobreposições não intencionais — dois títulos caindo um em cima do outro, uma estatística cobrindo um rótulo, conteúdo vazando para fora do quadro.

Atributos de Dados

Todos os Clipes

AtributoObrigatórioValores
idSimIdentificador único
data-startSimSegundos ou referência de ID de clipe ("el-1", "intro + 2")
data-durationObrigatório para img/div/composiçõesSegundos. Vídeo/áudio usa a duração da mídia como padrão.
data-track-indexSimInteiro. Clipes na mesma trilha não podem se sobrepor.
data-media-startNãoDeslocamento de corte na fonte (segundos)
data-volumeNão0-1 (padrão 1)

data-track-index não afeta a camada visual — use CSS z-index.

Clipes de Composição

AtributoObrigatórioValores
data-composition-idSimID único da composição
data-startSimTempo de início (composição raiz: use "0")
data-durationSimTem precedência sobre a duração da timeline GSAP
data-width / data-heightSimDimensões em pixels (1920x1080 ou 1080x1920)
data-composition-srcNãoCaminho para arquivo HTML externo

Estrutura da Composição

Subcomposições carregadas via data-composition-src usam um wrapper <template>. Composições independentes (o index.html principal) NÃO usam <template> — elas colocam a 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 de subcomposiçã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 = gsap.timeline({ paused: true });
      // tweens...
      window.__timelines["my-comp"] = tl;
    </script>
  </div>
</template>

Carregar na raiz: <div id="el-1" data-composition-id="my-comp" data-composition-src="compositions/my-comp.html" data-start="0" data-duration="10" data-track-index="1"></div>

Vídeo e Áudio

O vídeo deve ter muted playsinline. O áudio é sempre um elemento <audio> separado:

<video
  id="el-v"
  data-start="0"
  data-duration="30"
  data-track-index="0"
  src="video.mp4"
  muted
  playsinline
></video>
<audio
  id="el-a"
  data-start="0"
  data-duration="30"
  data-track-index="2"
  src="video.mp4"
  data-volume="1"
></audio>

Contrato de Timeline

  • Todas as timelines começam { paused: true } — o player controla a reprodução
  • Registre cada timeline: window.__timelines["<id-da-composição>"] = tl
  • O framework aninha sub-timelines automaticamente — NÃO as adicione manualmente
  • A duração vem de data-duration, não da extensão da timeline GSAP
  • Nunca crie tweens vazios para definir duração

Regras (Não Negociáveis)

Determinístico: Sem Math.random(), Date.now() ou lógica baseada em tempo. Use um PRNG com semente se precisar de valores pseudo-aleatórios (ex.: mulberry32).

GSAP: Anima apenas propriedades visuais (opacity, x, y, scale, rotation, color, backgroundColor, borderRadius, transformações). NÃO anime visibility, display ou chame video.play()/audio.play().

Conflitos de animação: Nunca anime a mesma propriedade no mesmo elemento de múltiplas timelines simultaneamente.

Sem repeat: -1: Timelines com repetição infinita quebram o mecanismo de captura. Calcule o número exato de repetições a partir da duração da composição: repeat: Math.ceil(duration / cycleDuration) - 1.

Construção síncrona de timeline: Nunca construa timelines dentro de async/await, setTimeout ou Promises. O mecanismo de captura lê window.__timelines de forma síncrona após o carregamento da página. As fontes são incorporadas pelo compilador, portanto estão disponíveis imediatamente — não há necessidade de esperar pelo carregamento de fontes.

Nunca faça:

  1. Esqueça o registro de window.__timelines
  2. Use vídeo para áudio — sempre vídeo mudo + <audio> separado
  3. Aninhe vídeo dentro de uma div temporizada — use um wrapper não temporizado
  4. Use data-layer (use data-track-index) ou data-end (use data-duration)
  5. Anime as dimensões do elemento de vídeo — anime uma div wrapper
  6. Chame play/pause/seek em mídia — o framework controla a reprodução
  7. Crie um contêiner de nível superior sem data-composition-id
  8. Use repeat: -1 em qualquer timeline ou tween — sempre repetições finitas
  9. Construa timelines de forma assíncrona (dentro de async, setTimeout, Promise)
  10. Use gsap.set() em elementos de clipe de cenas posteriores — eles não existem no DOM no carregamento da página. Use tl.set(selector, vars, timePosition) dentro da timeline no tempo igual ou posterior ao data-start do clipe.
  11. Use <br> em texto de conteúdo — quebras de linha forçadas não consideram a largura real da fonte renderizada. Texto que quebra naturalmente + um <br> produz uma quebra extra indesejada, causando sobreposição. Deixe o texto quebrar via max-width. Exceção: títulos curtos de exibição onde cada palavra está deliberadamente em sua própria linha (ex.: "THE\nIMMORTAL\nGAME" a 130px).

Transições de Cena (Não Negociáveis)

Toda composição com múltiplas cenas DEVE seguir TODAS estas regras. Violar qualquer uma delas resulta em uma composição quebrada.

  1. SEMPRE use transições entre cenas. Sem cortes secos. Sem exceções.
  2. SEMPRE use animações de entrada em cada cena. Cada elemento anima ENTRANDO via gsap.from(). Nenhum elemento pode aparecer totalmente formado. Se uma cena tem 5 elementos, precisa de 5 tweens de entrada.
  3. NUNCA use animações de saída, exceto na cena final. Isso significa: NENHUM gsap.to() que anime opacidade para 0, y para fora da tela, escala para 0, ou qualquer outra animação de "saída" antes de uma transição ser disparada. A transição É a saída. O conteúdo da cena de saída DEVE estar totalmente visível no momento em que a transição começa.
  4. Apenas na cena final: A última cena pode esmaecer elementos (ex.: fade para preto). Esta é a ÚNICA cena onde gsap.to(..., { opacity: 0 }) é permitido.

ERRADO — animação de saída antes da transição:

// PROIBIDO — isso esvazia a cena antes que a transição possa usá-la
tl.to("#s1-title", { opacity: 0, y: -40, duration: 0.4 }, 6.5);
tl.to("#s1-subtitle", { opacity: 0, duration: 0.3 }, 6.7);
// transição dispara em quadro vazio

CERTO — apenas entrada, transição lida com a saída:

// Animações de entrada da Cena 1
tl.from("#s1-title", { y: 50, opacity: 0, duration: 0.7, ease: "power3.out" }, 0.3);
tl.from("#s1-subtitle", { y: 30, opacity: 0, duration: 0.5, ease: "power2.out" }, 0.6);
// SEM tweens de saída — transição em 7.2s lida com a mudança de cena
// Animações de entrada da Cena 2
tl.from("#s2-heading", { x: -40, opacity: 0, duration: 0.6, ease: "expo.out" }, 8.0);

Diretrizes de Animação

  • Desloque a primeira animação em 0.1-0.3s (não t=0)
  • Varie os eases entre os tweens de entrada — use pelo menos 3 eases diferentes por cena
  • Não repita um padrão de entrada dentro de uma cena
  • Evite gradientes lineares em tela cheia em fundos escuros (bandeamento H.264 — use radial ou sólido + brilho localizado)
  • Títulos com 60px+, corpo com 20px+, rótulos de dados com 16px+ para vídeo renderizado
  • font-variant-numeric: tabular-nums em colunas de números

Quando não houver visual-style.md ou direção de animação fornecida, siga house-style.md para padrões estéticos.

Tipografia e Assets

  • Fontes: Basta escrever o font-family desejado no CSS — o compilador incorpora as fontes suportadas automaticamente. Se uma fonte não for suportada, o compilador avisa.
  • Adicione crossorigin="anonymous" a mídia externa

Habilidades Relacionadas