Communitygithub.com

YahyaLendani/motionbrief

Crea gráficos en movimiento y videos cortos a partir de HTML o React: tarjetas de título, intros de logo, tipografía cinética, contadores, revelaciones de estadísticas, tercios inferiores, superposiciones transparentes y montajes de características. Compila una solicitud en lenguaje natural en un brief validado y luego lo renderiza; procesa un solo brief en múltiples videos.

¿Qué es motionbrief?

Esta skill transforma descripciones en lenguaje natural en videos animados profesionales, ya sea usando HyperFrames (HTML + GSAP, licencia Apache 2.0) o Remotion (React + TypeScript). El flujo de trabajo comienza con la compilación de un `brief.json` que define duración, tamaño, fotogramas por segundo (fps), ritmos (beats), transiciones y paleta de colores, asegurando que no haya valores indefinidos. Luego, elige automáticamente la vía técnica más adecuada (HyperFrames para equipos grandes o prototipos rápidos, Remotion para proyectos React complejos), genera el código a partir de plantillas preconstruidas y lo valida con un verificador de contrato que detecta fallos silenciosos —como una línea de tiempo no registrada— antes de renderizar. Finalmente, revisa los fotogramas para verificar que los cortes no sean negros, que el texto sea legible en móviles y que las transiciones sean suaves, y soporta la exportación por lotes de múltiples variaciones desde un solo brief. Es útil para cualquier desarrollador que necesite producir rápidamente gráficos en movimiento o videos cortos para lanzamientos, demostraciones o contenido de marketing.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YahyaLendani/motionbrief-claude-skills/tree/main/skills/motionbrief

Preguntar en tu IA favorita

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

Documentación

Gráficos en movimiento

Genera un video escribiendo una página web que el renderizador recorre fotograma a fotograma. Ambas vías hacen lo mismo; la diferencia es lo que escribes.

  • HyperFrames — un archivo HTML, CSS para el aspecto, una línea de tiempo de GSAP en pausa para el movimiento. node scripts/hf.mjs ejecuta la versión anclada y la instala una vez desde un archivo de bloqueo comprometido. Apache 2.0.
  • Remotion — componentes de React. useCurrentFrame() devuelve el fotograma, tú haces los cálculos. Maduro, tipado y con licencia gratuita solo para hasta tres personas.

Carga la referencia correspondiente antes de escribir el código de composición. Las reglas del framework no se pueden adivinar y la mayoría de los fallos son silenciosos: un archivo de HyperFrames que nunca registra su línea de tiempo renderiza un fotograma estático sin error.


El camino fácil

El usuario describe lo que quiere en cualquier palabra. Nunca escribe un brief, una especificación o una hoja de ritmos — Claude compila uno.

/motion un logo sting de 6 segundos contundente para Inkwell

Esa es toda la entrada. Por debajo:

  1. Compila la solicitud en brief.json — duración, tamaño, fps, ritmos con tiempos, texto textual, suavizado, paleta y una lista de supposiciones. Cada vacío recibe un valor predeterminado de la tabla en references/brief.md; nada queda sin definir y nada se cuestiona.
  2. Muestra el resumen compacto (una tabla, ~12 líneas) y construye en el mismo turno. Sin compuerta de aprobación.
  3. Construye a partir de la plantilla, valida, renderiza, observa los fotogramas.

La iteración es entonces una edición de campo, no una reconstrucción. "Hazlo más contundente" cambia feel.ease y dos duraciones; el código no se mueve a menos que cambien kind o motion.

El brief es el artefacto que hace que esto sea económico. Vive en el disco junto a la composición, por lo que una revisión es un diff, y re-renderizar es un solo comando.


Enrutar primero

SeñalVía
Compilación nueva, sin framework nombradoHyperFrames
HTML/CSS/GSAP/Lottie existente para reutilizarHyperFrames
Sin node_modules, sin paso de compilación deseadoHyperFrames
Equipo de más de tres personasHyperFrames (licencia)
El usuario nombra Remotion, o el repositorio es React/TSRemotion
Necesita un sistema de diseño, biblioteca de gráficos o componentes complejosRemotion
Portar un proyecto Remotion existenteRemotion (portar cuesta más de lo que ahorra)

Cuando el usuario nombra ambos, construye en HyperFrames y di en una línea que el puerto de Remotion está disponible a petición. Dos compilaciones completas de la misma pieza son trabajo desperdiciado a menos que se haya solicitado una comparación.


El bucle

1. Compila el brief

Convierte la solicitud en brief.json antes de escribir código. El esquema, la gramática kind/motion, la tabla de valores predeterminados y las palancas de iteración viven en references/brief.md.

node scripts/brief.mjs brief.json          # validar + tabla de resumen
node scripts/brief.mjs brief.json --json   # resultado de máquina

Imprime el resumen al usuario, corrige cualquier ERROR, luego continúa en el mismo turno. Las advertencias son juicios — una advertencia que aceptas va en supposiciones.

El brief también lleva el tempo. Elige audio.bpm para que la cuadrícula de ritmos divida los cortes — a bpm, un ritmo es 60 / bpm segundos y cada beats[].start debería caer en uno. 120 BPM da un ritmo cada 0.5 s y se adapta a la mayoría de las piezas cortas. Si brief.mjs informa off_beat_grid, mueve el corte o cambia el tempo; no lo ignores, porque esa es la diferencia entre una pieza que encaja y una que se siente sutilmente incorrecta.

Hecho cuando brief.mjs sale con 0, cada ritmo tiene una ventana de tiempo, un tipo, un movimiento y texto textual, y ningún corte está fuera de la cuadrícula de ritmos.

2. Andamiaje

Comienza desde las plantillas en esta skill en lugar de un archivo vacío — son correctas para ambos contratos y ahorran los dos pasos propensos a fallos (registro de línea de tiempo, temporización de secuencia).

# HyperFrames — HTML plano. El motor anclado se instala una vez, lo que necesita red
cp -R assets/hyperframes/. ./my-video/
node scripts/hf.mjs lint ./my-video

# Remotion — proyecto React, necesita sus dependencias ancladas una vez
cp -R assets/remotion/. ./my-video/
cd my-video && npm ci
# PowerShell
Copy-Item -Recurse -Force assets\hyperframes\* .\my-video\
Copy-Item -Recurse -Force assets\remotion\* .\my-video\

Hecho cuando node scripts/hf.mjs lint pasa, o npx remotion compositions src/index.tsx lista el id de composición.

3. Construye los ritmos

Un archivo por ritmo. Mantén la línea de tiempo plana — tiempos absolutos en HyperFrames, fotogramas <Sequence> en Remotion. Actualiza la hoja de ritmos cuando la compilación cambie la temporización, luego vuelve a verificar la duración total.

Nombra cada escena según su ritmo, porque así es como las comprobaciones lo encuentran: data-brief-beat="<id>" en el host de HyperFrames, <Sequence name="<id>"> en Remotion. Si una secuencia de Remotion calcula su temporización, también pon data-brief-beat="<id>" en un elemento dentro de ella, para que la temporización se pueda medir.

Hecho cuando cada ritmo en la hoja existe en el código, la duración de la composición coincide con la hoja, y no hay TODOs, stubs o texto de marcador de posición.

4. Verifica el movimiento

Los fotogramas estáticos mienten sobre la temporización. Observa los fotogramas, luego observa el renderizado.

node scripts/check-contract.mjs --dir ./my-video --preflight   # estático, sin instalación
node scripts/check-contract.mjs --dir ./my-video --runtime     # también lo inspecciona en un navegador

node scripts/hf.mjs check ./my-video                # diseño, movimiento, contraste
node scripts/hf.mjs snapshot ./my-video --review    # fotogramas de ritmo + costuras como PNGs
node scripts/hf.mjs keyframes ./my-video --selector "#card" --shot motion.png

npx remotion still src/index.tsx LaunchCard out/f.png --frame=45
npx remotion studio src/index.tsx              # míralo a 1x

check-contract.mjs captura los fallos silenciosos sin instalar nada: una línea de tiempo no registrada, una clave window.__timelines que no coincide, una línea de tiempo no en pausa, una duración faltante, Math.random() en una composición, un interpolate sin ajustar. Es una verificación previa, no un reemplazo de los linters reales.

Cuando brief.json está en el proyecto (o --brief apunta a uno), también compara la compilación con el brief. Cada requisito termina verified, failed o unverified. unverified no es un aprobado, y bloquea el renderizado.

CódigoEstadoSignifica
brief_format_mismatchfallidoAncho, alto, fps o duración difieren de format
brief_scene_count, brief_scene_unmappedfallidoUn ritmo no tiene escena que declare su id, o una escena no tiene ritmo. La posición no es identidad
brief_timing_mismatchfallidoUna escena no comienza o dura lo que dice el brief, dentro de un fotograma
brief_copy_missingfallidoLa línea no está en la escena. Comentarios y variables no utilizadas no cuentan
brief_copy_wrong_scenefallidoLa línea solo está en otra escena
copy_not_visiblefallidoTiempo de ejecución: en el DOM pero oculto, transparente, fuera de pantalla, recortado, difuminado o cubierto
copy_hold_shortfallidoTiempo de ejecución: legible por menos de beats[].hold
first_frame_emptyfallidoTiempo de ejecución: visibleAtStart está establecido y nada del ritmo está pintado
first_frame_unverifiedno verificadoTiempo de ejecución: solo un gráfico está en el primer fotograma, o el ritmo no tiene texto. Mira el fotograma
brief_timing_unverified, brief_format_unverifiedno verificadoLa fuente lo calcula. El tiempo de ejecución puede resolverlo
brief_copy_dynamic, brief_copy_unverifiedno verificadoSi se muestra es una cuestión de tiempo de ejecución. El texto de Remotion siempre es esto hasta el tiempo de ejecución

La coincidencia ignora mayúsculas/minúsculas y espacios en blanco y pliega comillas curvas. Otra puntuación es significativa, y "12,480" coincide con un contador que se estabiliza en 12480. Cuando los requisitos permanecen no verificados, di cuáles, e intenta hacerlos medibles antes de aceptarlos. Aceptar uno significa nombrarlo, con --allow-unverified "beat.lines.copy[0].visible", e informarlo al usuario. Nunca aceptes un patrón general, y los fallos no se pueden aceptar en absoluto. Lee references/validation.md para las reglas y límites exactos.

Corrige la desviación en el código, o cambia el brief a propósito y vuelve a ejecutar brief.mjs — nunca dejes que los dos estén en desacuerdo.

Revisa los fotogramas — todas las comprobaciones pueden pasar en una película rota

Un contrato que pasa dice que la temporización y el texto coinciden, y que el texto es legible. No dice nada sobre la paleta, la suavización, las transiciones, o si la película funciona. Las comprobaciones de lint, diseño, movimiento, contraste y artesanía pasaron en la propia plantilla de esta skill mientras se cortaba a negro en cada ritmo y salía de su contador en el instante en que el número aterrizaba. Solo mirar los fotogramas lo capturó. Captúralos:

# HyperFrames: fotogramas de ritmo, una tira de 5 fotogramas alrededor de cada corte, y una hoja de teléfono
node scripts/motion-render.mjs --brief ./my-video/brief.json --snapshot --no-render

# Remotion: para cada corte c (en fotogramas), toma c-6, c y c+6, más el centro de cada ritmo
# (la plantilla corta en 75, 210 y 270)
node scripts/motion-render.mjs --dir ./my-video --no-render \
  --stills 37,69,75,81,142,204,210,216,240,264,270,276,315

Luego lee las imágenes y responde cada pregunta. Corrige el código, vuelve a capturar, mira de nuevo:

  • ¿El corte es negro? Más de un fotograma vacío alrededor de un corte significa que la salida termina temprano y el siguiente ritmo aparece desde la nada. Mueve la salida para que termine en el corte (start = duración del ritmo − duración de la salida).
  • ¿La recompensa se mantiene? El número final de un contador, o la última palabra de una línea, permanece quieto en pantalla durante al menos un ritmo (60 / bpm s) antes de desaparecer. Salir en el momento en que aterriza significa que nunca se lee.
  • ¿Se lee en un teléfono? Verifica review-phone.jpg, o imagina el fotograma a 360 px de ancho. A 1080p, las etiquetas y lemas por debajo de ~40 px generalmente fallan.
  • ¿Es la fuente del brief? Una fuente de respaldo como Segoe UI o Arial significa que la fuente nunca se cargó, y otra máquina renderizará una película diferente. --runtime advierte con font_fallback, y el informe registra las fuentes realmente dibujadas. Remotion necesita @fontsource/* (la elección de la plantilla) o @remotion/fonts para un archivo local.
  • ¿Es la transición del brief? feel.transition está en los fotogramas alrededor de cada corte, no un descenso a negro.

Hecho cuando has leído los fotogramas de los ritmos y cada tira de costura, has respondido cada pregunta anterior, y cada línea de la lista de verificación bajo "Lista de verificación de envío" se cumple.

5. Renderiza

node scripts/motion-render.mjs --brief ./my-video/brief.json
node scripts/motion-render.mjs --brief ./my-video/brief.json --batch rows.json --no-audio

El envoltorio lee la vía, formato, fps y slug del brief, y se detiene antes de que se gaste cualquier tiempo de renderizado si el brief, las comprobaciones estáticas, las herramientas, los activos o la comprobación de tiempo de ejecución lo dicen. Sale con 1 en un fallo y 3 en requisitos no verificados. --no-checks omite la validación y lo registra en el informe. Luego hace lint, renderiza, mide el archivo con ffprobe, y escribe <out>.report.json.

Cuando audio.policy es generated, en cualquier vía, sintetiza la cama con music.mjs, renderiza el video solo con imagen, y multiplexa los dos con una sola llamada ffmpeg — para que la composición nunca dependa del mezclador de audio de un motor. Luego mide que el archivo tenga un flujo de audio y que no esté en silencio.

Para transparencia: --format webm o --format mov — H.264 no puede llevar alfa. --no-audio omite la cama y da un archivo sin flujo de audio. GIF no puede llevar audio, por lo que un brief con una cama es rechazado para GIF a menos que pases --no-audio.

Con --batch, un brief más un archivo de filas se convierte en N videos: HyperFrames renderiza filas de forma nativa, Remotion obtiene un archivo de props por fila. El lote es solo video, y un brief con una cama es rechazado a menos que pases --no-audio.

Hecho cuando el archivo existe, el informe dice rendered, su lista notVerified está vacía o le has dicho al usuario lo que hay en ella, y su primer y último fotogramas son intencionales.


El contrato que se rompe silenciosamente

HyperFrames — cuatro cosas, todas obligatorias:

  1. La raíz lleva data-composition-id, data-width, data-height, data-duration, data-start="0".
  2. Cada elemento temporizado lleva id + data-start + data-duration.
  3. La línea de tiempo de GSAP se construye con { paused: true }.
  4. window.__timelines[<data-composition-id>] = tl — misma clave. Después de que se agreguen los tweens. Omite esto y obtienes un fotograma estático, sin error.

Remotion — tres:

  1. registerRoot() en el archivo de entrada, <Composition> en el componente raíz.
  2. interpolate(..., { extrapolateLeft: "clamp", extrapolateRight: "clamp" }) — ajusta ambos extremos, cada vez.
  3. Sin Math.random(), sin Date.now() en una composición. Usa random(seed).

Las cuatro reglas que deciden si se ve barato

Estas son las que fallan más a menudo. Conjunto completo con código en references/motion-craft.md.

  1. Mueve solo lo que está vivo. Las cosas establecidas se mantienen quietas. Una escala "respirante" inactiva se lee como generada por máquina.
  2. Superpón, no hagas cola. Escalonar ≈ 15–30% de la duración del propio elemento. La siguiente cosa comienza mientras la última aún se está estabilizando.
  3. Sin rebote en el tipo. El sobrepaso es para objetos con masa — tarjetas, solapas, personajes. El texto, los números y las etiquetas de interfaz usan power3.out / expo.out y nunca sobrepasan.
  4. Una idea por movimiento. y + opacity es "llegando". Añade rotación y escala y la palabra es ilegible en pleno vuelo.

También: una transición es la salida, no un desvanecimiento seguido de una aparición. Eso se renderiza como un corte brusco con un descenso en el medio.


Lista de verificación de envío

  • brief.json valida: los tiempos encajan, el primer fotograma es intencional, la pausa final ≥ 2 s.
  • check-contract.mjs --runtime dice verified, o los ids no verificados son aceptados por nombre e informados al usuario.
  • Texto, números, identificadores y URLs están como se escribieron — sin lorem, sin marcador de posición.
  • Línea de tiempo registrada bajo el id de composición (HyperFrames), o composición listada por npx remotion compositions (Remotion).
  • Lint/check limpio.
  • <out>.report.json dice rendered, con el tamaño esperado, fps, duración y audio.
  • Fotogramas inspeccionados: cada ritmo, cada costura, ancho de teléfono — sin negro en un corte,

...

[truncado para traducción]

Skills relacionados