Communitygithub.com

d0-hyperframe

Crea videos de la marca D0 con HyperFrames. Incluye extracción de activos, configuración de proyectos, diseño de escenas, animaciones GSAP, especificaciones de componentes TG y reglas de transición.

¿Qué es d0-hyperframe?

Esta habilidad para agentes de IA (como Claude Code, Cursor o Codex) proporciona un flujo de trabajo completo y listo para usar para la producción de videos de la marca D0 utilizando HyperFrames HTML, GSAP y CSS. Está diseñada para agentes de ingeniería de software que necesitan crear videos promocionales o demostraciones de productos de alta calidad con la apariencia y sensación consistentes de la marca D0. La habilidad guía al agente a través de un proceso estructurado de 8 pasos: inicialización del proyecto y extracción de activos (imágenes, fuentes, logotipos), definición de tokens de marca CSS, construcción de una capa de fondo persistente y un sistema de componentes de contenido, diseño de escenas equilibradas, creación de paneles estilizados de Telegram (TG) y aplicación de reglas de transición estrictas a nivel de componente para evitar la sensación de 'diapositiva PowerPoint'. Las reglas de transición son un punto clave: en lugar de animar pantallas enteras (lo que se siente entrecortado), la habilidad mantiene el fondo fijo y anima componentes individuales de forma escalonada y superpuesta, logrando transiciones suaves y continuas. La habilidad también incluye un script de arranque para configurar el proyecto rápidamente, pautas para usar GSAP (por ejemplo, usar siempre `fromTo`, evitar bucles infinitos) y un paso de linting para garantizar que el resultado final esté libre de errores.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

D0 HyperFrame - Creación de Videos

Flujo de trabajo completo para crear videos de la marca D0 con HyperFrames HTML + GSAP. Este documento es la única autoridad en cuanto a reglas de fuente, color, diseño, animación y transición.

La especificación de fuentes definitiva está en el skill d0-brand; este skill solo complementa las reglas relacionadas con la producción de videos.


Palabras clave de activación

  • "Haz un video de D0" / "d0 hyperframe"
  • "Usa hyperframes para hacer un video" / "/d0-hyperframe"

Paso 0 — Inicializar proyecto y activos

Recomendado: Usar el script de inicialización incluido con el Skill

Después de instalar el repositorio, ejecuta el script dentro de este Skill. Inicializará un proyecto HyperFrames y copiará el logotipo de D0, el avatar de D0 y todas las fuentes necesarias:

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

Si el proyecto ya está inicializado, solo sincroniza los activos de la marca:

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

El script requiere Node.js 18+ y npx. La CLI de HyperFrames se ejecuta bajo demanda mediante npx hyperframes@latest y no copia paquetes de terceros en el repositorio del Skill.

Opcional: Sobrescribir D0_AVATAR y Logotipo desde el HTML fuente

Extraer D0_AVATAR y Logotipo desde el HTML fuente

El HTML del póster fuente normalmente incluye dos tipos de imágenes base64 incrustadas:

ActivoTipoCaracterísticaUso
Logotipo de D0PNG, ~12–16 KB.brand img o PNG más cortoEsquina superior izquierda de todas las escenas
D0_AVATARJPEG, ~100 KB.av o JPEG más largoAvatar del componente TG
python3 - << 'EOF'
import re, base64, os

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

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

# Logotipo (PNG más corto)
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 (JPEG más largo)
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/ listo:", os.listdir('assets'))
EOF

Fuentes (método manual)

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

Inicialización del proyecto (método manual)

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

Paso 1 — Tokens de 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; }

Paso 2 — Estructura del escenario (escenario persistente + capa de componentes)

Modelo central: una capa de fondo fija, el contenido se divide en componentes. El fondo + elementos fijos (logotipo/pie de página/carril superior) pertenecen a la capa persistente, que no se mueve en todo el video; los títulos, datos, paneles TG, gráficos, etc., son componentes .blk independientes, cada uno con su propia entrada y salida. Las transiciones ocurren a nivel de componente, no a nivel de pantalla completa; esta es la base para eliminar los "cortes bruscos tipo PowerPoint".

Esqueleto HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D0 · [Título del video]</title>
<style>/* tokens + CSS de escena */</style>
</head>
<body>
<div id="main"
  data-composition-id="main"
  data-start="0"
  data-duration="[segundos totales]"
  data-width="1920"
  data-height="1080">

  <!-- ── Capa persistente: no se mueve en todo el video, sin animación tl (ver Paso 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>

  <!-- ── Capa de contenido: agrupada por beat, componentes entran y salen escalonadamente (ver Paso 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>/* Línea de tiempo GSAP */</script>
</body>
</html>

CSS del escenario (capa persistente + capa de contenido)

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

/* Fondo persistente — fijo en todo momento, nunca entra en animación 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%);
}

/* Carril degradado superior — fijo, solo uno en todo el video */
.rail {
  position: absolute; top: 0; left: 0; right: 0; height: 5px; z-index: 10;
  background: var(--grad);
}

/* Componentes de contenido — la unidad mínima de animación, ocultos por defecto, entran y salen individualmente */
.blk { position: absolute; opacity: 0; z-index: 2; }

El modelo anterior, cada .scene de pantalla completa tenía su propio fondo y se deslizaba como un bloque, lo que daba sensación de PowerPoint y puntos de corte. El nuevo modelo solo tiene una capa de fondo fija, el contenido se divide en componentes .blk y las transiciones ocurren a nivel de componente (ver Paso 6).


Paso 3 — Especificaciones de elementos fijos (no negociables)

Los siguientes tres elementos se mantienen consistentes en todas las escenas y no tienen animación de entrada ni salida:

ElementoPosiciónTamañoDescripción
Logotipo de DonutSuperior izquierda top:40px left:72px200×76pxCSS background, sin <img>
Agentic Trading for Every Market.Inferior izquierda bottom:48px left:72px27pxInstrument Serif italic, --pu2
getdonut.aiInferior derecha bottom:50px right:72px14pxOpen Sans, --t3
/* Logotipo — CSS background, sin 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;
}

/* Pie de página — directamente visible, sin animación */
.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;
}

Los elementos fijos pertenecen a la capa persistente, son visibles desde el fotograma 0 y no deben tener ninguna animación tl en todo el video. foot-tag es directamente visible; foot-url puede tener un ligero fundido de entrada único, pero no es obligatorio.


Paso 4 — Principios de diseño

Equilibrio izquierda-derecha, eliminar el espacio vacío central

  • Priorizar diseño de dos columnas: texto/datos a la izquierda, componentes TG/imágenes a la derecha.
  • Cuando hay una imagen de fondo de personaje a la derecha: posicionamiento absoluto que cubra completamente la derecha, con un degradado de superposición de izquierda a derecha.
.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%);
}
  • El área de texto izquierdo debe tener position: relative; z-index: 2 para asegurar que se superponga a la imagen de fondo.

Tamaños de fuente mínimos

Tomando como referencia el video de D0 Thorp Engine, no deben ser inferiores a:

NivelTamaño mínimoFuente
Título principal80pxInstrument Serif
Subtítulo de escena56pxInstrument Serif
Etiqueta Kick / Eyebrow18pxOpen Sans 700 uppercase
Cuerpo / Viñeta de característica22pxOpen Sans
Ancla de datos (stat-val)48pxInstrument Serif
Etiqueta de pie de página27pxInstrument Serif italic
Texto dentro de componente TG13px (mínimo aceptable)Open Sans

Paso 5 — Especificaciones de componentes TG

Avatar: Debe usar D0_AVATAR

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

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

No usar etiquetas <img> para evitar que HyperFrames detecte nodos multimedia duplicados (advertencia de lint). No usar degradados de respaldo; debe ser el archivo real de D0_AVATAR.

Estructura del Panel 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 del usuario</div>
    <div class="msg-bot">
      <div class="mav"></div>
      <div class="bbubble">contenido de respuesta de D0</div>
    </div>
  </div>
</div>

Paso 6 — Reglas de transición (no negociables)

Principio central: el fondo no se mueve, los componentes se mueven. La "sensación de PowerPoint" proviene de que toda la escena (incluido el fondo) se deslice junta — el espectador pierde un punto de anclaje estable; los "puntos de corte" provienen de que las animaciones de salida y entrada estén conectadas extremo a extremo — hay un instante en el que todo está quieto. La solución para ambos es la misma frase: fondo fijo + componentes que entran y salen de forma entrelazada y superpuesta.

Transición predeterminada: entrada/salida escalonada a nivel de componente (element cross-stagger)

El fondo + elementos fijos (logotipo/pie de página/carril) no se mueven en todo el video. Cada cambio de beat solo hace que los componentes de contenido se muevan:

  • Los componentes del beat anterior salen secuencialmente (stagger, ease .in, pequeño desplazamiento + fundido)
  • Los componentes del nuevo beat entran secuencialmente (stagger, ease .out)
  • Ambos se superponen en el tiempo ≈ 0.2–0.3s — los antiguos aún no han terminado de salir, los nuevos ya empiezan a entrar. Esta es la clave para eliminar los puntos de corte.
// Cambio de beat: componentes antiguos salen escalonadamente, nuevos entran escalonadamente, con superposición temporal (no extremo a extremo)
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 = superposición
}
// Uso: beat(['#b1-title','#b1-sub'], ['#b2-stat','#b2-tg'], 4.0);
  • El desplazamiento es pequeño (20–40px); la dirección puede ser uniforme (por ejemplo, todos hacia arriba) para crear una "corriente de aire de paso de página", pero el fondo nunca participa.
  • Cuando hay muchos componentes, el stagger mantiene la pantalla en movimiento continuo, evitando la sensación de "entran todos a la vez → se congelan juntos".

Cuándo usar transición de pantalla completa

Solo ocasionalmente en grandes secciones (como de una tarjeta de título de marca a una sección de datos), y solo se empuja la capa de contenido, no el fondo — envuelve los componentes de esa sección en un contenedor #grp y luego lo empujas:

// Push-slide (solo empuja el contenedor de contenido, el fondo .bg no se mueve)
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 (transición emocional, generalmente para la última transición)
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);

❌ Prohibido: Deslizar toda la escena (incluido el fondo), escalar esquinas, zoom de pantalla completa, transiciones de salida/entrada conectadas extremo a extremo sin superposición.


Paso 7 — Reglas de animación GSAP

Obligatorio

const tl = gsap.timeline({ paused: true });
// ... tweens ...
window.__timelines['main'] = tl;
  • Usa tl.fromTo() en lugar de tl.from() (para garantizar la determinación de la búsqueda en HyperFrames)
  • Para animaciones repetitivas, usa Math.floor(duration / cycle) - 1, está prohibido repeat: -1
  • Si hay múltiples grupos de animación en el mismo elemento, añade overwrite: 'auto'
  • Usa ease .out para la entrada y ease .in para la salida

Priorizar el diseño, luego la animación

Primero escribe el estado final del elemento (posicionamiento CSS), luego usa fromTo para describir la trayectoria de entrada:

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

Sin animación en la capa persistente

.bg, .rail, .logo, .foot-tag, .foot-url están fijos en todo el video; la animación ocurre solo en los componentes .blk. Una vez que el fondo participa en el movimiento, se regresa inmediatamente a la sensación de PowerPoint — las transiciones solo mueven la capa de contenido (ver beat() en el Paso 6).


Paso 8 — Lint y vista previa

npx hyperframes lint     # Debe tener 0 errores
npx hyperframes preview  # http://localhost:300x, recarga en caliente
Advertencia comúnManejo
overlapping_gsap_tweensAñadir overwrite:'auto'
duplicate_media_discovery_riskReemplazar <img> por CSS background:url()
composition_file_too_largeIgnorar si el archivo único tiene <500 líneas

Dependencias y fuentes de activos

  • Skill d0-brand: autoridad definitiva para fuentes, tamaños y principios de marca; debe estar instalado junto con este Skill.
  • CLI de HyperFrames: se obtiene bajo demanda mediante npx hyperframes@latest.
  • GSAP: el ejemplo usa la versión fija 3.14.2 de CDN; si se actualiza la versión, primero se deben volver a ejecutar las validaciones de lint y seek.
  • assets/fonts/: Instrument Serif y Open Sans; los archivos de licencia se encuentran en los directorios de fuentes correspondientes.
  • assets/brand/: Logotipo de D0 y avatar de D0, solo para uso de miembros autorizados del equipo de Donut para contenido de la marca D0.

Individual skills in this repo

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

Skills relacionados