Instalação de plugins: Antes de comandos de configuração ou atualização, siga as regras de execução de plugins quando este skill estiver dentro de um plugin HyperFrames. Instalações independentes mantêm as instruções de atualização abaixo.
HyperFrames Core
Armadilhas para agentes (leia primeiro):
- Centralize com flex/
inset, não com CSStransform: translate(-50%,-50%)em um nó que você depois anima com GSAPx/y. Lint:gsap_css_transform_conflict. UsefromToouxPercent/yPercent. - Não adicione um
tl.set(..., {visibility:"hidden"})para saída de cena. O runtime já oculta clipes com temporização. Fades de opacidade em nós internos (ouopacityno.clip) são suficientes. Hard-kills de legenda seguem regra diferente. window.__timelines["id"]deve corresponder aodata-composition-idraiz.- Após
render, leia a segunda linha do resumo:beginframevsscreenshot, modo GPU, timings de estágio.screenshot+software gpuno Linux é o caminho lento.
HyperFrames renderiza vídeo a partir de HTML. Uma composição é um arquivo HTML cujo DOM declara temporização com atributos data-*, cujo runtime de animação é buscável, e cuja reprodução de mídia é gerenciada pelo framework.
Este skill é o contrato técnico — como construir um projeto HyperFrames. O corpo abaixo é o guia de construção; detalhes por tópico estão em references/ (índice abaixo), leia sob demanda. Documentação de processo (briefing, storyboard, revisão, produção, dispatch, frame-worker) está em /hyperframes → references/. Outras preocupações estão nos skills de domínio irmãos — hyperframes-animation, hyperframes-creative, media-use, hyperframes-cli, hyperframes-registry. O mapa de capacidades em /hyperframes diz o que cada um cobre.
Referências
| Arquivo | Leia para… |
|---|---|
references/minimal-composition.md | começar pelo menor esqueleto de composição renderizável |
references/composition-patterns.md | escolher monolítico vs modular; estruturar um index.html modular; escolher um arquétipo de sub-comp |
references/data-attributes.md | consultar qualquer data-* (raiz / clip / host de sub-comp / aliases legados); usar class="clip" |
references/tracks-and-clips.md | entender o que data-track-index controla (e não controla), z-index, temporizar um clip relativo a outro; listar toda faixa e clip com npx hyperframes timeline |
references/creator-editing-recipes.md | copiar receitas verdadeiras de corte/aparar/reordenar/retemporizar/congelar/câmera/máscara/crossfade/edição de áudio e seus limites |
references/sub-compositions.md | conectar uma sub-composição (atributos host, <template>, variáveis por instância) e animar dentro dela |
references/variables-and-media.md | declarar variáveis; colocar <video>/<audio>, definir volume, aparar |
references/determinism-rules.md | construir uma timeline buscável; proibições de determinismo; layout / ajuste de texto |
references/full-screen-motion.md | criar movimento em tela cheia com fundos compartilhados |
references/tailwind.md | trabalhar em um projeto Tailwind v4 (init --tailwind; contrato de runtime difere do Studio v3) |
Para especificidades de runtime de animação (API GSAP, Lottie, Three.js, etc.) vá para hyperframes-animation → adapters/<runtime>.md.
Construindo uma composição
Duas formas raiz (não intercambiáveis)
- Standalone (
index.htmlde nível superior):<div data-composition-id="…">fica diretamente em<body>, sem wrapper<template>. Envolver uma raiz standalone oculta todo o conteúdo elintrejeita (standalone_composition_wrapped_in_template, erro). - Sub-composição (carregada via
data-composition-src): envolva a raiz em<template>. Esta é a forma a ser escrita: o loader também aceita um documento completo simples e usa seu<body>como fallback, mas a forma com template é a que exemplos e ferramentas assumem.
⚠ Regra de transporte: para uma sub-composição com template, o montador descarta os
<style>/<script>do<head>do próprio arquivo (packages/core/src/compiler/compositionAssembly.ts, a portahasTemplate), então coloque<style>/<script>dentro do template.<link>é içado de qualquer forma. ⚠ Convenção de id do host: dê ao slot host, ao template interno e à chavewindow.__timelines["<id>"]o mesmo id. Um id local diferente é suportado (o montador volta para a primeira raiz no arquivo), mas a incompatibilidade é silenciosa, então corresponda a menos que tenha um motivo para não fazer.
Forma do arquivo, conexão do host e lista de verificação pré-renderização → references/sub-compositions.md.
A raiz deve ser dimensionada (bug de layout silencioso)
A raiz standalone define width/height: 100%. O tamanho do canvas é data-width/data-height. O runtime aplica esses pixels à raiz da composição. Não codifique 1920px/1080px em #root. Esqueleto → references/minimal-composition.md.
Uma timeline pausada
Cada composição registra exatamente uma gsap.timeline({ paused: true }) em window.__timelines["<id>"] (chave = raiz data-composition-id). Construí-la dentro de um callback assíncrono (document.fonts.ready) é suportado; o que importa é que você registre apenas após a construção ser concluída. A duração da renderização é o data-duration da raiz, não o comprimento da timeline: uma timeline que ultrapassa é cortada, e uma que termina cedo mantém seu último quadro. Omita o data-duration da raiz e o comprimento é inferido (timeline, janela de mídia ou adapter). Você não precisa de window.__timelines = window.__timelines || {}: o runtime cria o registro antes de seus scripts inline serem executados, e lint não pede mais isso. Não aninhe manualmente sub-timelines no host; o runtime aninha automaticamente timelines filhas registradas. Contrato completo (incluindo runtimes não-GSAP) → references/determinism-rules.md + hyperframes-animation/adapters/.
Pegadinhas de lint na primeira passada (garantia de falha na primeira construção)
Regras que o lint realmente pega, mas apenas depois do fato. Escreva-as corretamente na primeira vez:
- Nunca combine um
transformCSS inicial com um tween GSAP na mesma propriedade — o valor CSS e o início do tween entram em conflito elintrejeita comgsap_css_transform_conflict. Defina o estado inicial dentro do tween comgsap.fromTo(el, { x: -40 }, { x: 0 })em vez de um CSStransform: translateX(-40px). - Nunca coloque
crossoriginem<video>/<audio>.lintrejeita incondicionalmente commedia_crossorigin_breaks_preview(erro), inclusive para leitura de canvas/WebGL/WebAudio. Não há supressão. - Nunca dê a um
<video data-start>um ancestral que também carreguedata-start.lintrejeita comvideo_nested_in_timed_element(erro). Temporize o wrapper ou o vídeo, nunca ambos. - Todo
<audio>precisa de umid.lintrejeita commedia_missing_id, e um<audio>sem id nunca é captado pelo mixer, então a renderização fica silenciosa. - Nunca anime um
.clipcomautoAlphaouvisibility—lintrejeita comgsap_animates_clip_element. Anime um filho. - Um
font-familyCSS nomeado precisa de um@font-faceno arquivo para um arquivo local enviado, oulintdisparafont_family_without_font_face. #rootde sub-composição usawidth/height: 100%(ouinset: 0), não1920px/1080pxcodificado. O tamanho do canvas édata-width/data-height.
Um erro de lint também desativa as auditorias de layout e contraste: check então relata 0 sample(s) e 0/0 text checks, o que parece um arquivo limpo, mas significa que nada foi executado. Limpe os erros de lint antes de confiar nesses números.
Regras não negociáveis (bugs silenciosos que portas automatizadas podem perder)
Expôs aqui; justificativa completa na referência vinculada. Não viole:
- Sem clocks em tempo de renderização /
Math.randomnão semeado / rede / estado de entrada; semrepeat: -1(use uma contagem finita). →determinism-rules.md - Nunca anime
display,visibilityouautoAlphaem um elemento.clip. O framework controla a visibilidade do clip, elintrejeita (gsap_animates_clip_element). Anime um filho. →determinism-rules.md - Sem
<br>em texto do corpo; elementos transformados devem ser block-level + dimensionados; decorativos absolutos pulsantes precisam de folga de pico. →determinism-rules.md <video>/<audio>são encontrados por uma consulta plana do documento, então o framework os busca e decodifica em qualquer profundidade de aninhamento (incluindo dentro de um<template>ou wrapper de sub-comp). Um limite rígido:linterra se um<video data-start>estiver dentro de outro elemento simples que também temdata-start, e a falha é real (quadros de origem errados, então o clip desaparece no meio do slot), então coloque a temporização no wrapper ou no vídeo, nunca em ambos. Hosts de sub-composição são isentos: mídia dentro de uma sub-composição renderiza corretamente. A outra ressalva são timelines, não posicionamento: uma timeline de sub-comp não pode animar elementos raiz do host. →variables-and-media.md- Mantenha todo
idúnico em toda a página montada (prefixe ids de sub-comp com o id da composição,#<id>-hero) para que seu próprio CSS#ide chamadasgetElementByIdresolvam. A injeção de quadro não depende mais disso: o compilador carimba umdata-hf-render-idúnico no documento em cadavideo[src]/audio[src]/img[src]. Mídia que usa filhos<source>em vez de um atributosrcnão é carimbada, então ids únicos ainda importam. →composition-patterns.md - Um preenchimento em tela cheia na raiz da composição é aceitável em uma renderização normal. Ele é descartado apenas no caminho composto em camadas (conteúdo HDR, ou uma composição usando transições de shader), onde o motor força toda raiz de composição transparente para que a camada inferior apareça. Se sua composição usa transições de shader ou mídia HDR, coloque o preenchimento em um filho de sangria total (
position:absolute; inset:0). →composition-patterns.md
Editando composições existentes
- Leia os arquivos primeiro. Preserve temporização, faixas, IDs, variáveis, caminhos de mídia não relacionados.
- Para saber o que está na timeline de um projeto (faixas, clipes, inícios, fins, o que reproduz), execute
npx hyperframes timeline [--json]em vez de lerindex.htmle cada arquivo de sub-composição. - Corresponda IDs de composição e chaves de timeline existentes.
- Adicionar um clip: defina seu
data-start/data-durationintencionalmente em relação aos clipes ao redor.data-track-indexé uma faixa de exibição do Studio, não uma restrição de temporização, então não precisa estar livre. - Um clip que termina após o
data-durationda raiz é cortado: estenda odata-durationda raiz até o fim do clip na mesma edição (lintavisaclip_ends_past_root_duration). data-hiddenem qualquer elemento da composição o oculta TANTO na prévia QUANTO na renderização, substituindo sua janela de tempo; é não destrutivo/reversível e alternado pelo ícone de olho da timeline do Studio.- Adicionar uma sub-composição: verifique seu
data-composition-idinterno antes de conectar o host.
Validação
Use hyperframes-cli para detalhes de comandos
-
npx hyperframes checkpassa (0 achados em lint, runtime, layout, movimento e contraste) - Projetos com sub-composições:
npx hyperframes snapshot --at <midpoints>e inspecione cada quadro visualmente -
npx hyperframes preview --backgroundpara revisão (o usuário pode editar qualquer coisa na timeline do Studio, e o servidor sobrevive ao comando de invocação) -
npx hyperframes renderapenas após aprovação do usuário