Communitygithub.com

d0-hyperframe

Crie vídeos da marca D0 com HyperFrames. Inclui extração de assets, configuração de projeto, layout de cena, animações GSAP, especificações de componente TG e regras de transição.

O que é d0-hyperframe?

O skill **d0-hyperframe** é um fluxo de trabalho completo para produzir vídeos da marca D0 usando HTML, CSS e GSAP no ecossistema HyperFrames. Ele define regras rígidas e não negociáveis para tipografia (fontes Instrument Serif e Open Sans), paleta de cores (roxo, branco, tons de cinza, gradiente), layout de tela (duas colunas, fundo fixo), animação de componentes (stagger com overlaps) e transições (apenas nível de componente, nunca de tela inteira). O skill é acionado por comandos como "fazer um vídeo D0" e suporta as plataformas Claude Code, Cursor e Codex (via scripts bash). Ele inclui um script de inicialização que configura o projeto HyperFrames e copia os assets da marca (logo, avatar, fontes). As animações são construídas com GSAP, sempre usando `fromTo` para garantir seek determinístico, e as transições entre beats usam staggered entry/exit com sobreposição de 0.2–0.3s para eliminar o efeito "PPT cut". O skill também especifica a estrutura do componente de painel do Telegram (TG), com avatar obrigatório e sem tags `<img>`. O resultado final deve passar pelo lint do HyperFrames com zero erros antes da pré-visualização.

Funciona com~Claude Code✓Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/scof-real/d0-hyperframe-skill/tree/main/skills/d0-hyperframe

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

D0 HyperFrame - Criação de Vídeos

Fluxo de trabalho completo para produzir vídeos da marca D0 com HyperFrames HTML + GSAP. Este documento é a única autoridade — regras de fontes, cores, layout, animação e transições estão definidas aqui.

A especificação de fontes do skill d0-brand é a autoridade final; este skill apenas complementa as regras relacionadas à produção de vídeos.


Palavras de ativação

  • "Fazer um vídeo D0" / "d0 hyperframe"
  • "Usar hyperframes para fazer vídeo" / "/d0-hyperframe"

Passo 0 — Inicializar projeto e assets

Recomendado: usar script de inicialização fornecido com o skill

Após instalar o repositório, execute o script deste skill. Ele inicializará o projeto HyperFrames e copiará o Logo D0, o Avatar D0 e todas as fontes necessárias:

bash "${CODEX_HOME:-$HOME/.codex}/skills/d0-hyperframe/scripts/bootstrap_project.sh" .

Se o projeto já estiver inicializado, sincronize apenas os assets da marca:

bash "${CODEX_HOME:-$HOME/.codex}/skills/d0-hyperframe/scripts/bootstrap_project.sh" . --assets-only

O script depende do Node.js 18+ e do npx. O CLI do HyperFrames é executado sob demanda via npx hyperframes@latest, sem copiar pacotes de terceiros no repositório do skill.

Opcional: sobrescrever D0_AVATAR e Logo a partir de HTML fonte

Extrair D0_AVATAR e Logo de HTML fonte

O HTML do pôster fonte geralmente contém dois tipos de imagens base64:

AssetTipoCaracterísticaUso
D0 LogoPNG, aprox. 12–16 KB.brand img ou menor PNGCanto superior esquerdo de todas as cenas
D0_AVATARJPEG, aprox. 100 KB.av ou maior JPEGAvatar do componente TG
python3 - << 'EOF'
import re, base64, os

with open('SOURCE.html', 'r') as f:
    src = f.read()

os.makedirs('assets', exist_ok=True)

# Logo (menor PNG)
pngs = re.findall(r'(data:image/png;base64,[A-Za-z0-9+/=]+)', src)
logo_b64 = min(pngs, key=len)
with open('assets/d0-logo.png', 'wb') as f:
    f.write(base64.b64decode(logo_b64.split(',')[1]))

# D0_AVATAR (maior JPEG)
jpegs = re.findall(r'data:image/jpeg;base64,([A-Za-z0-9+/=]+)', src)
avatar = max(jpegs, key=len)
with open('assets/d0-avatar.jpg', 'wb') as f:
    f.write(base64.b64decode(avatar))

print("assets/ pronto:", os.listdir('assets'))
EOF

Fontes (método manual)

mkdir -p fonts
cp /path/to/d0-hyperframe/assets/fonts/*.woff2 fonts/
# Necessário: InstrumentSerif-Regular.woff2, InstrumentSerif-Italic.woff2
#       OpenSans-400/600/700/800-normal.woff2

Inicialização do projeto (método manual)

npx hyperframes@latest init . --non-interactive --example blank --skill=d0-hyperframe

Passo 1 — Tokens da marca (CSS)

:root {
  --bg:    #06060d;
  --pu2:   #b3a8f7;
  --white: #f2f2f5;
  --t2:    #8d8d98;
  --t3:    #5a5a66;
  --green: #3ddc84;
  --red:   #f87171;
  --gold:  #f7a93a;
  --bdr:   #23232c;
  --bdr2:  #2e2e39;
  --grad:  linear-gradient(120deg, #5468F5 0%, #9B4FD6 34%, #C25C9A 62%, #DD8B57 100%);
}

@font-face { font-family:'Instrument Serif'; src:url('fonts/InstrumentSerif-Regular.woff2') format('woff2'); font-weight:400; font-style:normal; }
@font-face { font-family:'Instrument Serif'; src:url('fonts/InstrumentSerif-Italic.woff2')  format('woff2'); font-weight:400; font-style:italic; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-400-normal.woff2') format('woff2'); font-weight:400; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-600-normal.woff2') format('woff2'); font-weight:600; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-700-normal.woff2') format('woff2'); font-weight:700; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-800-normal.woff2') format('woff2'); font-weight:800; }

Passo 2 — Estrutura do palco (stage persistente + camada de componentes)

Modelo central: uma camada de fundo fixa, conteúdo dividido em componentes. O fundo + elementos fixos (logo/footer/trilho superior) pertencem à camada persistente, imóveis durante todo o vídeo; título, dados, painel TG, gráficos etc. são componentes .blk independentes, cada um com sua própria entrada/saída. As transições acontecem no nível do componente, não no nível da tela inteira — esta é a chave para eliminar o "corte PPT".

Esqueleto HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D0 · [título do vídeo]</title>
<style>/* tokens + CSS da cena */</style>
</head>
<body>
<div id="main"
  data-composition-id="main"
  data-start="0"
  data-duration="[segundos totais]"
  data-width="1920"
  data-height="1080">

  <!-- ── Camada persistente: imóvel durante todo o vídeo, sem animações tl (ver Passo 3) ── -->
  <div class="bg"></div>
  <div class="rail"></div>
  <div class="logo"></div>
  <div class="foot-tag">Agentic Trading for Every Market.</div>
  <div class="foot-url">getdonut.ai</div>

  <!-- ── Camada de conteúdo: agrupada por beat, componentes entram e saem entrelaçados (ver Passo 6) ── -->
  <!-- beat 1 -->
  <div class="blk" id="b1-title">...</div>
  <div class="blk" id="b1-sub">...</div>
  <!-- beat 2 -->
  <div class="blk" id="b2-stat">...</div>
  <div class="blk" id="b2-tg">...</div>

</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>/* linha do tempo GSAP */</script>
</body>
</html>

CSS do palco (camada persistente + camada de conteúdo)

/* Container do palco */
#main {
  position: absolute; inset: 0; overflow: hidden;
  font-family: 'Open Sans', sans-serif; color: var(--white);
}

/* Fundo persistente — fixo durante todo o vídeo, nunca entra na animação tl */
.bg {
  position: absolute; inset: 0; width: 1920px; height: 1080px; z-index: 0;
  background: var(--bg);
  background-image:
    radial-gradient(ellipse 46% 58% at 76% 50%, rgba(150,128,255,.16) 0%, transparent 60%),
    radial-gradient(ellipse 62% 50% at 8%   4%, rgba(110,100,255,.10) 0%, transparent 56%);
}

/* Trilho gradiente superior — fixo, apenas um para todo o vídeo */
.rail {
  position: absolute; top: 0; left: 0; right: 0; height: 5px; z-index: 10;
  background: var(--grad);
}

/* Componente de conteúdo — unidade mínima de animação, oculto por padrão, entradas e saídas individuais */
.blk { position: absolute; opacity: 0; z-index: 2; }

Modelo antigo: cada tela .scene com seu próprio fundo e deslizamento inteiro → sensação de PPT + ponto de parada. Novo modelo: apenas uma camada de fundo fixa, conteúdo dividido em componentes .blk, transições no nível do componente (ver Passo 6).


Passo 3 — Especificação de elementos fixos (não negociável)

Os três elementos a seguir são consistentes em todas as cenas e não devem ter animação de entrada ou saída:

ElementoPosiçãoTamanho da fonteDescrição
Donut LogoCanto superior esquerdo top:40px left:72px200×76pxCSS background, não usar <img>
Agentic Trading for Every Market.Canto inferior esquerdo bottom:48px left:72px27pxInstrument Serif itálico, --pu2
getdonut.aiCanto inferior direito bottom:50px right:72px14pxOpen Sans, --t3
/* Logo — CSS background, não escrever opacity:0 */
.logo {
  position: absolute; top: 40px; left: 72px; z-index: 10;
  width: 200px; height: 76px;
  background: url('assets/d0-logo.png') left center / contain no-repeat;
}

/* Footer — visível imediatamente, sem animação */
.foot-tag {
  position: absolute; bottom: 48px; left: 72px; z-index: 10;
  font-family: 'Instrument Serif', serif; font-style: italic;
  font-size: 27px; color: var(--pu2);
}

.foot-url {
  position: absolute; bottom: 50px; right: 72px; z-index: 10;
  font-size: 14px; font-weight: 700; letter-spacing: .06em; color: var(--t3); opacity: 0;
}

Elementos fixos pertencem à camada persistente, visíveis desde o frame 0, sem nenhuma animação tl durante todo o vídeo. foot-tag fica visível diretamente; foot-url pode ter um leve fade-in único, mas não é obrigatório.


Passo 4 — Princípios de layout

Equilíbrio esquerda-direita, eliminar espaço central vazio

  • Layout de duas colunas preferencialmente: texto/dados à esquerda, componente TG/imagem à direita
  • Quando houver imagem de fundo de personagem à direita: posicionamento absoluto preenchendo a direita, com gradiente de máscara da esquerda para a direita
.scene-char {
  position: absolute; top:0; right:0; bottom:0; width:62%;
  background: url('assets/bg-char.png') right center / cover no-repeat;
  z-index: 0;
}
.scene-char::after {
  content:''; position:absolute; inset:0;
  background: linear-gradient(to right,
    var(--bg) 0%, rgba(6,6,13,.82) 18%, rgba(6,6,13,.45) 45%, transparent 100%);
}
  • Área de texto à esquerda deve ter position: relative; z-index: 2 para garantir que fique acima da imagem de fundo

Tamanhos mínimos de fonte

Com base no vídeo D0 Thorp Engine, não devem ser inferiores a:

NívelTamanho mínimoFonte
Título principal80pxInstrument Serif
Subtítulo da cena56pxInstrument Serif
Kick label / eyebrow18pxOpen Sans 700 maiúsculo
Corpo / feature bullet22pxOpen Sans
Âncora de dados (stat-val)48pxInstrument Serif
Footer tag27pxInstrument Serif itálico
Texto interno do componente TG13px (valor mínimo aceitável)Open Sans

Passo 5 — Especificação do componente TG

Avatar: deve usar D0_AVATAR

/* Avatar grande (header, 40px) */
.av  { width:40px; height:40px; border-radius:50%; flex:none;
       background: url('assets/d0-avatar.jpg') center/cover no-repeat; }

/* Avatar pequeno (linha de mensagem, 28px) */
.mav { width:28px; height:28px; border-radius:50%; flex:none; margin-top:2px;
       background: url('assets/d0-avatar.jpg') center/cover no-repeat; }

Não usar tags <img> para evitar que o HyperFrames detecte nós de mídia duplicados (aviso de lint). Não usar fallback gradiente — deve ser o arquivo D0_AVATAR real.

Estrutura do Painel TG

<div id="tg-panel">
  <div class="tg-chrome">
    <div class="dot r"></div><div class="dot y"></div><div class="dot g"></div>
    <div class="tg-url">t.me / D0_Bot</div>
  </div>
  <div class="tg-hdr">
    <div class="av"></div>
    <div>
      <div class="tg-nm">D0</div>
      <div class="tg-st">bot · online</div>
    </div>
  </div>
  <div class="tg-body">
    <div class="msg-user">prompt do usuário</div>
    <div class="msg-bot">
      <div class="mav"></div>
      <div class="bbubble">conteúdo da resposta D0</div>
    </div>
  </div>
</div>

Passo 6 — Regras de transição (não negociável)

Princípio central: fundo não se move, componentes se movem. A "sensação PPT" vem de toda a cena (incluindo fundo) deslizando junto — o espectador perde o ponto de referência estável; O "ponto de parada" vem das animações de saída e entrada conectadas ponta a ponta — há um instante de paralisação total entre elas. A solução para ambos é a mesma frase: fundo fixo + componentes entrando e saindo entrelaçados e sobrepostos.

Transição padrão: entrada/saída escalonada de componentes (element cross-stagger)

Fundo + elementos fixos (logo/footer/trilho) permanecem imóveis durante todo o vídeo. A cada troca de beat, apenas os componentes de conteúdo se movem:

  • Componentes do beat antigo saem sequencialmente (stagger, ease .in, leve deslocamento + fade out)
  • Componentes do novo beat entram sequencialmente (stagger, ease .out)
  • Os dois tempos se sobrepõem em ≈ 0,2–0,3s — os antigos ainda não terminaram de sair, os novos já começam a entrar. Esta é a chave para eliminar os pontos de parada.
// Troca de beat: componentes antigos saem escalonados, novos entram escalonados, com sobreposição de tempo (não ponta a ponta)
function beat(outEls, inEls, t) {
  outEls.forEach((el, i) =>
    tl.to(el, { opacity:0, y:-30, duration:0.45, ease:'power2.in' }, t + i*0.06));
  inEls.forEach((el, i) =>
    tl.fromTo(el, { opacity:0, y:40 },
      { opacity:1, y:0, duration:0.6, ease:'expo.out' }, t + 0.2 + i*0.08));  // +0.2 = sobreposição
}
// Uso: beat(['#b1-title','#b1-sub'], ['#b2-stat','#b2-tg'], 4.0);
  • Deslocamento pequeno (20–40px); direção pode ser uniforme (ex.: todos para cima) para criar uma "corrente de ar de virada de página", mas fundo nunca participa.
  • Com muitos componentes, use stagger para que a tela tenha movimento contínuo, evitando "entrada simultânea → congelamento geral".

Quando usar transição de tela inteira

Apenas em grandes seções (ex.: cartão de título da marca → seção de dados) e, mesmo assim, apenas empurrando a camada de conteúdo, não o fundo — agrupe os componentes da seção em um container #grp e empurre-o:

// Push-slide (apenas empurra o container de conteúdo, fundo .bg não se move)
tl.to('#grpA',     { x:-1920, duration:0.55, ease:'power3.inOut' }, t);
tl.fromTo('#grpB', { x:1920, opacity:1 }, { x:0, duration:0.55, ease:'power3.inOut' }, t);

// Blur crossfade (transição emocional, geralmente usada para a última transição)
tl.to('#grpC', { filter:'blur(20px)', opacity:0, duration:0.65, ease:'power2.in' }, t);
tl.fromTo('#grpD', { filter:'blur(20px)', opacity:0 },
  { filter:'blur(0px)', opacity:1, duration:0.65, ease:'power2.out' }, t);

❌ Proibido: tela inteira (incluindo fundo) deslizando, zoom de canto, zoom de tela inteira, saída/entrada ponta a ponta sem sobreposição.


Passo 7 — Regras de animação GSAP

Obrigatório

const tl = gsap.timeline({ paused: true });
// ... tweens ...
window.__timelines['main'] = tl;
  • Usar tl.fromTo() em vez de tl.from() (garantir determinismo de seek do HyperFrames)
  • Animações repetitivas usar Math.floor(duration / cycle) - 1, proibido repeat: -1
  • Múltiplas animações no mesmo elemento adicionar overwrite: 'auto'
  • Entrada usar ease .out, saída usar ease .in

Layout primeiro, animação depois

Escreva primeiro o estado final do elemento (posicionamento CSS), depois use fromTo para descrever o caminho de entrada:

// ✅ Correto
tl.fromTo('#title', { opacity:0, y:40 }, { opacity:1, y:0, duration:0.8, ease:'expo.out' }, 0.3);

Camada persistente sem animação

.bg, .rail, .logo, .foot-tag, .foot-url são fixos durante todo o vídeo. Animações ocorrem apenas nos componentes .blk. Assim que o fundo se move, volta a sensação de PPT — transições movem apenas a camada de conteúdo (ver Passo 6 beat()).


Passo 8 — Lint & Pré-visualização

npx hyperframes lint     # deve ter 0 erros
npx hyperframes preview  # http://localhost:300x, hot reload
Aviso comumTratamento
overlapping_gsap_tweensAdicionar overwrite:'auto'
duplicate_media_discovery_riskSubstituir <img> por CSS background:url()
composition_file_too_largeIgnorar se arquivo único < 500 linhas

Dependências e fontes de assets

  • Skill d0-brand: autoridade final para fontes, tamanhos e princípios da marca; deve ser instalado junto com este skill.
  • HyperFrames CLI: obtido sob demanda via npx hyperframes@latest.
  • GSAP: versão 3.14.2 CDN fixada nos exemplos; se atualizar a versão, execute novamente lint e seek para validação.
  • assets/fonts/: Instrument Serif e Open Sans; arquivos de licença estão nos diretórios das fontes correspondentes.
  • assets/brand/: Logo D0 e Avatar D0, uso exclusivo por membros autorizados da equipe Donut para conteúdo da marca D0.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas