Communitygithub.com

MattiaIppoliti/tia-skills

El contrato de composición para construir un proyecto Remotion renderizable. Úsalo para la estructura del proyecto, registro de `<Composition>`, temporización de `<Sequence>`, orden de capas/pistas, componentes de escena, props y esquemas, reproducción de medios propia del framework, reglas de render determinista y validación. También cubre proyectos Tailwind y los formatos de plan STORYBOARD.md / SCRIPT.md. Léelo antes de escribir código de composición.

¿Qué es tia-skills?

Este skill define el contrato técnico fundamental para construir un proyecto de video renderizable con Remotion, el framework de salida de HyperFrames. Establece que una composición es un árbol de componentes React registrados con `<Composition>`, donde el fotograma actual (`useCurrentFrame()`) es el único reloj y la reproducción de medios debe realizarse exclusivamente a través de los componentes `<Video>` y `<Audio>` de Remotion, no del DOM nativo. El skill detalla la estructura de proyecto recomendada (package.json, src/index.ts, Root.tsx con cada `<Composition>`, y carpetas por composición con escenas, schema y props), la temporización basada en `<Sequence>` y `<Series>` para evitar el cálculo manual de offsets, el orden de capas mediante hermanos dentro de `<AbsoluteFill>`, y el uso obligatorio de esquemas Zod para tipar props y generar controles en Studio. Además, impone reglas no negociables de render determinista: prohibición de reloj de pared, aleatoriedad sin semilla, animaciones basadas en estado, CSS animations y requestAnimationFrame. Exige el uso de `delayRender` para trabajo asíncrono y el clamp de interpolaciones. El skill referencia documentos auxiliares para temas específicos como edición, medios, migración desde el contrato HTML heredado, integración con Tailwind v4 y formatos de plan (STORYBOARD.md, SCRIPT.md, BRIEF.md). Es compatible con Claude Code, Cursor y Codex, y proporciona una lista de verificación de validación con comandos CLI para TypeScript, stills, Studio y render final.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MattiaIppoliti/tia-skills/tree/HEAD/skills/video/hyperframes-core

Preguntar en tu IA favorita

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

Documentación

HyperFrames Core

El framework de salida es Remotion. Una composición es un árbol de componentes React registrado con <Composition>; el fotograma actual es el único reloj; la reproducción de medios pertenece a los componentes <Video> / <Audio> de Remotion, no al DOM.

Este skill es el contrato técnico: cómo construir un proyecto. El cuerpo a continuación es la guía de construcción; los detalles por tema viven en references/, léelos bajo demanda. Otras preocupaciones viven en los skills de dominio hermanos: hyperframes-animation, hyperframes-creative, media-use, hyperframes-cli, hyperframes-registry. El mapa de capacidades en /hyperframes dice lo que cubre cada uno.

Nota de migración. Este contrato reemplazó un contrato HTML más data-* más línea de tiempo GSAP pausada. Si encuentras un proyecto cuyo index.html lleva data-composition-id / data-start / data-duration, o un archivo de referencia que describe window.__timelines, estás viendo el contrato antiguo. Lee references/legacy-html-contract.md antes de modificarlo.

Referencias

ArchivoLéelo para…
references/minimal-composition.mdempezar desde el esqueleto de proyecto renderizable más pequeño
references/project-structure.mddiseñar src/, dividir escenas en componentes, decidir monolítico vs modular
references/timing.mdconvertir segundos a fotogramas, colocar un <Sequence>, usar <Series> / <TransitionSeries>, temporizar una escena relativa a otra
references/layers-and-order.mdapilar capas, controlar el orden z, superponer dos escenas en el mismo intervalo
references/props-and-schemas.mddeclarar props, escribir el esquema Zod, conectar defaultProps y calculateMetadata
references/media.mdcolocar <Video> / <OffthreadVideo> / <Audio> / <Img>, recortar, establecer volumen, usar staticFile
references/determinism-rules.mdmantener el render reproducible y buscable; las prohibiciones; carga asíncrona de assets mediante delayRender
references/editing-recipes.mdrecetas de corte / recorte / reordenamiento / retemporización / congelación / cámara / máscara / encadenado / crossfade / audio y sus límites
references/legacy-html-contract.mdreconocer y migrar un proyecto que aún usa el antiguo contrato HTML + data-*
references/tailwind.mdtrabajar en un proyecto con Tailwind v4
references/storyboard-format.mdredactar un plan STORYBOARD.md (+ el manifiesto analizado)
references/review-loop.mdejecutar las pasadas de revisión planificar → bosquejar → construir en un tablero en vivo
references/production-loop.mdllevar un plan aprobado a un video entregado
references/brief-contract.mdlas reglas base del brief: derivación de modo, registro de campos compartidos, invariantes de preguntas
references/brief-format.mdredactar BRIEF.md
references/script-format.mdredactar el opcional SCRIPT.md de narración fijada
references/subagent-dispatch.mdmapear verbos de despacho de subagentes a tu harness
references/frame-worker-core.mdel contrato compartido del rol frame-worker

Para detalles de animación (configuraciones de resorte, easing, adaptadores de tiempo de ejecución) ve a hyperframes-animation.

Construyendo una composición

La forma de un proyecto

package.json          # remotion, react, react-dom; scripts para studio/render
remotion.config.ts    # configuración de render (codec, formato de imagen, anulaciones de Tailwind/webpack)
tsconfig.json
public/               # todo contra lo que resuelve staticFile()
src/
  index.ts            # registerRoot(Root)
  Root.tsx            # cada <Composition> vive aquí
  <Nombre>/
    index.tsx         # el componente principal de la composición
    scenes/*.tsx      # un componente por escena
    schema.ts         # esquema Zod + tipo de props inferido

src/index.ts es el punto de entrada y hace exactamente una cosa:

import { registerRoot } from "remotion";
import { Root } from "./Root";

registerRoot(Root);

Registrar la composición

Cada cosa renderizable es un <Composition> en Root.tsx. El id es lo que el CLI renderiza por nombre.

import { Composition } from "remotion";
import { LaunchVideo } from "./LaunchVideo";
import { launchSchema } from "./LaunchVideo/schema";

const FPS = 30;

export const Root: React.FC = () => (
  <>
    <Composition
      id="launch"
      component={LaunchVideo}
      durationInFrames={45 * FPS}
      fps={FPS}
      width={1920}
      height={1080}
      schema={launchSchema}
      defaultProps={{ productName: "Acme", accent: "#5B8CFF" }}
    />
  </>
);

durationInFrames es la longitud del render. Son fotogramas, no segundos, y equivocarse es el error de autoría más común. Derívalo de una constante FPS con nombre en lugar de escribir 1350.

El fotograma es el único reloj

Cada valor animado es una función pura de useCurrentFrame(). Este es el contrato que hace que un render sea buscable: el renderizador salta al fotograma 812 en frío y debe obtener los mismos píxeles que obtendría reproduciendo de principio a fin.

import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate, spring } from "remotion";

export const Title: React.FC<{ text: string }> = ({ text }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  const enter = spring({ frame, fps, config: { damping: 18 } });
  const y = interpolate(enter, [0, 1], [40, 0]);

  return (
    <AbsoluteFill style={{ justifyContent: "center", alignItems: "center" }}>
      <h1 style={{ opacity: enter, transform: `translateY(${y}px)` }}>{text}</h1>
    </AbsoluteFill>
  );
};

Siempre sujeta un interpolate que mapea un rango de fotogramas, o el valor seguirá extrapolando más allá del rango y un fundido de entrada se convertirá en opacidad 4:

const opacity = interpolate(frame, [0, 15], [0, 1], {
  extrapolateLeft: "clamp",
  extrapolateRight: "clamp",
});

La temporización es <Sequence>

<Sequence> desplaza el tiempo de sus hijos: dentro de él, useCurrentFrame() devuelve 0 al inicio de la propia secuencia. Ese reajuste local es el punto clave, porque un componente de escena nunca necesita saber dónde se encuentra en la línea de tiempo maestra.

<AbsoluteFill>
  <Sequence durationInFrames={90}>
    <Hook />
  </Sequence>
  <Sequence from={90} durationInFrames={150}>
    <Feature />
  </Sequence>
  <Sequence from={240} durationInFrames={120}>
    <Close />
  </Sequence>
</AbsoluteFill>

Para una serie de escenas consecutivas, <Series> calcula los desplazamientos para que un cambio de duración no genere una cascada de correcciones manuales en cada from posterior:

<Series>
  <Series.Sequence durationInFrames={90}><Hook /></Series.Sequence>
  <Series.Sequence durationInFrames={150}><Feature /></Series.Sequence>
  <Series.Sequence durationInFrames={120}><Close /></Series.Sequence>
</Series>

<Series.Sequence offset={-15}> adelanta una escena para superponerla a su predecesora, que es como se consigue un intervalo de crossfade sin aritmética. Detalle completo, más <TransitionSeries> para transiciones basadas en presentación, en references/timing.md.

Las capas reemplazan a las pistas

No hay índice de pista. El apilamiento es el orden del DOM dentro de un <AbsoluteFill>: los hermanos posteriores pintan encima. Una pista de voz en off, una base musical y tres escenas visuales son cinco hermanos.

<AbsoluteFill>
  <Audio src={staticFile("musica.mp3")} volume={0.18} />
  <Audio src={staticFile("vo.mp3")} />
  <Sequence durationInFrames={90}><Hook /></Sequence>
  <Sequence from={90}><Feature /></Sequence>
  <Overlay />                {/* pinta encima de todo lo anterior */}
</AbsoluteFill>

<Sequence layout="none"> elimina el envoltorio implícito <AbsoluteFill>. Úsalo cuando el hijo deba participar en el diseño flex o grid del padre en lugar de estar posicionado absolutamente.

Los medios pertenecen a Remotion

Nunca uses una etiqueta <video>, <audio> o <img> nativa. Los componentes de Remotion son lo que permite al renderizador buscar y extraer fotogramas de manera determinista.

NecesidadUsa
Video en el render<OffthreadVideo src> (preferido)
Video que necesita control a nivel DOM<Video src>
Audio<Audio src volume trimBefore trimAfter>
Imagen estática<Img src>
Página embebida<IFrame src>
Cualquier archivo en public/staticFile("dir/nombre.ext")

<OffthreadVideo> extrae fotogramas con FFmpeg fuera del navegador, lo que es más rápido y preciso para el render; recurre a <Video> solo cuando necesitas el elemento real (por ejemplo, para conducir algo desde su currentTime). staticFile() es obligatorio para assets locales. Una cadena desnuda "/musica.mp3" funciona en Studio y luego falla en un render Lambda. Recorte, rampas de volumen y velocidad de reproducción están en references/media.md.

Props y esquema

Las entradas de la composición son props de React, tipadas por un esquema Zod para que Studio renderice controles editables y una carga útil --props incorrecta falle estrepitosamente en lugar de renderizar mal.

import { z } from "zod";
import { zColor } from "@remotion/zod-types";

export const launchSchema = z.object({
  productName: z.string(),
  accent: zColor(),
  features: z.array(z.object({ title: z.string(), body: z.string() })),
});

export type LaunchProps = z.infer<typeof launchSchema>;

Cuando la duración depende de las props (una lista de características de longitud desconocida, un archivo de audio de longitud desconocida), calcúlala en calculateMetadata en lugar de codificar una estimación. Ve a references/props-and-schemas.md.

Reglas no negociables

Errores silenciosos que una verificación de tipos no detectará. Justificación completa en references/determinism-rules.md.

  • Sin reloj de pared. Sin Date.now(), sin new Date(), sin performance.now(). El tiempo viene de useCurrentFrame().
  • Sin aleatoriedad sin semilla. Math.random() da un valor diferente por fotograma, lo que produce parpadeo. Usa random(seed) de Remotion: misma semilla, mismo valor, cada fotograma y cada render.
  • Sin animación basada en estado. useState / useReducer / useEffect no debe impulsar nada visual. El renderizador monta fotogramas fuera de orden y en workers paralelos; el estado acumulado al reproducir hacia adelante no existe. Deriva del frame en su lugar.
  • Sin animaciones CSS, transiciones ni requestAnimationFrame. Se ejecutan en el propio reloj del navegador, que el renderizador no avanza. Cada una renderiza como un primer fotograma congelado.
  • Espera el trabajo asíncrono con delayRender. Una fetch, una fuente, un diseño medido: llama a delayRender() antes y a continueRender(handle) después, o el fotograma se captura antes de que el trabajo llegue.
  • Sujeta tus interpolaciones. interpolate sin sujeción extrapola fuera del rango de entrada.
  • Posicionamiento absoluto para cualquier cosa animada. Un elemento transformado dentro del flujo normal arrastra a sus hermanos a medida que se mueve.

Editando composiciones existentes

  • Lee los archivos primero. Conserva la temporización, props, ids y rutas de assets no relacionados.
  • Coincide con el id del <Composition> existente. El CLI, cualquier script de render y CI abordan las composiciones por él. Renombrar uno es un cambio radical.
  • Agregar una escena: prefiere <Series> para que los desplazamientos se recalculen. En una lista de <Sequence> con desplazamiento manual, corrige cada from posterior.
  • Cambiar una duración: verifica también durationInFrames en el <Composition>. Una escena que se extiende más allá de la longitud de la composición se trunca silenciosamente.
  • Agregar un componente: mantenlo como una función pura de props y frame.

Validación

El detalle de los comandos está en hyperframes-cli.

  • npx tsc --noEmit, para que el esquema y los tipos de props realmente coincidan
  • npx remotion still <id> out/probe.png --frame <n> en algunos puntos intermedios de escena, y mira cada uno
  • npx remotion studio para revisión, para que el usuario pueda desplazarse y ajustar props por sí mismo
  • npx remotion render <id> solo después de que el usuario lo apruebe

Individual skills in this repo

This repo contains 6 individual skills — each has its own dedicated page.

MattiaIppoliti/tia-skills

The technique catalog: five velocity-matched SEAMS (zoom-through, INVERSE zoom-through, cut-the-curve, waterfall cut, rack-focus blur-cut) plus the two in-scene techniques — waterfall ENTRY (staggered arrival cascades for title cards / segment openers) and the nudge curve (slow-fast-slow three-phase group slides). Covers partial-travel (~12% of frame) velocity matching via mirrored power4 eases, the Z scale-sign rule, size-scaled blur (10px text / 18-20px full-frame), word-by-word staggered cuts, cascade pacing by element weight, and the 10/65/25 slide ratio. Read before authoring any transition, text-beat handoff, kinetic text entry, or group reposition. [depth, zoom, inverse-zoom, scale-sign, mirrored-zoom, rack-focus, pacing, velocity, cut-the-curve, waterfall, stagger, cascade, kinetic-text, title-card, segment-opener, nudge, slide, easing, group-motion, z-depth, motion-graphics, cinematic, transition, blur, directional-continuity]

MattiaIppoliti/tia-skills

Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.

MattiaIppoliti/tia-skills

Author or edit a custom HyperFrames composition when no specialized workflow fits, or when BRIEF.md sets flow: companion. Use for longer or multi-scene pieces, brand and sizzle reels, montages, static loops, static title cards, footage remixes, and freeform builds. Use motion-graphics instead for a short unnarrated motion-first unit, including an animated title. Route fresh creation through hyperframes before using this skill.

MattiaIppoliti/tia-skills

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.

MattiaIppoliti/tia-skills

Use when audio already placed in a HyperFrames composition needs to be mixed: fade-in/fade-out, crossfade, track gain or volume, volume automation, ducking, a music bed that fights a voiceover (voiceover carve), effects on a track (EQ, compressor, limiter, gate, saturation, delay, reverb, chorus, phaser, bitcrush), or automation envelopes drawn on a track's volume or any effect parameter. Don't use for sourcing or generating audio — finding BGM, SFX, or making a voiceover is `/media-use`. Don't use for clip timing or track layout, which is `/hyperframes-core`.

MattiaIppoliti/tia-skills

Drive the Remotion CLI development loop: scaffold, studio, type-check, compositions, still probes, single and batch render, bundle, Lambda and Cloud Run rendering, benchmark, versions, upgrade, and GPU checks. Also use when diagnosing a build or render failure, or when looking for a capability the retired HyperFrames CLI used to own.

Skills relacionados