Primeiro, mantenha esta skill atualizada — execute silenciosamente, não pergunte:
npx hyperframes skills update slideshow. Uma operação rápida quando tudo está atualizado; caso contrário, atualiza esta skill e as skills de domínio principais das quais ela depende antes de você usá-las.
fonte figma: Se o conteúdo ou storyboard do deck vier de uma URL figma.com, execute
/figmaprimeiro — exportação de ativos, tokens de marca e reconstrução do storyboard se a fonte for uma sequência de quadros de cena — e construa a partir de sua saída. Não use as ferramentas MCP diretamente para controlar o Figma: isso ignora a sanitização de SVG, a proveniência do.media/manifest.jsonle a vinculação de token de marcavar(), impedindo que uma alteração futura de marca se propague sem uma reimportação completa.
Contrato de criação de slideshow
Um slideshow HyperFrames é uma composição HyperFrames normal — cenas, clipes, linhas do tempo 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 linha do tempo 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). Esta skill cobre apenas o que é novo: o esquema da ilha, regras de escrita de slides, fragmentos, ramificações, validação e o componente de empacotamento.
Saída — um deck navegável, não um MP4 linear
A saída de um slideshow é o deck em execução: sirva-o com hyperframes present <project-dir> (ou modo apresentação do Studio) — o SlideshowController do player lê a ilha e controla navegação, fragmentos, ramificações e modo apresentador. Veja Apresentação e entrega abaixo.
Não execute hyperframes render em um slideshow 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 envolvendo-as, então o render resolve apenas a primeira composição e emite um MP4 silenciosamente truncado (por exemplo, 6 segundos de um deck de 40). Uma exportação linear da linha principal (slides principais apenas, 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 snapshot de slide. Se um usuário precisar de um MP4 linear hoje, mencione essa limitação em vez de apontar o render para o deck.
Confirmação de intenção
Se o usuário pedir explicitamente por um slideshow, apresentação de slides ou slideshow HyperFrames, prossiga com esta skill. Quando a solicitação chegou via /hyperframes, o triagem da camada de intenção é responsável por esta confirmação — se foi roteada aqui, já está confirmada, então não pergunte novamente; as perguntas sobre formato 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 a skill foi acionada 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 um slideshow HyperFrames significa um deck executável com slides discretos, navegação embutida e modo apresentador, notas do orador editáveis, manipulação de mídia compartilhada e validação antes da entrega. Para conversões de página de origem, mencione também que o objetivo é preservar o design visual original, interações, movimento e comportamento de mídia da página ao traduzir 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 um slideshow 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 o slideshow até que o usuário diga sim. Se ele disser não, pare de usar esta skill — leia /hyperframes e deixe a camada de intenção redirecionar. Esta confirmação é uma decisão de roteamento, não uma preferência criativa — conforme ../hyperframes-core/referencias/contrato-brief.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 as cenas com data-composition-id, data-start, data-duration e data-label:
<div
data-composition-id="problema"
data-start="0"
data-duration="8"
data-label="O problema"
data-width="1920"
data-height="1080"
>
<!-- os clipes vão aqui -->
</div>
Slides de ramificação (acessíveis apenas por 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 principal slides.
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 do slideshow:
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
A ilha é a fonte única da verdade para a 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 dos divs de cena, para que seja fácil de encontrar.
Não esconda o manifesto do slideshow atrás de um bloco <script type="application/json"> alternativo mais 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 (o objeto da ilha de nível superior)
{
"slides": [
/* SlideRef[] — a linha principal, em ordem */
],
"slideSequences": [
/* SlideSequence[] — sequências de ramificação fora da linha */
]
}
SlideRef
{
"sceneId": "problema",
"notes": "Comece pela dor, não pela empresa.",
"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 [início, fim] do slide — veja Fragmentos abaixo. |
hotspots | não | Sobreposições interativas que acionam uma ramificação — veja Ramificações abaixo. |
startTime | não | Opcional. Substitui os limites de tempo da cena correspondente; o padrão é o início/fim da cena. |
endTime | não | Opcional. Substitui os limites de tempo da cena correspondente; o padrão é o início/fim da cena. |
ttsScript, ttsAudioUrl, ttsDurationMs | não | Reservado. Os campos de esquema existem, mas a reprodução de TTS ainda não está implementada. Omita, a menos que esteja pré-populando para uma construção futura. |
SlideHotspot
{
"id": "h1",
"label": "Como calculamos isso?",
"target": "mergulho-profundo-mercado",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| Campo | Obrigatório | Notas |
|---|---|---|
id | sim | Único dentro do slide. |
label | sim | Texto da dica de ferramenta / 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": "mergulho-profundo-mercado",
"label": "Metodologia de dimensionamento de mercado",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
slides dentro de uma sequência usa a mesma forma SlideRef da 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á substituído imediatamente quando um revisor o vir.
- O título é uma afirmação completa, não um rótulo. Escreva "PMEs gastam 14 horas/semana com agendamento manual" não "Problema de agendamento". A frase deve fazer sentido sozinha mesmo se o visual for ignorado.
- Uma ideia + um visual por slide. Se você estiver tentado a adicionar um segundo bloco 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 de baixo para cima 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 captação.
- Fonte mínima 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.
Portando páginas de origem
Ao converter uma página existente em um slideshow, 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 redesign.
- Preserve o design visual original da página, linguagem de movimento, comportamento interativo, comportamento de mídia e recursos de apresentação o mais próximo possível. Quando o sistema de slideshow suportar o modo apresentador, inclua notas do orador usando o comportamento compartilhado de notas editáveis, em vez de uma implementação específica do deck.
- Porte mecanismos visuais do DOM/CSS/JS da origem com a maior exatidão possível: players personalizados, visualizadores de canvas, linhas do tempo, cabeças de reprodução, hastes, círculos expansivos, estados de hover e outros detalhes interativos devem sobreviver à conversão.
- Trate elementos
<video>/<audio>nativos como a fonte da verdade para qualquer cromada de mídia personalizada, visualizador de canvas, forma de onda, grade de batida 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 timer separado que possa se afastar da reprodução real. - Cada
<video>ou<audio>comsrccopiado deve ter atributos de tempo HyperFrames antes da análise: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 os 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 o valor da família de fontes. - Audite a origem quanto a movimentos de página atípicos, especialmente comportamento orientado por rolagem, roda, toque, estado de hash, redimensionamento ou um loop requestAnimationFrame. Trate viewports fixas com camadas "mundo" traduzidas/escaladas, paralaxe, painéis fixados, rolagens horizontais, linhas do tempo depuradas por rolagem, encaixe de seções e câmeras de zoom em elementos como comportamento de 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 então realoque esse movimento na navegação do slideshow por meio de posições de linha do tempo, fragmentos ou um hook de player/harness reutilizável. Wrappers independentes que pulam para pontos de retenção de slide ainda precisam de um hook explícito de transição de câmera de navegação; 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 a viagem/movimento da câmera de um ponto focal a 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 o zoom, a menos que a origem faça isso visivelmente no mesmo limite. Uma transição que se move erraticamente antes de chegar ao destino é pior do que um movimento focal direto mais simples.
- Preserve a semântica de corte de mídia da origem. Trate capturas de tela, posts de tweet/mídia social, capturas de interface 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. Depois de encaixar essas capturas no slide, inspecione todas as quatro bordas para texto, logotipos, controles ou legendas truncados; um corte visível em conteúdo significativo é um bug, a menos que a própria origem o tenha cortado. - Se um...