🛠️ A tool copy_starter_component
É a ferramenta que importa scaffolds prontos. Substitui "desenhar manualmente molduras de dispositivo, cascas de deck, grades de apresentação".
Citação literal
"Use copy_starter_component para inserir estruturas prontas no projeto em vez de desenhar manualmente molduras de dispositivos, cascas de deck ou grades de apresentação. A ferramenta devolve o conteúdo completo para que você possa encaixar imediatamente seu design nele. Os tipos incluem a extensão do arquivo — alguns são JS puro (carregue com <script src>), outros são JSX (carregue com <script type='text/babel' src>). Passe a extensão exatamente; a ferramenta falha se você usar o nome sem extensão ou com extensão errada."
⚠️ Extensão exata é obrigatória
// ✓ FUNCIONA
copy_starter_component({ kind: "deck_stage.js" })
copy_starter_component({ kind: "ios_frame.jsx" })
copy_starter_component({ kind: "animations.jsx" })
// ✗ FALHA SILENCIOSAMENTE
copy_starter_component({ kind: "deck_stage" }) // sem extensão
copy_starter_component({ kind: "ios_frame.js" }) // extensão errada
copy_starter_component({ kind: "deck-stage.js" }) // hífen em vez de underscore
📋 Tabela completa dos 7 starters
| kind | Tipo | Como carregar | Use case obrigatório |
|---|---|---|---|
deck_stage.js | JS puro | <script src> | QUALQUER deck — sem alternativa |
design_canvas.jsx | JSX React | <script type="text/babel" src> | 2+ opções estáticas lado a lado |
ios_frame.jsx | JSX React | <script type="text/babel" src> | Mockup iOS (notch + status + teclado) |
android_frame.jsx | JSX React | <script type="text/babel" src> | Mockup Android (status + nav) |
macos_window.jsx | JSX React | <script type="text/babel" src> | Janela macOS (traffic lights) |
browser_window.jsx | JSX React | <script type="text/babel" src> | Browser chrome (address bar + tabs) |
animations.jsx | JSX React | <script type="text/babel" src> | Motion design (Stage + Sprite + Easing) |
📊 deck_stage.js — internals e contratos
É o starter mais importante (obrigatório por system prompt para QUALQUER deck). Ele faz 10 coisas automaticamente que você não precisa implementar.
10 features built-in (citação literal)
"Para decks de slides, não implemente isso manualmente — chame copy_starter_component com kind: 'deck_stage.js' e coloque cada slide como filho direto <section> do elemento <deck-stage>. O componente cuida da escala, navegação por teclado/toque, overlay de contagem de slides, persistência em localStorage, impressão para PDF (uma página por slide) e dos contratos externos dos quais o host depende: ele rotula automaticamente cada slide com data-screen-label e data-om-validate, e envia {slideIndexChanged: N} ao pai para manter as notas do apresentador sincronizadas."
- Auto-scale 1920×1080 via
transform: scale() - Letterbox preto nas bordas para qualquer aspect ratio do viewport
- Navegação teclado — setas, espaço, page up/down
- Navegação touch — swipe esquerda/direita
- Overlay de contagem "03/12" no canto inferior
- Persistência localStorage — reload volta ao slide atual
- Print to PDF — uma página por slide (preserva quebras)
- Auto-rotula data-screen-label — "01", "02", "03"... automaticamente
- Auto-rotula data-om-validate — para o verificador silencioso checar
- postMessage({slideIndexChanged: N}) — para sync com speaker notes externas
Estrutura HTML mínima
<!DOCTYPE html>
<html>
<head>
<script src="deck_stage.js"></script>
</head>
<body>
<deck-stage>
<section><!-- Slide 1 (recebe data-screen-label="01" auto) --></section>
<section><!-- Slide 2 (data-screen-label="02") --></section>
<section><!-- Slide 3 (data-screen-label="03") --></section>
</deck-stage>
</body>
</html>
Cada <section> é um slide. O resto é automático.
📢 Speaker notes — script tag oficial
O system prompt define o formato EXATO:
<head>
<script type="application/json" id="speaker-notes">
[
"Notas do slide 0 (1-indexed na UI mas 0-indexed aqui)",
"Notas do slide 1",
"Notas do slide 2"
]
</script>
</head>
Combinado com deck_stage.js (que envia postMessage({slideIndexChanged: N}) automaticamente), o sistema renderiza notas externamente em sync.
⚠️ Regra: "NUNCA adicione notas do apresentador a menos que isso seja explicitamente pedido."
data-screen-label — convenção 1-indexed
"Slide numbers are 1-indexed. Use labels like '01 Title', '02 Agenda' — matching the slide counter ({idx + 1}/{total}) the user sees. Quando um usuário diz 'slide 5' ou 'index 5', ele quer dizer o 5º slide (label '05'), nunca a posição do array [4] — humanos não falam em índice começando do zero. Se você numerar a partir de 0, toda referência de slide ficará deslocada em um."
Se você criar manualmente, use "01", "02"... Se usar deck_stage.js, é automático.
🎬 animations.jsx — Stage, Sprite, hooks completos
API completa (do system prompt)
"Comece chamando copy_starter_component com kind: 'animations.jsx' — ele fornece <Stage> (autoescala + scrubber + play/pause), <Sprite start end>, hooks useTime() / useSprite(), Easing, interpolate() e primitivas de entrada/saída. Construa cenas compondo Sprites dentro de um Stage. Só use Popmotion (https://unpkg.com/popmotion@11.0.5/dist/popmotion.min.js) se o componente inicial realmente não cobrir o caso de uso. Para protótipos interativos, transições CSS ou estado React simples bastam. Resista à vontade de adicionar TÍTULOS à página HTML em si."
Cheat sheet API
| Símbolo | Tipo | Para quê |
|---|---|---|
<Stage duration={ms}> | Component | Container — autoescala + scrubber + play/pause |
<Sprite start end> | Component | Existe entre start/end ms (props ms). Hidden fora dessa janela |
useTime() | Hook | Retorna tempo absoluto do Stage (ms) |
useSprite() | Hook | Retorna progresso 0-1 do Sprite atual |
Easing.{easeIn, easeOut, easeInOut, ...} | Helper | Curvas de easing |
interpolate(v, [0,1], [a,b]) | Helper | Mapeia range linear |
fadeIn, slideUp, scaleIn, ... | Primitivas | Entry/exit prontos |
Exemplo composto
<Stage duration={3000}>
{/* Hero entra fade+slide nos primeiros 800ms */}
<Sprite start={0} end={800}>
{(() => {
const p = useSprite();
return (
<h1 style={{
opacity: p,
transform: `translateY(${(1-p) * 40}px)`
}}>Welcome</h1>
);
})()}
</Sprite>
{/* 3 cards stagger de 600 a 1800ms */}
<Sprite start={600} end={1800}>
{(() => {
const p = useSprite();
const y = interpolate(Easing.easeOut(p), [0,1], [40, 0]);
return <CardGrid translateY={y} opacity={p} />;
})()}
</Sprite>
{/* CTA pulse 2200-3000ms */}
<Sprite start={2200} end={3000}>
{(() => {
const p = useSprite();
const scale = 1 + Easing.easeOut(p) * 0.1;
return <Button style={{transform: `scale(${scale})`}} />;
})()}
</Sprite>
</Stage>
⚠️ Regra: "Resist titles"
"Resist the urge to add TITLES to the actual html page."
Animation HTML não deve ter cabeçalhos. Cena começa direto. Se quer "título", inclua como Sprite na própria timeline.
📱🖥️ design_canvas + frames
design_canvas.jsx
Citação:
"Use ao apresentar 2 ou mais opções estáticas lado a lado. Um layout em grade com células rotuladas para variações."
Quando usar
- • 3-6 variações de hero, lado a lado
- • Comparação de 2 estéticas (Linear vs A24)
- • Apresentar opções de cor/tipo
Quando NÃO usar
- • Variações de fluxo/interação → use Tweak
- • 1 design só (waste)
Os 4 frames
ios_frame.jsx | notch + status + home indicator + teclado virtual |
android_frame.jsx | status bar + nav bar Android |
macos_window.jsx | traffic lights + title bar |
browser_window.jsx | address bar + nav buttons + tabs |
Combinação poderosa: design_canvas com 3 células, cada uma usando ios_frame = 3 flows mobile lado a lado para comparação.
📐 .napkin sketches + conteúdo de tamanho fixo
Esboços .napkin (citação literal)
"Quando um arquivo .napkin for anexado, leia sua miniatura em scraps/.{filename}.thumbnail.png — o JSON é só dado bruto de desenho, não é útil diretamente."
Se você usa Napkin (ferramenta de sketch), o anexo fica visível para Claude via thumbnail PNG, não o JSON cru.
Conteúdo de tamanho fixo (regra geral)
"Decks de slides, apresentações, vídeos e outros conteúdos de tamanho fixo devem implementar sua própria escala em JS para que o conteúdo caiba em qualquer viewport: uma tela fixa (padrão 1920×1080, 16:9) envolta em um palco de viewport completo que a enquadra em preto via transform: scale(), com controles anterior/próximo fora do elemento escalado para que continuem utilizáveis em telas pequenas."
Para decks: deck_stage.js faz isso. Para vídeos/animações: animations.jsx faz com Stage. Manualmente, padrão é 1920×1080, 16:9, transform-scale + letterbox preto.
Override aspect ratio
Para 9:16 (Stories, Reels, vertical):
"Não use deck_stage.js (ele é hardcoded 1920×1080).
Implemente manualmente: stage 1080×1920 (9:16),
escala via transform-scale para fit no viewport.
Mantenha controles fora do elemento escalado."
✅ Resumo do Módulo
Próximo Módulo:
3.3 — 🔒 Verificador silencioso (fork_verifier_agent + done flow)