Mapa de la ruta
Contenido detallado
🗂️ Estructura del skill
Anatomía completa de la carpeta video-explicativo/: el SKILL.md en el centro, las tres referencias especializadas y los tres scripts que automatizan el trabajo pesado.
La raíz de la skill contiene SKILL.md (el orquestador), la subcarpeta scripts/ con 3 archivos ejecutables y la subcarpeta references/ con 3 archivos de especificación. Nada más.
Conocer el mapa de la carpeta es el primer paso para entender qué hace la skill, modificarla sin romper nada y crear nuevas skills con el mismo patrón.
Raíz = SKILL.md; especialización en subcarpetas; separación entre orquestador, referencia y scripts.
pipeline.md describe los 7 pasos del flujo de producción; house-style.md define la paleta, la tipografía y las reglas visuales; gotchas.md enumera los errores más comunes y sus correcciones específicas.
Saber qué referencia consultar para cada duda evita lecturas innecesarias: cada archivo tiene un alcance preciso y no se superpone con los demás.
Especialización por dominio; se cargan bajo demanda; sin redundancia entre archivos.
fetch-fonts.mjs descarga las fuentes .woff2 locales; narration-template.sh genera el guion TTS con voz pf_dora --speed 0.98; composition-template.mjs es el generador central que produce el index.html final con todas las escenas.
Cada script resuelve un problema específico de automatización; juntos, eliminan el trabajo manual repetitivo y garantizan que la salida sea determinista.
Automatización mediante script; fuentes locales; TTS; generación determinística de HTML.
El SKILL.md define 7 etapas numeradas: (1) confirmar el tema, (2) escribir el guion, (3) generar audio TTS, (4) descargar fuentes, (5) ejecutar el generador, (6) validar el output, (7) entregar los archivos. Cada paso señala la referencia correcta.
El flujo numerado es lo que Claude ejecuta en orden; entenderlo permite depurar en qué paso ocurrió un error.
Flujo numerado; responsabilidad por etapa; referencias indicadas en cada paso.
El SKILL.md indica a Claude que lea house-style.md solo antes de construir las escenas visuales, y gotchas.md solo antes de validar el output; nunca todo de una vez.
Conserva el contexto para la tarea real, en vez de gastar tokens cargando especificaciones que quizá no sean necesarias.
On demand; ahorro de contexto; lectura condicional.
El SKILL.md incorpora preferencias fijas del autor: narración en PT-BR, paleta dark premium ámbar, salida doble (16:9 para YouTube y 9:16 para Shorts) y CTA final siempre dirigido a INEMA.CLUB.
Estos valores predeterminados evitan que el usuario tenga que repetir sus preferencias en cada solicitud: están codificados en el skill para mantener la coherencia de marca.
Valores predeterminados de marca; PT-BR; salida doble; CTA coherente.
🎨 House style dark premium
La guía de estilo completa del video explicativo: fondo #0D1321, acento ámbar #FFC300, tipografía Sora/Inter/JetBrains Mono y las reglas que diferencian la escala de video de la escala web.
Seis variables fijas: fondo #0D1321, panel #1D2D44, borde #3E5C76, texto principal #F0EBD8, acento ámbar #FFC300 y resaltado de código #2EC4B6. No se permite ningún otro color de acento.
La paleta es la identidad visual del canal. Apartarse de ella rompe la coherencia de marca: el ámbar debe ser el único punto cálido en pantalla.
Sistema cerrado de colores; ámbar = único acento; código en cian.
Sora para títulos y titulares (gran impacto visual), Inter para el cuerpo del texto (alta legibilidad), JetBrains Mono para código y datos. Las tres familias cubren todos los casos de uso del video.
Mezclar fuentes fuera del sistema crea ruido visual. La regla es simple: título → Sora, texto → Inter, código → JetBrains.
Sora para títulos; Inter para el cuerpo; JetBrains para código; nunca Google Fonts CDN en tiempo de ejecución.
Cada escena tiene una capa de fondo compuesta por 4 elementos: (1) brillo radial ámbar (glow), (2) texto fantasma con baja opacidad (ghost text), (3) cuadrícula de puntos (grid) y (4) textura de grano SVG (grain). Esta capa nunca se anima; queda estática.
La capa crea profundidad sin distraer. Entender que es estática evita el error de intentar animarla (lo que causa conflictos con el framework).
Capa estática; 4 elementos; profundidad sin distracciones.
Las fuentes se descargan mediante el script fetch-fonts.mjs en formato .woff2 y referenciadas mediante @font-face local. La CDN de Google Fonts está prohibida porque el renderizador podría no tener acceso a internet.
Un video renderizado sin acceso al CDN mostrará fuentes de respaldo, lo que arruinará el aspecto visual. Las fuentes locales garantizan coherencia sin conexión.
woff2 local; @font-face; fetch-fonts.mjs; compatible sin conexión.
El video no es la web: cada escena debe tener como máximo 8-10 elementos visuales para no sobrecargar al espectador. Los titulares van de 64px (subtítulo) a 172px (énfasis máximo): tamaños imposibles en un sitio web, pero necesarios para leer en TV o móvil.
Los diseñadores que vienen de la web tienden a poner demasiada información en cada escena. La regla de 8-10 elementos es el antídoto.
Máximo 10 elementos; fuentes grandes; espacio visual; enfoque del espectador.
Todo video termina con la escena scene9() (CTA), que muestra el logo ámbar y la dirección INEMA.CLUB con el máximo protagonismo. Esta escena la genera automáticamente composition-template y no debe omitirse.
La CTA es el punto de conversión del canal. Incluida de forma predeterminada, garantiza que ningún video se entregue sin la llamada a la acción de marca.
scene9() automática; INEMA.CLUB; conversión de canal; nunca omitir.
⚙️ El generador build-index.mjs
El corazón técnico de la skill: el array AUDIO[] como única fuente de verdad que calcula el timing, ensambla las escenas, genera los captions, las pistas y la timeline GSAP sincronizada.
AUDIO[] es el único array que edita el autor: cada entrada tiene el archivo MP3 y la duración en segundos. A partir de ahí, el generador deriva todo: la temporización de las escenas, la duración de las transiciones, la posición de las pistas de audio en el HTML y las marcas de tiempo de la timeline GSAP.
Tener una única fuente elimina las desincronizaciones: no hay forma de que el audio y la timeline discrepen porque ambos leen el mismo dato.
Fuente única de verdad; array AUDIO[]; derivación automática.
El generador calcula el array S[] sumando LEAD=0.5s (silencio antes del audio), TAIL=0.9s (silencio después) y FADE=0.45s (superposición de entrada/salida). Para cada escena: start = soma das durações anteriores, dur = audio.dur + LEAD + TAIL, audioStart = LEAD.
Comprender el cálculo te permite ajustar los parámetros para videos con otro ritmo sin romper la sincronización.
LEAD 0.5s; TAIL 0.9s; FADE 0.45s; S[] derivado de AUDIO[].
Cada escena es una función sceneN(s) que devuelve la cadena HTML de la escena usando el objeto de timing s. Las animaciones se declaran con anim(element, props, delay), que acumula una lista de tweens GSAP, nunca CSS directo.
Separar la estructura visual (HTML) de la animación (GSAP vía anim()) facilita editar una sin tocar la otra.
sceneN() devuelve HTML; anim() declara tweens; separación entre estructura y movimiento.
El generador construye el HTML en 4 bloques: (1) .scene divs con el contenido visual, (2) .caption divs con subtítulos sincronizados, (3) <audio> pistas alternadas (escenas 1/3 en la pista A, 2/4 en la pista B), y (4) el bloque <script> con la timeline GSAP iniciada en pausa.
Conocer la estructura de los 4 bloques te permite editar el output manualmente cuando sea necesario sin perder la lógica de sincronización.
4 bloques; timeline en pausa; reproducción controlada por eventos de audio.
Ejecutando el generador con la flag --vertical, añade la clase .v a <body> y aplica overrides CSS que reposicionan elementos para el formato 9:16 (1080×1920px). El archivo generado siempre es index.html, sobrescribiendo la versión 16:9.
Comprender el mecanismo de override evita confusiones entre los dos formatos y explica por qué ambos comparten el mismo archivo base.
body.v; CSS overrides; --vertical flag; un archivo, dos formatos.
El composition-template define scene9() como la escena final de CTA codificada directamente. Siempre se inserta después de las escenas de contenido, independientemente de cuántas tenga el video; si el video tiene 7 escenas, la última siempre es la scene9 de CTA.
Saber que es automática evita duplicar la CTA manualmente, y saber que no se puede omitir garantiza la coherencia de marca en todo el resultado.
scene9() hard-coded; siempre al final; INEMA.CLUB; nunca duplicar.
🧯 Problemas frecuentes y correcciones
Los errores que aparecen cada vez y la corrección exacta para cada uno: desde qué elemento animar hasta los problemas de fuentes, los clips superpuestos y el determinismo del generador.
El framework de HyperFrames establece opacity:1 en todos los .clip durante la captura del frame — las animaciones de opacidad en ellos se ignoran. El objetivo correcto para el fade-in/out siempre es .scene-inner, el contenedor interno de la escena.
Este es el gotcha #1 más frecuente. El video parece correcto en el navegador, pero el render final muestra escenas parpadeantes o sin transición.
El objetivo correcto es .scene-inner; .clip está prohibido para opacity; el framework lo sobrescribe.
Las escenas impares (1, 3, 5…) usan el <audio> track A; las escenas pares (2, 4, 6…) usan el track B. Esto permite que un track termine de forma natural mientras el otro ya carga el siguiente audio, lo que elimina el problema de clips superpuestos donde dos audios se reproducen al mismo tiempo.
Si pones todos los audios en el mismo track, habrá superposición inevitable en las transiciones con FADE. El patrón alternado resuelve esto de forma estructural.
Track A = impares; Track B = pares; superposición eliminada; preload en el track inactivo.
Los elementos puramente decorativos colocados fuera del área visible (p. ej., brillos que se desbordan, textos fantasma con valores negativos) deben tener el atributo data-layout-ignore. Sin él, el motor de layout de Remotion los cuenta en el bounding box y puede recortar o desplazar la escena.
Los elementos decorativos fuera del canvas sin el atributo son la causa n.º 1 de composiciones con recortes inesperados en el render.
data-layout-ignore; fuera del lienzo; cuadro delimitador; elementos decorativos invisibles.
El gotchas.md prohíbe cualquier @import url(fonts.googleapis.com) en el HTML generado. La variable centinela google_fonts_import se usa en las plantillas para garantizar que el generador lance un error si detecta la cadena en el output, lo que fuerza siempre el uso de @font-face local.
El entorno de render no tiene acceso a Internet. Una importación externa provoca que falten fuentes, que el texto use una sans-serif de reemplazo y que el aspecto se rompa por completo.
Prohibido usar Google Fonts CDN; @font-face local; centinela google_fonts_import.
En Windows y en git-bash, ffmpeg intenta leer stdin interactivo incluso en llamadas no interactivas, lo que bloquea el proceso indefinidamente. La flag -nostdin desactiva este comportamiento. Todos los comandos ffmpeg en los scripts del skill la incluyen de forma predeterminada.
Si quitas la flag al adaptar un script, el proceso se bloqueará silenciosamente en Windows, sin mostrar ningún mensaje de error: será difícil de diagnosticar.
-nostdin; Windows/git-bash; stdin interactivo; proceso bloqueado.
El generador y las plantillas prohíben Date.now(), Math.random() y cualquier fetch() dentro del HTML renderizable. Remotion renderiza cada frame de forma independiente — el código no determinista produce frames inconsistentes y un video con parpadeos.
Es la causa más difícil de diagnosticar: el video parece correcto en la vista previa, pero tiembla en el render final. La regla sencilla: si el valor cambia entre ejecuciones, no pertenece a la plantilla.
Determinismo total; sin Date.now; sin Math.random; sin fetch en tiempo de ejecución; valores fijos.