Skill de Produção Visual Remotion
Construída a partir de experiência real de produção do vídeo de lançamento do SureCart 4.2. Autor: Chandresh Vaghanani
Antes de Começar — 2 Perguntas (Não Negociáveis)
Faça estas 2 perguntas antes de escrever qualquer código. Mantenha o tom casual — uma mensagem, duas perguntas. Não as pule, mesmo que o usuário diga "pode ir" ou "comece agora". Esses 10 segundos previnem horas de retrabalho.
Antes de começar — duas coisinhas:
1. Fundo claro ou escuro? (ou compartilhe seu site/print e eu tiro de lá)
2. Você tem um print ou mockup do produto? (totalmente opcional — posso criar sem um)
É só isso. Sem mais perguntas, a menos que o usuário ofereça mais informações.
O que fazer com as respostas:
- Se ele compartilhar um mockup/print — extraia cor de fundo, cor de destaque, estilo de fonte, texto da UI. Use-os.
- Se ele compartilhar uma URL de site — acesse-a, extraia o mesmo. Não adivinhe.
- Se ele responder apenas claro/escuro — prossiga com os Padrões Fallback Sem Informação abaixo.
- Se ele pular ambas as perguntas — prossiga com os Padrões Fallback Sem Informação abaixo. Não pergunte novamente.
Outros ativos (logotipo, música, cores extras) — aceite se oferecidos, mas nunca bloqueie por causa deles.
Padrões Fallback Sem Informação
Quando informações da marca não estão disponíveis, o instinto da IA é reduzir fontes e adicionar padding. Esse instinto está errado para vídeo. Aplique estes em vez disso:
Estes entram em ação automaticamente quando nenhum mockup, print ou site é fornecido. Eles garantem um resultado profissional mesmo com zero informação de marca.
Layout
justifyContent: "center"+alignItems: "center"no AbsoluteFill de cada cena — sem exceçõesmarginTop: -50para puxar o conteúdo ligeiramente acima do centro verdadeiro- Largura do mockup/card: 1200px (use o limite superior — preencha o quadro)
- Padding do container: máx. 40px — nunca mais
- O conteúdo deve ocupar pelo menos 75% da altura de 1080px. Se não ocupar, aumente os tamanhos de fonte ou reduza os espaços.
Tamanhos de fonte (fallback — limite superior da faixa)
| Elemento | Tamanho fallback |
|---|---|
| Título principal | 140px |
| Subtítulo | 56px |
| Corpo / descrição | 36px |
| Rótulo / pill | 22px |
| Texto de conteúdo do card | 28px |
Cores (paleta fallback — segura e profissional)
- Fundo:
#0a0a0f(quase preto, neutro) - Destaque:
#6366f1(índigo — legível, moderno, não específico do produto) - Texto:
#ffffff - Texto suave:
rgba(255,255,255,0.55) - Fundo do card:
rgba(255,255,255,0.06)
Estes são apenas PONTOS DE PARTIDA. No momento em que o usuário compartilhar as cores da marca, substitua-as completamente.
O que NÃO fazer sem informação de marca
- NÃO use cores neon/cyber — isso é uma estética pessoal, não uma correspondência de marca
- NÃO use
paddingTop: 120e chame de "centralizado" — fica alinhado ao topo com espaço morto - NÃO escolha
fontSize: 32para um título porque "parece limpo" — fica ilegível em vídeo
Regra #1 — Canvas NÃO é um Site
Este é o erro mais comum em vídeos Remotion gerados por IA.
O canvas do Remotion é 1920×1080px. Projete para preenchê-lo — não como uma página web.
⚠️ Estes são MÍNIMOS. Escrever
fontSize: 18para texto do corpo é um BUG, não uma escolha de estilo. Qualquer coisa abaixo da coluna de mínimo significa que o texto é ilegível em uma tela 1080p. Trate esses números como erros de tipo — eles devem ser corrigidos antes de prosseguir.
| Elemento | MÍNIMO (piso rígido) | Faixa Recomendada |
|---|---|---|
| Título principal | 80px | 100–160px |
| Subtítulo | 40px | 48–72px |
| Corpo / descrição | 28px | 32–40px |
| Rótulo / pill / badge | 18px | 20–24px |
| Texto de conteúdo do card | 22px | 24–32px |
Regras:
- O conteúdo deve parecer que preenche a tela
- Cards de mockup:
width: 1100–1200px, centralizados - Padding do container: máx. 48px — NÃO 80–120px como em uma página web
- Se o texto parecer "grande demais para o conforto" — provavelmente está certo para vídeo
Regra #2 — Todas as Animações DEVEM Usar useCurrentFrame()
// CORRETO
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 20], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
// PROIBIDO — NÃO renderizará corretamente
// CSS: transition: opacity 1s ease
// Tailwind: animate-fade-in
// CSS @keyframes
Sempre inclua extrapolateLeft: "clamp" e extrapolateRight: "clamp" em toda chamada de interpolate() a menos que você explicitamente precise de valores não limitados. Esquecer isso faz com que os valores vazem para fora do intervalo e criem bugs sutis.
Regra #3 — Determinismo
// PROIBIDO — valor diferente em cada passada de renderização
const x = Math.random() * 100;
// CORRETO — mesmo valor sempre, em todos os frames
import { random } from "remotion";
const x = random("particle-x-1") * 100; // string seed = determinística
Regra #4 — Ativos
import { staticFile } from "remotion";
import { Img } from "remotion"; // NÃO <img> nativo
import { Audio } from "@remotion/media";
// Sempre use staticFile() para qualquer coisa na pasta public/
<Audio src={staticFile("bg-music.mp3")} />
<Img src={staticFile("logo.png")} /> // <Img> garante que o ativo carregue antes da renderização do frame
// URLs remotas não precisam de staticFile() mas exigem CORS
Regra #5 — Reprodução Suave na Pré-visualização
Adicione premountFor={30} nos componentes <Sequence> para que componentes pesados pré-carreguem 30 frames antes do seu tempo:
<Sequence from={90} durationInFrames={120} premountFor={30}>
<HeavyScene />
</Sequence>
Receitas de Easing
import { Easing } from "remotion";
// Entrada de UI nítida (ease-out forte, sem overshoot) — a maioria das animações de entrada
Easing.bezier(0.16, 1, 0.3, 1)
// Transição editorial lenta (ease-in-out equilibrado) — transições de clima
Easing.bezier(0.45, 0, 0.55, 1)
// Overshoot divertido — elementos saltitantes/divertidos
Easing.bezier(0.34, 1.56, 0.64, 1)
// Spring — sem bounce (entradas de mockup, cards, UI)
spring({ frame, fps, config: { damping: 200 } })
// Spring — rápido com leve bounce (elementos impactantes)
spring({ frame, fps, config: { damping: 20, stiffness: 200 } })
// Spring — saltitante/divertido
spring({ frame, fps, config: { damping: 8 } })
Gates de Pré-Layout — Execute ANTES de Escrever Qualquer Layout de Cena
Estes não são sugestões. Execute todos os três gates antes de escrever o primeiro <div> de qualquer cena. Se algum gate falhar, mude o layout — nunca remende com dimensões fixas ou conteúdo extra.
Gate 1 — Preenchimento do Canvas (ambos os eixos, obrigatório)
Eixo de largura:
dead_side = (1920 − content_width) / 2
DEVE ser ≤ 300px. Se > 300px → conteúdo é muito estreito. Alargue-o ou mude o layout.
Eixo de altura:
fill_h = content_height / 1080
DEVE ser ≥ 0,80. Se < 0,80 → conteúdo é muito curto. Mude a forma do layout.
⚠️ Se a altura falhar, NÃO a corrija definindo uma altura fixa em cards ou containers. Uma altura fixa cria um vazio vazio dentro do card — o espaço morto se move para dentro do elemento em vez de ser eliminado. A única correção real é mudar a forma do layout (Gate 2).
Exemplo real de falha — 3 cards de recurso curtos:
| Versão | content_width | dead_side | content_height | fill_h | Veredito |
|---|---|---|---|---|---|
| v1: 3 colunas de cards (365px) | 1151px | 384px | 416px | 38% | ❌ ambos os eixos falham |
v2: height: 720px forçada | 1542px | 189px | 864px | 80% | ✅ largura, ❌ visual (vazio vazio no card) |
| v3: linhas horizontais (1400px) | 1400px | 260px | 916px | 85% | ✅ ambos os eixos passam |
Gate 2 — Tabela de Decisão de Seleção de Layout
O volume de conteúdo determina a forma do layout. Escolha o layout desta tabela ANTES de escrever código.
| Itens | Conteúdo por item | Layout correto | Porquê |
|---|---|---|---|
| 3–5 itens | ícone + nome + 1 linha | Linhas horizontais (1400px de largura) | Conteúdo curto empilha verticalmente → preenche altura naturalmente |
| 3 itens | ícone + nome + 2–3 linhas | Cards de 3 colunas (mín. 1100px de largura) | Conteúdo suficiente para preencher a altura do card sem vazio |
| 2 itens | substancial | Grandes cards lado a lado ou tela dividida | |
| 1 item | qualquer coisa | Herói em tela cheia |
Se o layout natural para seu conteúdo deixar qualquer eixo abaixo do limite após o Gate 1 — esse layout está errado. Escolha uma linha diferente nesta tabela.
Nunca escolha o layout por estética ou instinto padrão. Ajuste de conteúdo primeiro. Estética depois.
Gate 3 — Limite de Densidade de Conteúdo
Por item, máximo: ícone + nome + 1 linha curta. Parada obrigatória. Sem bullets. Sem subseções. Sem parágrafos. Sem segundas linhas de descrição.
Um espectador tem aproximadamente 5 segundos por cena. Ele lê 1 linha. Ele não lê 4 bullets.
Se o conteúdo parecer raso e você quiser adicionar mais para preencher espaço — isso é o Gate 2 dizendo que a forma do layout está errada, não que o conteúdo está faltando.
Preencha o espaço vazio com TAMANHO (fontes maiores, ícones maiores, espaços maiores entre itens) — nunca com mais conteúdo.
Regras Universais de Cena
-
Alinhamento vertical —
justifyContent: "center"+marginTop: -40a-60(ligeiramente acima do centro verdadeiro = sensação moderna e premium. NÃO alinhado ao topo com padding.)❌ ERRADO — alinhado ao topo, deixa espaço vazio na parte inferior:
<AbsoluteFill style={{ display: "flex", flexDirection: "column", paddingTop: 110 }}> <h1>Título</h1> <p>Subtítulo</p> {/* grande vazio vazio na parte inferior */} </AbsoluteFill>✅ CERTO — centralizado verticalmente, ligeiramente acima do ponto médio:
<AbsoluteFill style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", marginTop: -50 }}> <h1>Título</h1> <p>Subtítulo</p> {/* conteúdo preenche o quadro — sem espaço morto */} </AbsoluteFill> -
Preenchimento do canvas — execute os Gates de Pré-Layout antes de escrever esta cena. O Gate 1 verifica tanto a largura (
dead_side ≤ 300px) quanto a altura (fill_h ≥ 0.80) juntos. O Gate 2 seleciona a forma do layout da tabela de decisão. O Gate 3 limita o conteúdo por item. Todos os três gates estão na seção Gates de Pré-Layout acima — eles substituem a antiga verificação apenas de largura que estava aqui. -
z-index do título — sempre
zIndex: 20no container do título para que o mockup nunca sobreponha o texto -
Estouro do título — sempre
whiteSpace: "nowrap"no texto do título (evita quebra atrás do mockup) -
Sem
overflow: hiddenno AbsoluteFill — corta elementos de cursor e SVG. Remova-o ou coloque o cursor fora. -
Segurar 15 frames — toda cena deve ter pelo menos 15 frames de exibição totalmente visível no FINAL antes de a transição disparar. Nunca inicie uma transição enquanto uma animação ainda estiver em execução na cena de saída.
-
Fonte — use uma fonte consistente em todo o vídeo. Recomendada: Plus Jakarta Sans via
@remotion/google-fonts. Peso máximo disponível: 800 (escreverfontWeight: 900renderiza como 800). -
Cor — máximo de 2–3 cores da marca. Um fundo escuro, um destaque primário, branco/branco suave para texto. Consistente em todas as cenas.
Hierarquia de Tipografia
// Supertítulo / Rótulo pill
{ fontSize: 20, letterSpacing: "4px", textTransform: "uppercase", fontWeight: 600 }
// Título principal
{ fontSize: 112, fontWeight: 800 } // faixa: 100–160px
// Subtítulo / descrição
{ fontSize: 36, opacity: 0.7 } // faixa: 32–40px
// Linha de confiança / badges pequenos
{ fontSize: 26, opacity: 0.5 } // faixa: 24–28px
Configuração de Fonte
import { loadFont } from "@remotion/google-fonts/PlusJakartaSans";
// Chame no nível superior — deve carregar antes da renderização
const { fontFamily } = loadFont("normal", {
weights: ["400", "600", "800"],
subsets: ["latin"],
});
Para outras fontes: instale via @remotion/google-fonts/NomeDaFonte ou coloque o arquivo .woff2 na pasta public/ e use loadFont de @remotion/fonts.
Modelo de Estrutura de Cena
Toda cena segue esta ordem fixa de camadas (de baixo para cima):
<AbsoluteFill style={{ background: brandBg }}>