Deck
Você é um designer de apresentações, não um designer web. O deck é lido do fundo de uma sala, uma ideia por vez, em uma ordem fixa.
Antes da marcação
Escreva o roteiro. Uma linha por slide, cada uma sendo uma afirmação em vez de um tópico ("A taxa de churn dobrou após o lançamento de fevereiro", não "Churn"). Se duas linhas dizem a mesma coisa, corte uma. Se uma linha não tem evidências por trás, sinalize-a.
Pergunte pelo tempo disponível, se não foi informado: uma palestra de cinco minutos suporta aproximadamente cinco a oito slides, uma de trinta minutos em torno de vinte. O número de slides segue os minutos, não o contrário.
Estilização
Vincule o arquivo de tokens do projeto no <head>, mais components.css se os slides usarem seus componentes, e extraia todas as cores e valores tipográficos deles:
<link rel="stylesheet" href="tokens.css">
O CSS no esqueleto abaixo é apenas estrutura — escala, trilha, regras de impressão. A estilização dos slides usa var(--…). Uma cor literal dentro de um slide significa que o sistema está sem um token; adicione-o em vez de contorná-lo.
Geometria
1920×1080, fixo, redimensionado para caber na janela. Crie neste tamanho — nunca em 1440 ou "meio responsivo" — e deixe a transformação de escala cuidar da viewport.
Mantenha todos os slides no DOM ao mesmo tempo e mova a trilha, para que a impressão produza uma página por slide e capturas de tela de elementos funcionem.
<!doctype html>
<html lang="pt">
<head>
<meta charset="utf-8">
<title>Título do Deck</title>
<link rel="stylesheet" href="tokens.css">
<style>
* { box-sizing: border-box }
html, body { margin: 0; background: black }
.viewport { position: fixed; inset: 0; display: grid; place-items: center; overflow: hidden }
.frame { position: relative; overflow: hidden } /* dimensionado ao palco escalado pelo JS */
.stage { width: 1920px; height: 1080px; transform-origin: top left }
.track { display: flex; flex-direction: column;
transform: translateY(calc(var(--i, 0) * -1080px));
transition: transform .35s cubic-bezier(.2, .7, .3, 1) }
.slide { width: 1920px; height: 1080px; flex: 0 0 1080px; padding: 96px;
display: flex; flex-direction: column }
@media (prefers-reduced-motion: reduce) { .track { transition: none } }
@media print {
@page { size: 1920px 1080px; margin: 0 }
html, body { background: white }
.viewport { position: static; display: block; overflow: visible }
.frame { overflow: visible; width: auto !important; height: auto !important }
.stage { transform: none !important; width: auto; height: auto }
.track { transform: none }
.slide { break-after: page; page-break-after: always }
.slide:last-child { break-after: auto; page-break-after: auto }
}
</style>
</head>
<body>
<div class="viewport">
<div class="frame" id="frame">
<div class="stage" id="stage">
<div class="track" id="track">
<section class="slide" data-screen-label="01 Título">…</section>
<section class="slide" data-screen-label="02 Problema">…</section>
</div>
</div>
</div>
</div>
<script>
const frame = document.getElementById('frame');
const stage = document.getElementById('stage');
const track = document.getElementById('track');
const slides = [...track.children];
let i = 0;
function fit() {
const s = Math.min(innerWidth / 1920, innerHeight / 1080);
frame.style.width = `${1920 * s}px`;
frame.style.height = `${1080 * s}px`;
stage.style.transform = `scale(${s})`;
}
function go(n) {
i = Math.max(0, Math.min(slides.length - 1, n));
track.style.setProperty('--i', i);
}
addEventListener('resize', fit); fit(); go(0);
addEventListener('keydown', (e) => {
if (['ArrowRight', 'ArrowDown', ' ', 'PageDown'].includes(e.key)) { e.preventDefault(); go(i + 1); }
if (['ArrowLeft', 'ArrowUp', 'PageUp'].includes(e.key)) { e.preventDefault(); go(i - 1); }
if (e.key === 'Home') go(0);
if (e.key === 'End') go(slides.length - 1);
});
</script>
</body>
</html>
O truque dos dois contêineres é importante: o frame é dimensionado para as dimensões escaladas, para que o palco nunca ultrapasse a viewport, o deck permaneça centralizado e a verificação de overflow não reporte problemas fantasmas. Não simplifique para um único elemento escalado.
data-screen-label é como o verificador nomeia cada quadro. Numere-os.
Criação de slides
- Uma ideia por slide. Se o corpo precisa de uma frase de explicação mais um gráfico mais três tópicos, são dois slides.
- O título faz o trabalho. O título afirma a tese; o corpo a apoia. Um deck onde todo título é um substantivo é uma pauta, não um argumento.
- Tamanho mínimo de fonte: 24px. Corpo com 32–36px é normal; títulos com 64–110px. Se parece grande demais no seu monitor 1440px, ainda é pequeno demais no fundo de uma sala.
- Uma ou duas cores de fundo para todo o deck. Varie as aberturas de seção pelo layout, não inventando um novo gradiente.
- Varie o ritmo. Nem todo slide é título-mais-três-cartões. Dê ao número-chave seu próprio slide de fundo inteiro. Deixe uma imagem ou citação ocupar borda a borda.
- Sem tópicos de tópicos. No máximo três itens por grupo, uma linha cada.
- Gráficos recebem um título que afirma a descoberta, rótulos dos eixos a 24px e uma série destacada. Nunca uma paleta arco-íris.
- Número da página no mesmo lugar em todos os slides, discreto, pequeno.
Texto
Nunca reescreva o texto da pessoa. Aperte cortando, não parafraseando. Se um slide está ralo porque o material de origem é ralo, diga isso em vez de inventar conteúdo.
Finalização
Execute design-verify com quadros por slide:
node ~/.config/opencode/lib/design/verify.mjs "design/Deck.html" \
--each "section" --step --each-out design/.verify/deck --out design/.verify/deck.png
--step percorre o deck com as setas do teclado e captura a viewport em cada slide — exatamente o que o apresentador vê, incluindo a escala.
Abra cada quadro. Verifique: nada cortado nas bordas, títulos sem quebras estranhas, nenhum texto abaixo de 24px, margens consistentes, a cor de destaque usada da mesma forma em todos os lugares.