Remotion Sistema de Design para Locução HUD (v1 hub)
Objetivo de estilo: replicar o HUD de locução dos vídeos de referência (galeria de referências no diretório refs/). Este arquivo é o hub de restrições rígidas: regras de ferro + semântica de tokens + consulta rápida de componentes + coleção de erros; os detalhes de cada seção estão em references/ (aprofundamento da comparação de 77 diferenças em 16/07/2026). Decisões visuais não previstas no sistema devem ser adicionadas ao arquivo da seção correspondente antes de codificar.
Tabela de Rotas (leia o arquivo correto para cada seção)
| Seção | Arquivo | O que cobre |
|---|---|---|
| Tabela de especificações (consulte antes de codificar) | references/specs.md | Valores reais medidos dos vídeos de referência: largura do cartão/tamanho da fonte/posição/quadros-chave de animação. Verifique antes de implementar. Se não estiver na tabela, meça e preencha de volta. Proibido estimar a olho. |
| Layout e composição | references/layout.md | Três zonas, mecanismo de takeover (Nível A sem PiP, escurecimento de câmera lenta já descartado), um centro gravitacional por tela, modelos de agrupamento, posições de encaixe. |
| Tipografia | references/typography.md | Uma única fonte máxima, obrigatoriedade de h1, sanduíche hero, variante de título SideLabel. |
| Cor e textura | references/texture.md | Gradiente/bloco de gelatina, brilho, variantes claro/escuro de SURFACE, especificação única de carimbo, máximo de 2 cores por tela, regras para "não usar texto sem fundo em fundos claros". |
| Motion | references/motion.md | useEnter/useExit, ritmo de batida, build-up, intervalo de serviço, Breathe, tela limpa. |
| Design de informação | references/infographic.md | Seleção de gráficos, metáforas visuais, waffle, grandes números em três camadas, vocabulário de micro-gráficos. |
| Narrativa/ritmo/legendas/materiais/áudio | references/ do remotion-assembly | narrative / rhythm / subtitle / broll / audio |
| Coleção de erros (sintoma -> índice de correção) | Skill independente remotion-gotchas-index | Consulte aqui a localização da correção para cada Erro #NN; verifique aqui primeiro se a renderização estiver anormal ou a imagem incorreta. |
Lista de Base Técnica (substrate – verifique a presença antes de iniciar um novo projeto frio)
Este sistema de design é uma base compartilhada para todo o repositório, não recriada para cada vídeo. Os arquivos abaixo são pré-requisitos para todo o fluxo de montagem (assembly "verificação de entrada → geração de quadros → três barreiras de qualidade" + motion §12 portão). Um novo projeto reutiliza esta base por padrão, apenas adiciona sua própria composição, legendas e cena, sem reconstruir a base. Leitores de inicialização fria (proibidos de ler src/) frequentemente se perdem aqui – primeiro verifique se os arquivos estão presentes; para obter valores específicos, abra o arquivo correspondente, não espere que o skill copie para você.
| Arquivo de Base | O que contém | Como usar na inicialização fria |
|---|---|---|
src/design/tokens.ts | Fonte única de verdade para valores: COLOR (quatro semânticas + hex cores base), SURFACE, FONT, GRADIENT, escada SIZE (kicker…mega), GRID, RADIUS, SAFE, quadros-chave MOTION | Para SIZE.mega, hex de cor semântica, vá direto a este arquivo – o skill propositalmente não copia (para evitar dessincronização entre snapshot e código, veja §1). Se o arquivo não existir, a base está faltando. |
src/design/*.tsx | Biblioteca de componentes (tabela completa na §3: SideLabel/HeroText/Chip…) + FontGuard.tsx (guardião de fonte, Erro #01) + qc.tsx (sonda QC QcProbe: lê caixas [data-qc] quadro a quadro para detectar sobreposição, Erro #29) | Antes de escrever um elemento de embalagem, consulte a tabela de componentes na §3 para localizar o arquivo. |
src/design/motion.ts | Hooks base useEnter/useExit/usePop + constantes MOTION | Os hooks referenciados nas regras de motion.md estão aqui. |
src/design/fonts.ts | Registro local de fontes @fontsource (Erro #01: fontes web silenciosamente fallback para Song Ti) | package.json sideEffects deve incluí-lo. |
src/koubo/scenes/shared.tsx | Quatro ferramentas de portão da camada de montagem Enter/DimAfter/Exit/ClearOut (motion §12) + caixa de posicionamento Place + qcAllow para lista branca de encaixe QC (assembly §2.5 gate ①) | Ao escrever uma cena de montagem, use diretamente esses wrappers, não manipule opacity manualmente. |
src/Root.tsx | Registro de composições (existente <Composition id="Koubo-0715-01" fps={30} …/>) | Para um novo vídeo, adicione uma linha <Composition> aqui, com id personalizado. O script de renderização por segmento deve corresponder a este id (veja assembly §6 render-service para alterar o id). |
src/koubo/ | Exclusivo de cada vídeo: subtitles-<nome>.ts / SubtitleTrack.tsx / <componente principal do vídeo>.tsx / scenes/SceneNN.tsx | Para um novo vídeo, apenas adicione arquivos nesta camada (veja assembly §4 para a estrutura). |
Inicialização verdadeiramente do zero (src/ completamente vazio): O fluxo de montagem não pode começar até que a base esteja presente (não é possível obter tokens, gerar o primeiro quadro ou aplicar as três barreiras de qualidade). Ordem = construa a base primeiro, depois monte: ① tokens.ts define a fonte de valores → ② fonts.ts + FontGuard.tsx (Erro #01) → ③ motion.ts três hooks → ④ Biblioteca de componentes §3 → ⑤ src/koubo/scenes/shared.tsx quatro ferramentas de portão + Place/qcAllow → ⑥ src/design/qc.tsx sonda QC → ⑦ src/Root.tsx registra a composição. Use o src/design deste repositório como referência para portabilidade; após a portabilidade, os valores ainda devem ser lidos de tokens.ts, não preenchidos de volta no skill.
0. Seis Regras de Ferro
- Área de informação à esquerda por padrão, pessoa à direita: A área de informação fica à esquerda por padrão (autor definido pelo usuário), HUD ancorado para crescimento vertical à esquerda, área da pessoa não pode ser invadida; mas para cada vídeo, pergunte primeiro ao usuário, não assuma. Coordenadas das três zonas e exceções de takeover em references/layout.md regra 1.
- Todo texto tem estrutura dupla: Inglês UPPERCASE com espaçamento amplo como kicker (pequeno) + Chinês grosso e preto (grande). Componentes com apenas uma camada de texto são considerados incompletos.
- Apenas uma palavra destacada por frase: No título em Chinês, no máximo uma palavra pode ter cor alterada/ênfase, a cor deve ser do sistema de quatro cores semânticas.
- Material real como corpo principal, Remotion é um sintetizador, não uma mesa de desenho (atualização de 16/07/2026 seg01): Cenas de "experiência do produto" (digitação/geração/interface/demonstração) devem ser clipes de material real – captura de tela própria > vídeo oficial > screenshot de página web > cartão simulado de UI; desenho manual apenas para camada HUD (side labels, legendas, gráficos, carimbos, gráficos metafóricos). Usar CSS para imitar o trabalho de equipes profissionais de motion graphics sempre falhará; "não importa como ajuste, parece errado/longe do alvo" – a raiz é usar uma mesa de desenho para fazer o trabalho de um sintetizador. O pipeline de captura e edição está em assembly references/broll.md.
- Fundo claro proíbe texto sem fundo (decisão de 16/07/2026 após comparação aprofundada, regra transversal que cobre 6 seções): Em fundos claros (quadro branco/parede branca/fundo de takeover claro) é proibido texto sem fundo – todo texto deve estar sobre um fundo escuro (SURFACE.darkPlate), cartão ou variante de superfície clara,
textShadownão é uma solução. Detalhes em references/texture.md. - Uma tela, uma camada dominante: Cada tela de informação tem um e apenas um "maior caractere/maior elemento", no máximo 2 pequenos elementos do tipo chip fora da área principal. Detalhes em references/typography.md e layout.md.
1. Design Tokens
Fonte única de verdade = src/design/tokens.ts, todos os componentes só podem importar valores de lá. Esta seção apenas escreve regras semânticas e de uso, não copia valores – já houve dessincronização entre snapshot e código uma vez (descoberto em 16/07/2026 que kicker/h1 etc. não correspondiam em vários lugares), o código é a autoridade.
- Quatro cores semânticas (únicas cores de ênfase permitidas): azul = definição/método/avanço neutro; verde = positivo/baixa barreira/ativo; amarelo = oportunidade/alerta/controvérsia/turno; vermelho = negativo/armadilha/crise. Cores base também: white/grey/greyDim/cardBg/cardStroke.
- Fontes (duas camadas, não misture): Camada de embalagem MG –
FONT.zh= Noto Sans SC (única fonte chinesa para camada de embalagem, títulos sempreFONT.zhHeavy);FONT.en= Inter (kicker/corpo principal/números);FONT.enTitle= Archivo Black (títulos em inglês e conclusões grandes, super preto estreito, weight sempre 400 – Inter não suporta a força de caracteres grandes, conclusão da comparação de glifos em 07/2026). Camada de legenda inferior –FONT.subZh= PingFang SC 400 /FONT.subEn= Inter 300 (decisão do usuário após comparação de 5 opções em 26/07/2026): A legenda é uma camada de leitura, não de embalagem; apenas a fonte fina tem a textura das legendas do iOS, e se diferencia do título MG grosso e preto, não roubando atenção. A versão antiga usando Noto 700 para toda a linha parecia um adesivo. PingFang SC é uma fonte do sistema macOS, não é empacotada via@fontsource– funciona em máquinas locais; em ambientes Windows/Linux, cairá de volta para o arquivo fino Noto Sans SC 400 (já importado emfonts.ts, visual semelhante mas não igual). Antes de renderizar em outra máquina, renderize um quadro para confirmar a aparência da legenda. A linha em inglês da legenda deve usar uma fonte proporcional ocidental, veja Erro #42. - Conclusões grandes devem usar cor semântica pura + textShadow, proibido usar
backgroundClip: textpara texto gradiente (Erro #06);GRADIENTé apenas para uso em blocos de cor/contornos. - Tamanhos de fonte apenas permitem a escada
SIZE(kicker / subSmall / chip / subZh / subEn / card / h2 / h1 / mega), proibido usar tamanhos fora da escada; base 1080p, saída 4K multiplica por ×2. - Espaçamento sempre múltiplos de
GRID(8px); cantos arredondados usamRADIUS; zona segura usaSAFE(ancoragem de side label, borda esquerda de empilhamento, distância da legenda ao fundo; cartões permanentes não ultrapassam x55%, coordenadas da zona proibida para pessoa/zona direita em layout.md; zona proibida para legenda y>82%, borda inferior de elementos da zona esquerda ≤y840 é uma linha rígida mais restritiva que y82%).
2. SideLabel (permanente em todo o vídeo, componente de maior prioridade)
- Estrutura:
│(linha vertical de 4px, cor semântica) +ENGLISH KICKER · frase chinesa(primeira linha, especificação kicker em inglês + cor semântica, chinês branco 34px) + segunda linha cinza 24px para explicação complementar. - Posição: fixa em
SAFE.sideLabel, ao alternar, o rótulo antigo desvanece em 12 quadros, o novo rótulo desliza para a esquerda em 15 quadros. - Sistema de numeração:
SCENE 01,PATH 1/2/3, contraste positivo/negativo (DISSOLVED·01..vsIMMUNE·01..). - Cor = semântica emocional do segmento, veja comentários em tokens. Referência:
refs/01-版式与侧标/.
3. Consulta Rápida de Especificações de Componentes (especificações detalhadas serão complementadas conforme implementação, veja as referências visuais primeiro e depois codifique)
| Componente | Especificações Chave | Referência |
|---|---|---|
| BilingualSub | Chinês 52 branco + sombra preta / Inglês 28 branco puro, centralizado inferior, sempre na camada mais superior | Qualquer refs |
| HeroText | kicker + h1/h2 chinês, palavra destacada em cor semântica; variantes: linha vermelha de correção, sublinhado amarelo como pincelada, carimbo inclinado | refs/02 |
| Chip | Cartão preto RADIUS.chip + ícone colorido + texto 34px, pode ter uma palavra com cor alterada | refs/03 |
| Checklist | Chip empilhados verticalmente, aparecem um a um; itens não ativos opacity 0.35 | refs/03 |
| InfoCard | Ícone + kicker + título 44px + palavra destacada azul | refs/01 |
| StepList | Numeração ①②③ em círculo + chinês + kicker inglês pequeno, aceso gradualmente | refs/04 |
| FlowChain | Cartão preto + seta → em série, nós aparecem um por um | refs/04 |
| CompareCard | Logo + nome + chip vermelho × para ponto fraco + chip verde ✓ para ponto forte, empilhados verticalmente | refs/04 |
| Formula | Caractere grande A símbolo B (>, », ⇄, =), símbolo em cor semântica | refs/05 |
| BigNumber | Número grande Inter + unidade pequena + kicker; contador usa spring para rolagem | refs/05 |
| BarChart | Barras de dados com cantos arredondados de 8px; barra de destaque fica amarela + chip de coroa no topo; resto cinza | refs/05 |
| CurveOverlay | Curva amarela de 2–3px sobreposta diretamente ao B-roll, com anotação no ponto direito | refs/05 |
| Timeline | Tipo intervalo entre dois pontos / tipo chip com resultado vermelho/verde para eventos | refs/05 |
| ScoreBoard | Placar de grandes números verde:vermelho | refs/05 |
| PhoneMockup | Moldura iPhone + gradiente de contorno brilhante + captura de tela longa interna em rolagem | refs/06 |
| WindowCard | Semáforo mac + ícone do app + chip de função, conteúdo dinâmico | refs/04 |
| QuoteDoc | Cartão de captura de tela com fundo branco + destaque fluorescente amarelo + camada flutuante de tradução chinesa com fundo preto | refs/07 |
| TweetCard | Avatar + kicker de identidade + conclusão grande em vermelho + chip views | refs/07 |
| PersonCard | Avatar circular + nome + texto pequeno de identidade + chip de instituição | refs/07 |
| Stamp | Inclinado -8°~-6° texto de carimbo com contorno (vermelho/verde), animação de carimbo = scale 1.3→1 + leve vibração | refs/08 |
| MatrixIcon | Ícone de matriz quadrada: vermelho = campo que será dissolvido / verde = campo imune | refs/08 |
| CardWall | Pequenos cartões brancos de 3→20 preenchem a tela um por um, simulando explosão de demanda | refs/06 |
| BeforeAfter | Dois cartões de ícone + seta azul + chip de conclusão abaixo | refs/04 |
| Breathe | Invólucro de micro-animação idle: respiração scale ±0.6% + flutuação ±3px, phase fora de fase para evitar sincronização; envolve o elemento principal | src/design/Breathe.tsx |
| BrickWall | Parede horizontal de tijolos dourados escalonados construídos um a um + etiqueta central, metáfora de "construir parede/barreira rígida" | src/design/BrickWall.tsx |
| UnitMatrix | Matriz quadrada de N grupos acessos ponto a ponto; modo waffle fillRatio (73% campo de dados) | src/design/UnitMatrix.tsx |
| CloneCascade | Cartão de ícone fonte + imitação aparece gradualmente + chip de alerta, metáfora de "ser copiado/destilado" | src/design/CloneCascade.tsx |
Componentes Inline de Cena em Lote (adicionados em 17/07/2026 para produção em lote, ainda não promovidos a componentes compartilhados)
Os componentes abaixo atualmente vivem apenas em uma única cena, marcados como "Inline de cena, promova para componente compartilhado em src/design e adicione linha de especificação em specs.md na segunda reutilização" – ao encontrar uma necessidade semelhante em um novo vídeo, verifique aqui primeiro, não recrie:
| Componente Inline | Localização | O que faz | Condição de Promoção |
|---|---|---|---|
| DissolveGrid | scenes/Scene08.tsx | Grade de dissolução: blocos do campo que será dissolvido dissolvem um por um, placa de fundo com ⚡ central desaparece, contorno branco flutua | Na segunda reutilização da metáfora de "dissolução de campo" |
| VerdictBox (caixa de decisão) | scenes/Scene17.tsx | Caixa de decisão espelho vermelho/verde: ≈400×170 moldura vazia primeiro erguida + header dentro + 3 chips horizontais entram em lote na caixa (vermelho primeiro, verde depois, criando suspense de "de que lado você está") | Na segunda reutilização da metáfora de "decisão VS" |
| NamePlate + CtaBadge (emblemas CTA) | scenes/Scene19.tsx | Linha horizontal no final do vídeo CTA: placa de nome primeiro como âncora → quatro emblemas de ação entram um por um (emblema de comentário é o mais largo = ênfase) | Na segunda reutilização de CTA de encerramento |
Especificações de Ícones
- Ícones devem sempre usar ícones SVG lineares de lucide-react, cor definida como semântica (
COLOR[accent]),strokeWidthem torno de 2.5; proibido usar emoji (blocos coloridos arredondados entram em conflito com o estilo linear monocromático dos vídeos de referência, lição da terceira rodada de aceitação em 07/2026). - A prop
iconde Chip / Checklist / SideLabel aceita ReactNode:icon={<Lock size={26} strokeWidth={2.5} />}.
Especificações de Textura → references/texture.md
Gradientes de bloco de gelatina, brilho da mesma cor, vinheta, logotipo verdadeiro, variantes claro/escuro de SURFACE, especificação única de carimbo – tudo em texture.md (desde 16/07/2026 é a única fonte de verdade para textura, o texto antigo desta seção foi movido).
4. Regras de Motion → references/motion.md
useEnter/useExit, entrada em ritmo de batida, intervalo de serviço, Breathe, tela limpa entre capítulos, itens proibidos – tudo em motion.md (desde 16/07/2026 é a única fonte de verdade para motion, o texto antigo desta seção foi movido; observe que a regra antiga "informação antiga fica transparente e permanente" foi substituída por "intervalo de serviço + disciplina de saída").
5. Auto-verificação Antes da Exportação (execute antes de cada renderização)
- Use
greppara verificar se algum componente tem valores de cor/tamanho de fonte/fonte inline fora dos tokens. - Todos os cartões permanentes ultrapassam a faceZone / subtitleZone?
- Cada destaque de palavra em título ≤ 1; o kicker em inglês está em maiúsculas com espaçamento?
- Capture 3–5 quadros-chave e compare lado a lado com as imagens de referência em
refs/; se não corresponder, identifique qual token está diferente, ajuste o token, não ajuste inline no componente.
6. Coleção de Erros
#01 Chinês silenciosamente regride para Song Ti (15/07/2026 · Primeiro dia do sistema de design)
- Sintoma: Na renderização/captura de tela, o texto chinês vira Song Ti, o texto inglês normal; o mesmo componente às vezes normal, às vezes não (depende da sorte).
- Causa: Três camadas, a última é a verdadeira culpada. ①
@remotion/google-fontspuxa fontes do gstatic em tempo de execução, rede doméstica não consegue puxar, fallback silencioso; ② Webfont chinês é dividido em pacotes por unicode-range, há condição de corrida entre carregamento e captura de tela; ③ Tree shaking:sideEffects: ["*.css"]empackage.jsonfaz com quefonts.ts, que é importado apenas por efeito colateral, seja completamente removido no bundle de produção, o CSS da fonte não está no bundle de renderização (document.fonts.size === 0) – o modo de desenvolvimento do Studio não faz tree shaking, então "Studio normal, renderização quebrada". - Correção: ① Fonte via
@fontsourcepacote local (src/design/fonts.ts); ②sideEffectsempackage.jsondeve incluir"src/design/fonts.ts"; ③ Qualquer composição com texto deve ter<FontGuard/>: loop load→check para verificar, e também deve verificardocument.fonts.size > 0(fonts.check()retorna verdadeiro vazio quando zero fontes estão registradas), timeout chamacancelRendercom erro, nunca renderizar silenciosamente um quadro com Song Ti. - Lição: "Studio normal, exportação quebrada" primeiro suspeite de diferenças de produção (tree shaking/compressão), não de condição de corrida mística; a aceitação de fontes deve depender da barreira rígida do FontGuard, olho humano não confia em miniaturas.
#02 Saída remotion still com ○ = reutilização de imagem antiga
- Sintoma: Código alterado, re-renderização, arquivo de saída parece inalterado; linha de comando mostra
○em vez de+. - Correção: Antes de aceitar a renderização, primeiro exclua a saída antiga (ou renderize para um novo nome de arquivo); se necessário, adicione
--bundle-cache=false.+= renderização real,○= suspeito. - Lição: A aceitação por comparação deve ser baseada em produtos de renderização confirmadamente frescos, caso contrário, pode diagnosticar erroneamente "correção ineficaz" (neste caso, perdeu duas rodadas por causa disso).
#03 Miniaturas de comparação enganam
- Sintoma: Na imagem lado a lado em miniatura, o chinês parece Song Ti, mas o original está normal.
- Correção: Ao julgar detalhes de fonte/contorno, recorte a resolução original e amplie a área local, não tire conclusões da miniatura do quadro inteiro.
#04 Atributo de string JSX não processa escape \uXXXX
- Sintoma:
<Chip icon="\u2705" />mostra literal\u2705na tela em vez de ✅. - Causa: Strings literais de atributos JSX são texto estilo HTML, não passam por escape JS; apenas strings em expressões JS (
icon={'\u2705'}) processam escapes. Mais fácil de pisar ao escrever TSX em lote com script. - Correção: Emoji/caracteres especiais em atributos JSX escreva o caractere diretamente (
icon="✅"); se precisar de escape, escreva comoicon={'\u2705'}.
#06 Texto gradiente com backgroundClip: text renderiza escuro
- Sintoma: Título grande usando backgroundImage gradiente + WebkitBackgroundClip:'text' + WebkitTextFillColor:'transparent', Studio aceitável, renderização sai escura e opaca (vermelho brilhante vira vermelho tijolo), usuário rejeita imediatamente.
- Correção: Conclusões grandes sempre usam cor semântica pura
COLOR[semantic]+ textShadow; para sensação de camada, use sombra e peso da fonte, não gradiente. tokens.GRADIENT é apenas para blocos de cor/contornos.
#08 Texto MG no produto final com auréola nas bordas, sensação de mancha ("adicionar MG piorou a qualidade do vídeo") (16/07/2026 · 0715-01 v3)
- Sintoma: Usuário vê o produto final e diz que a qualidade é ruim; ampliando, o texto MG tem ruído JPEG/auréola nas bordas, quanto mais nítido o elemento, mais óbvio. O material base HEVC 15 Mbps é muito limpo.
- Causa: Pipeline padrão do Remotion tem compressão dupla – cada quadro é capturado como JPEG qualidade 80, depois comprimido H264 com CRF 18. Texto MG grande/linhas finas são sinais de alta frequência, os primeiros a sofrer artefatos de compressão. Antes de adicionar MG, os artefatos estavam escondidos nas texturas do material real, por isso foi diagnosticado erroneamente como "MG causa má qualidade visual".
- Correção:
remotion.config.tsfixado comConfig.setJpegQuality(100)+Config.setCrf(15)(já configurado neste projeto, não reverta). Aumento de volume de ~20%, renderização um pouco mais lenta, vale a pena. - Método de diagnóstico: Capture um quadro do material/versão antiga/nova versão de teste, recorte a mesma área de texto MG, amplie e compare lado a lado; primeiro renderize um segmento de teste de 5 segundos para validar os parâmetros antes de renderizar o vídeo inteiro.
#09 Renderização longa desaparece no meio, mp4 fica truncado (16/07/2026 · 0715-01 v3)
- Sintoma: A renderização roda por muito tempo, "o processo ainda está lá" mas o arquivo de saída não cresce por um longo período; ou a renderização desaparece silenciosamente, deixando um mp4 que não abre.
- Causa: ① A renderização está pendurada em um subprocesso da sessão de IA, o reinício/desconexão da sessão mata a renderização (neste caso, foi morta em 90%); ② Detectar o processo com
pgrep -f "remotion render"corresponde ao próprio script de detecção (a linha de comando contém a mesma string), criando a ilusão de que "o processo ainda está vivo". - Correção: ① Renderizações com mais de alguns minutos sempre devem usar
nohup npx remotion render … > /tmp/xx.log 2>&1 & disownpara se desconectar da sessão; ② O critério de conclusão deve reconhecer a linha+ nome_do_arquivo_de_saídano log (+= renderização real bem-sucedida), não a existência do processo; ③ Para detectar o processo, exclua a auto-correspondência (veja uso de CPU ou use PID exato); ④ Antes de re-renderizar, exclua o arquivo truncado. - Lição: Arquivo mp4 truncado (duração/volume não correspondem) nunca é entregue; primeiro use
ffprobepara verificar duração e trilha de áudio antes de mostrar ao usuário.