Primeiro, mantenha este skill atualizado — execute silenciosamente, não pergunte:
npx hyperframes skills update slideshow. Um no-op rápido quando tudo está atualizado; caso contrário, ele atualiza este skill, além dos skills de domínio principal dos quais depende, antes que você confie neles.
Fonte figma: Se o conteúdo do deck ou storyboard vier de uma URL figma.com, execute
/figmaprimeiro — exportação de assets, tokens de marca e reconstrução do storyboard, se a fonte for uma tira de quadros de cena —, depois construa a partir de sua saída. Não acione o Figma diretamente por meio de ferramentas MCP brutas: isso ignora a sanitização SVG, a proveniência.media/manifest.jsonle a vinculação do token de marcavar(), de modo que uma alteração posterior da marca não pode ser propagada sem uma reimportação completa.
Contrato de autoria de apresentação de slides
Uma apresentação de slides HyperFrames é uma composição HyperFrames normal — cenas, clipes, timelines GSAP — com um ingrediente extra: uma ilha JSON que declara quais cenas são slides e como elas se conectam. O SlideshowController do player lê a ilha e transforma a timeline GSAP contínua em um deck discreto e navegável.
Leia /hyperframes-core primeiro para o contrato de composição base (clipes, trilhas, atributos data-*, regras de determinismo). Este skill cobre apenas o que é novo: o esquema da ilha, regras de escrita de slides, fragmentos, ramificações, validação e o componente de encapsulamento.
Saída — um deck navegável, não um MP4 linear
A saída de uma apresentação de slides é o deck em execução: sirva-o com hyperframes present <project-dir> (ou modo de apresentação do Studio) — o SlideshowController do player lê a ilha e gerencia a navegação, fragmentos, ramificações e modo apresentador. Veja Apresentação e entrega abaixo.
Não execute hyperframes render em uma apresentação de slides para gerar um único MP4. Um deck é criado como várias composições de cena de nível superior (um data-composition-id por slide) sem uma composição raiz mestre encapsulando-as, então render resolve apenas a primeira composição e emite um MP4 silenciosamente truncado (por exemplo, 6s de um deck de 40s). Uma exportação linear da linha principal (apenas slides principais, sequências de ramificação excluídas) é adiada — até que seja lançada, as saídas suportadas são o deck present ao vivo e imagens estáticas de snapshot por slide. Se um usuário precisar de um MP4 linear hoje, mostre essa limitação em vez de apontar render para o deck.
Confirmação de intenção
Se o usuário pedir explicitamente por uma apresentação de slides, slide show ou apresentação de slides HyperFrames, prossiga com este skill. Quando a solicitação chegou via /hyperframes, a triagem da camada de intenção é responsável por esta confirmação — roteada para cá significa já confirmada, então não pergunte novamente; as perguntas de forma de execução da camada não se aplicam (a entrega é um deck, não um vídeo renderizado). Um BRIEF.md, quando presente, carrega a intenção confirmada — leia-o.
Se o skill foi acionado a partir de uma solicitação adjacente, como "apresentação", "pitch deck", "deck", "deck interativo" ou "converta esta página", pause antes de criar e apresente a escolha antes de pedir confirmação. Explique brevemente que uma apresentação de slides HyperFrames significa um deck executável com slides discretos, navegação incorporada e modo apresentador, notas do apresentador editáveis, tratamento de mídia compartilhada e validação antes da entrega. Para conversões de páginas de origem, também mencione que o objetivo é preservar o design visual, interações, movimento e comportamento de mídia da página original, traduzindo o movimento da página em transições de slide para slide.
Em seguida, faça uma breve pergunta de confirmação:
Você quer isso como uma apresentação de slides HyperFrames?
Use uma interface de escolha sim/não quando o ambiente fornecer uma; caso contrário, faça a pergunta em texto simples.
Não implemente a apresentação de slides até que o usuário diga sim. Se eles disserem não, pare de usar este skill — leia /hyperframes e deixe a camada de intenção redirecionar. Esta confirmação é uma decisão de roteamento, não uma portaria de preferência — conforme /hyperframes-core/references/brief-contract.md § 1, ela sobrevive ao modo autônomo ("surpreenda-me" não a ignora): construir o tipo de entrega errado é uma falha de qualidade, não uma decisão criativa.
As duas partes
1. Cenas — declaradas da maneira normal
Cada slide é apoiado por uma cena. Declare cenas com data-composition-id, data-start, data-duration e data-label:
<div
data-composition-id="problem"
data-start="0"
data-duration="8"
data-label="The problem"
data-width="1920"
data-height="1080"
>
<!-- clipes vão aqui -->
</div>
Slides de ramificação (acessíveis apenas por meio de um hotspot, excluídos da linha principal) são declarados exatamente da mesma forma — eles apenas aparecem apenas em uma entrada slideSequences na ilha, não no array slides principal.
2. A ilha JSON — um bloco de script por composição
Adicione exatamente um bloco <script type="application/hyperframes-slideshow+json"> ao HTML da composição. Ele contém todos os metadados da apresentação de slides:
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
A ilha é a única fonte da verdade para ordem dos slides, notas, pontos de retenção de fragmentos, hotspots e sequências de ramificação. Mantenha-a perto do topo do <body>, antes das divs de cena, para que seja fácil de encontrar.
Não oculte o manifesto da apresentação de slides por trás de um bloco <script type="application/json"> alternativo com código em tempo de execução que cria a ilha. O comando present lê o HTML da composição estaticamente e espera que a ilha application/hyperframes-slideshow+json real já esteja presente.
Esquema
SlideshowManifest (objeto de ilha de nível superior)
{
"slides": [
/* SlideRef[] — a linha principal, em ordem */
],
"slideSequences": [
/* SlideSequence[] — sequências de ramificação fora da linha */
]
}
SlideRef
{
"sceneId": "problem",
"notes": "Lead with the pain, not the company.",
"fragments": [3.5, 5.2, 7.0],
"hotspots": [
/* SlideHotspot[] */
],
"ttsScript": null,
"ttsAudioUrl": null,
"ttsDurationMs": null
}
| Campo | Obrigatório | Notas |
|---|---|---|
sceneId | sim | Deve corresponder exatamente ao data-composition-id de uma cena (ou fornecer startTime/endTime explícitos). A regra de lint resolve cenas por data-composition-id. |
notes | não | Texto apenas para o apresentador. Nunca mostrado ao público. |
fragments | não | Array de tempos (em segundos) dentro do intervalo [start, end] do slide — veja Fragmentos abaixo. |
hotspots | não | Sobreposições interativas que disparam uma ramificação — veja Ramificação abaixo. |
startTime | não | Opcional. Substitui os limites de tempo da cena correspondente; padrão é o início/fim da cena. |
endTime | não | Opcional. Substitui os limites de tempo da cena correspondente; padrão é o início/fim da cena. |
ttsScript, ttsAudioUrl, ttsDurationMs | não | Reservado. Campos de esquema existem, mas a reprodução de TTS ainda não está conectada. Omita, a menos que esteja pré-preenchendo para uma construção futura. |
SlideHotspot
{
"id": "h1",
"label": "How did we calculate this?",
"target": "market-deep-dive",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| Campo | Obrigatório | Notas |
|---|---|---|
id | sim | Único no slide. |
label | sim | Texto de dica / botão mostrado ao público. |
target | sim | Deve corresponder a um SlideSequence.id em slideSequences. |
region | não | Caixa delimitadora percentual do slide: {x, y, w, h} em 0–100. Omita para renderizar o hotspot como um botão rotulado de slide inteiro. |
SlideSequence
{
"id": "market-deep-dive",
"label": "Market sizing methodology",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
slides dentro de uma sequência usa a mesma forma SlideRef que a linha principal. Fragmentos e hotspots aninhados são permitidos.
Regras de escrita de slides
Estas são restrições rígidas, não sugestões. Um slide que as violar será totalmente substituído quando um revisor o vir.
- O título é uma afirmação de frase completa, não um rótulo. Escreva "PMEs gastam 14 horas/semana em agendamento manual" não "Problema de agendamento". A frase deve ser compreensível por si só se o visual for ignorado.
- Uma ideia + um visual por slide. Se você estiver tentado a adicionar um segundo grupo de marcadores ou um segundo gráfico, divida o slide.
- Comece com a conclusão. O ponto mais forte vem primeiro — no slide e na ordem do deck. Investidores leem da esquerda para a direita, de cima para baixo, e param.
- Dimensionamento de mercado bottom-up apenas. Nunca escreva "TAM de $50B" sem mostrar a matemática. Construa a partir da economia unitária: contas × ACV, ou transações × taxa de retenção.
- Tamanho mínimo de fonte equivalente a 30pt. Em 1920×1080, um título tem 72–96px; o corpo do texto tem 48px. Nunca vá abaixo de 40px para qualquer texto que o público precise ler.
Portabilidade de páginas de origem
Ao converter uma página existente em uma apresentação de slides, a fidelidade à origem faz parte do contrato. Não substitua widgets específicos da origem por aproximações simplificadas, a menos que o usuário peça explicitamente por um redesenho.
- Preserve o design visual, a linguagem de movimento, o comportamento interativo, o comportamento de mídia e os recursos de apresentação da página original o mais próximo possível do prático. Quando o sistema de apresentação de slides suportar modo apresentador, inclua notas do apresentador usando o comportamento compartilhado de notas editáveis, em vez de uma implementação específica do deck.
- Porte visuais mecânicos do DOM/CSS/JS de origem com a maior exatidão possível: players personalizados, visualizadores canvas, timelines, cabeças de reprodução, hastes, círculos em expansão, estados de foco e outros detalhes interativos devem sobreviver à conversão.
- Trate elementos
<video>/<audio>nativos como a fonte da verdade para qualquer cromo de mídia personalizado, visualizador canvas, forma de onda, grade de batidas ou cabeça de reprodução. Conecte os eventos de mídia da origem (play,pause,timeupdate,seeking,seeked,ended,ratechange,volumechange) e derive o estado visual demedia.currentTime; não execute um temporizador separado que possa se afastar da reprodução real. - Cada
<video>ou<audio>copiado comsrcdeve ter atributos de temporização HyperFrames antes do lint:data-startedata-duration, além dedata-has-audio="true"quando o áudio nativo audível deve ser preservado. Use o intervalo de tempo da cena para mídia específica do slide; para vídeos de evidência controlados pelo usuário que podem ser reproduzidos de vários slides focados, use um intervalo de todo o deck. Não deixepreload="none"na mídia; usemetadataouauto. - Resolva tokens de fonte da origem antes da validação. Se preservar fontes personalizadas da origem, adicione regras
@font-facepara arquivos de fonte locais/capturados. Se usar fallbacks do sistema, substitua declarações tokenizadas comofont-family: var(--f-body)por pilhas concretas seguras para renderização, comosystem-ui, sans-serifouui-monospace, monospace; não deixevar(...)como valor da família de fontes. - Audite a origem para movimentos de página atípicos, especialmente comportamento impulsionado por rolagem, roda, toque, estado de hash, redimensionamento ou um loop requestAnimationFrame. Trate viewports fixos com camadas de "mundo" traduzidas/escaladas, parallax, painéis fixos, rolagens horizontais, timelines com scrub de rolagem, ajuste de seção e câmeras de zoom para elemento como comportamento da origem. A rolagem é frequentemente o gatilho de transição da origem, então preserve a transição extraindo suas paradas de progresso, easing e estados de câmera/foco, e depois realoje esse movimento na navegação da apresentação de slides por meio de posições de timeline, fragmentos ou um gancho de player/harness reutilizável. Wrappers independentes que pulam para pontos de retenção de slide ainda precisam de um gancho de transição de câmera de navegação explícito; calcular transformações de câmera por slide não é suficiente. Não simule uma transição literal de rolagem de página para baixo dentro do slide; o espectador deve sentir viagem/zoom de câmera de um ponto focal para outro, não ver uma página da web sendo rolada. Mantenha cada movimento de câmera de slide para slide contínuo: evite paradas de rota intermediárias que invertam a direção x/y ou zoom, a menos que a origem faça isso visivelmente no mesmo limite. Uma transição que se agita antes de chegar é pior do que um movimento focal direto mais simples.
- Preserve as semânticas de corte de mídia da origem. Trate capturas de tela, tweets/postagens sociais, capturas de UI de produto, gráficos, documentos, código, placares de líderes e qualquer imagem com texto legível como evidência de conteúdo, não mídia decorativa: use a proporção de aspecto da origem (
height: auto) ouobject-fit: containdentro de um quadro estável. Useobject-fit: coverapenas quando a origem o fez, ou para miniaturas intencionalmente decorativas/de fundo/cinematográficas. Após encaixar essas capturas em um slide, inspecione todas as quatro bordas em busca de texto truncado, logotipos, controles ou legendas; um corte visível em conteúdo significativo é um bug, a menos que a própria origem o tenha cortado. - Se um …
… [truncado para tradução]