ccvideo — Vídeos promocionais de produto estilo Claude
Você está produzindo um vídeo promocional curto (20–45 s, 1920×1080 @ 30 fps) na linguagem visual dos vídeos de lançamento da Anthropic Claude: uma tela terracota aquecida, uma única janela de terminal macOS executando uma sessão do Claude Code, texto que digita e flui, leves movimentos de câmera entre enquadramentos fixos, cartões de título serifados.
Pré-requisitos
- Um projeto Remotion deve existir. Caso contrário, crie um:
npx create-video@latest --yes --blank --no-tailwind .e depoisnpm i. - Pacotes (instale com
npx remotion add <pkg>para garantir versões compatíveis):@remotion/google-fonts,@remotion/transitions,zod(declare zod explicitamente — a biblioteca o importa diretamente; não dependa dele como dependência transitiva). - A biblioteca de componentes deve existir em
src/ccvideo/. Caso contrário, copie todos os arquivos do diretóriotemplates/desta skill parasrc/ccvideo/. Não reescreva esses componentes do zero. - As ferramentas de captura/verificação devem existir em
scripts/na raiz do projeto. Caso contrário, copie o diretórioscripts/desta skill (incluindoscripts/lib/) para lá. Todos os scripts resolvemcaptures/em relação ao diretório de onde são executados, portanto sempre execute-os da raiz do projeto.
Verdade absoluta (regras de conteúdo não negociáveis)
O conteúdo do vídeo nunca é escrito manualmente nos componentes de cena. Cada fato exibido — números, caminhos, endpoints, saída de comandos, contagens de linhas — deve vir de uma captura de algo que realmente foi executado:
- Cada vídeo tem um diretório
captures/<nome>/contendo artefatos brutos (respostas de API, eventos de sessão extraídos) além de umprops.jsonconstruído a partir deles deterministicamente.props.jsoné a única fonte da verdade que a composição renderiza. - Capture primeiro. Antes de fazer o vídeo, execute a coisa real:
node scripts/capture-xapi-cli.mjs— dados X ao vivo via a CLI xapi (npx xapi-to, chave em~/.xapi/config.json; a skillxapiem.agents/skills/xapi/documenta todas as suas capacidades).node scripts/capture-x-user.mjs— variante da API X oficial (requerX_BEARER_TOKEN;--sampleescreve dados de placeholder comraw-meta.jsonmarcado comosample: true— nunca publique uma captura de exemplo).node scripts/transcript-to-props.mjs <session.jsonl> --prompt-match <str> --out captures/<nome>— reproduz uma rodada real de sessão do Claude Code (transcrições ficam em~/.claude/projects/<project-slug>/*.jsonl).- Nova fonte de dados? Escreva um novo script de captura seguindo o mesmo padrão:
buscar realidade → salvar bruto → construir props via um construtor determinístico
compartilhado em
scripts/lib/.
- Verifique antes de publicar:
node scripts/verify-props.mjs captures/<nome>reconstrói os props a partir dos artefatos brutos e falha em qualquer edição manual. Corrija recapturando, nunca editandoprops.json. - Limite de reprodução honesta: o ritmo é uma performance (velocidade de digitação, tempo
de spinner), mas a capacidade deve ser real — o vídeo só pode mostrar o que a execução
capturada realmente fez. Isso se estende ao chrome: fatos do cabeçalho da sessão
(versão do Claude Code, cwd) vêm da captura (
claude --version, cwd real) ou o cabeçalho é omitido; o contador de tokens do spinner renderiza apenas quando a captura fornece um valor real dethinkingTokens(caso contrário, apenas segundos). Capturas de exemplo falham noverify-propscompletamente (--allow-sampleexiste apenas para testes de pipeline). - As capturas visam ser seguras para commit, com defesa em profundidade — não uma garantia:
transcript-to-propspersiste apenas as entradas que o vídeo realmente usa (as linhas exibidas dos eventos selecionados + contagens, uma saída de comando truncada, as linhas do resumo), remove strings com formato de segredo (chaves de API, tokens Bearer, credenciais em URL, campos de senha em env/JSON, chaves privadas) e reescreve caminhos home normais e achatados por slug para~— tudo antes que os props sejam construídos, para que props, vídeo e brutos arquivados vejam conteúdo redigido idêntico. Listas de padrões nunca podem ser completas: sempre revise uma captura antes de commitar e trate qualquer aviso de redação como um sinal de parada.
Fluxo de trabalho
- Capture primeiro (veja Verdade absoluta): produza
captures/<nome>/props.jsona partir de uma execução real. - Roteiro a partir da captura. O texto de apresentação (títulos de cartão, palavra de pensamento) vive nas constantes/flags do script de captura — escolha o único prompt, o trecho de código, a saída da execução, os pontos do resumo. Busque o arco clássico: código → criado → executado+saída → resumo.
- Componha: registre uma
<Composition>emsrc/Root.tsxusandoGroundedVideodesrc/ccvideocomschema={groundedVideoSchema},defaultPropsimportado doprops.jsonda captura ecalculateMetadataderivando a duração viagroundedVideoDuration— as durações seguem o conteúdo automaticamente. Trabalho de cena personalizado além do arco padrão: construa com os primitivos da biblioteca, mesmas regras. - Verifique com stills antes de declarar pronto. Renderize um still por trecho:
npx remotion still <CompId> --frame=<n> --scale=0.5 out.pnge observe-os. Verifique: nada cortado pela janela do terminal (um aviso de overflow[ccvideo]na saída de renderização significa que é preciso aparar trechos), o ritmo parece sem pressa, as cores correspondem à paleta. - Execute
node scripts/verify-props.mjs captures/<nome>, depois pré-visualize comnpx remotion studio --no-open; renderize finalmente comnpx remotion render <CompId> out/<CompId>.mp4(adicione--props=captures/<nome>/props.jsonpara renderizar uma captura diferente sem tocar no código; adicione--scale=2para um master 4K como os demos oficiais — as composições permanecem 1920×1080 @ 30 fps no código).
Dois temas
Escolha por produto, ambos compartilham o terracota da marca #D97656/#D97757:
- Terracota (padrão) — tela quente, sessão REPL do Claude Code. Para
histórias de agente/fluxo de trabalho com IA. Componentes:
GroundedVideo/DataSession. - Escuro (a gramática do demo CLI
ant) — tela quase preta#0B0B0B, terminal preto-aquecido#181716separado apenas por uma borda sutil, prompt de shell▶ ~/dir >(seta#8B92C9, chevron#5FA97B), serifa creme#D6D4CF. A estrutura é capitulada: cartão de logotipo pixelado → [cartão de transição (kicker mono + divisor fino + afirmação serifa) → novo trecho de shell (digitar comando real, saída real fade-in, prompt ocioso retorna)] por capítulo → wordmark de encerramento. Para produtos CLI/ferramentas de desenvolvedor. Componentes:DarkVideo/ShellBeat/InterstitialCard/WordmarkCard, paletadarkemtheme.ts, esquemadarkVideoSchema(construído a partir de capturas como o tema claro — por exemplo,props-dark.jsonescrito porcapture-xapi-cli.mjs, verificado porverify-props.mjs).
O visual (regras de estilo não negociáveis)
- Tela
#CC7D5D, terminal#2B2C36, barra de título#3A3634. Texto do corpo#E3E4EB, dim#9899A1, comentários#6C6E6A, números de linha#83848C. Acentos: pervinca#B8B9F2(caminhos, código inline, strings), teal#85BEC5(palavras-chave), dourado#F2C43D(setas de status). Tudo definido emsrc/ccvideo/theme.ts— importe, nunca codifique manualmente. - Fontes: JetBrains Mono para tudo do terminal, Source Serif 4 para cartões de
título. Carregadas em
theme.tsvia@remotion/google-fonts, com Noto Sans SC já adicionado como fallback CJK para ambas as pilhas — prompts em chinês renderizam sem configuração adicional. - Janela do terminal 1560×950 centralizada (985 quando um
headerde sessão é exibido; tema escuro 1860×1010), raio de 14 px, sombra suave profunda, três luzes de tráfego, texto da barra de título mono que reflete a tarefa, por exemplo,dev — · Implement X — claude — 106×31. - A sessão do Claude Code deve parecer real: linha de entrada
>acima de uma barra de status dourada⏵⏵ auto mode on (shift+tab to cycle) · esc to interrupt(ambas sempre visíveis, fixadas na parte inferior); um spinner✻ Cogitating…em um espaço de altura fixa logo acima da linha de entrada; marcadores de resultado de ferramenta●; um bloco de código numerado terminando em… +N lines (ctrl+o to expand); um resumoWhat it doesem negrito com marcadores-. - Câmera: sem zoom contínuo ou pan em cenas de terminal — nunca. Movimentos de câmera
em escala fracionária lenta fazem o texto mono pequeno deriva e flutuar visivelmente. O único
movimento de câmera permitido é
<CutZoom>: movimentos breves e fortemente suavizados (~0,6 s) entre enquadramentos fixos — aproxime-se de conteúdo denso, segure, afaste para a revelação. O texto pode estar em escala média apenas durante um movimento rápido deliberado, nunca por segundos. Mantenha a mesmaoriginno afastamento que na aproximação para que não pareça um deslize lateral.DataSessionaplica isso automaticamente ao redor do trechorun.<SlowZoom>permanece apenas para cartões de título. - Chrome de autenticidade da sessão (tudo orientado por esquema, tudo opcional):
header(logotipo pixel +Claude Code vX+ linha modelo/cwd, sempre visível),windowTitleIdle→ trocawindowTitleno envio do prompt, eco do prompt como um bloco destacado, spinner com contadores ao vivo(Ns · ↓ N tokens)e um opcional⎿ Tip:, barra de status que ganhaesc to interruptapenas durante o trabalho. Tipos de trecho extras:answer(bloco de prosa rico),alert(linha destacada em vermelho), trechostoolpodem carregar linhas filhas⎿. - Sem deriva de transcrição. O texto do terminal só pode aparecer no lugar: sem animações de entrada posicionais dentro da janela e nunca monte/desmonte um elemento que reflua as linhas abaixo dele — linhas transitórias (spinners, progresso) vivem em espaços de altura fixa para que seu desaparecimento não desloque nada.
- Cartões de título: manchete serifada em preto quase sólido
#1F1508sobre o terracota, subtítulo mono com opacidade de 68 %, entrada fade-up. Manchete ≥ 132 px, subtítulo ≥ 52 px a 1920 de largura.
API de componentes (src/ccvideo)
Camada orientada a dados (preferida para vídeos inteiros):
<GroundedVideo {...props}>— cartão de introdução → sessão → cartão de encerramento, inteiramente a partir de um valorgroundedVideoSchema(umprops.jsonde captura).<DataSession {...props.session}>— renderiza qualquer valorsessionSchema: cabeçalho opcional, digitação do prompt, spinner, depoisbeats(união discriminada:code,tool,run,summary,answer,alert). Aplica o corte-zoom do trecho de execução automaticamente; avisa em tempo de renderização se o conteúdo transbordar.sessionTiming(props, fps)/groundedVideoDuration(props, fps)— derivação de tempo pura; use emcalculateMetadata.<Rich segments>— renderiza segmentos JSON{t: 'plain'|'kw'|'code'| 'comment'|'dim'|'bold', s}; a ponte de props.json para texto estilizado.
Primitivos de apresentação:
<TerminalWindow title width? height? variant?>— janela na tela (variant="dark"para o tema escuro). Os filhos são uma coluna flex; dê à transcriçãoflex: 1para que<InputBox>+<StatusBar>fixem na parte inferior.<TypeText text from cps? cursor?>/<Cursor>— máquina de escrever, 35–45 cps.<InputBox typedText? from? cps?>— linha>; semtypedText= cursor piscando.<StatusBar mode? hint?>.<Thinking from? until? word? stats? tokens? tip?>— spinner;statsmostra(Ns)ao vivo — mais↓ N tokensapenas quandotokenscarrega uma contagem real capturada;tipadiciona uma linha⎿ Tip:. Coloque-o em um espaço de altura fixa entre transcrição e entrada;untilo desaparece no lugar.<Line from?>— uma linha de saída, fade-in de 8 quadros (apenas opacidade).<ToolLine from>— linha de marcador●.<CodeBlock from lines stagger? startLineNo? expandNote?>— linhas numeradas.- Spans de token:
<K>palavra-chave,<C>código/caminho,<Cm>comentário,<Dim>,<B>. <SessionHeader version modelLine>,<PromptEcho>,<AlertLine from?>,<ToolChild from?>— chrome da sessão (veja regras de estilo).<CutZoom cuts={[{from, scale?, origin?, ease?}]}>— movimentos breves suavizados entre enquadramentos fixos; o único movimento de câmera permitido em cenas de terminal.<SlowZoom from? to?>— apenas cartões de título, nunca em torno de um terminal.<TitleCard title subtitle? titleSize?>.
Toda animação é orientada por quadros (useCurrentFrame + interpolate, clamped,
inline em style). Nunca use transition/animation do CSS.