Communitygithub.com

MattiaIppoliti/tia-skills

Le contrat de composition pour construire un projet Remotion rendable. À utiliser pour la structure du projet, l'enregistrement de `<Composition>`, le timing de `<Sequence>`, l'ordre des couches/pistes, les composants de scène, les props et schémas, la lecture des médias gérée par le framework, les règles de rendu déterministe et la validation. Couvre également les projets Tailwind et les formats de plan STORYBOARD.md / SCRIPT.md. À lire avant d'écrire du code de composition.

Qu'est-ce que tia-skills ?

Cette compétence constitue le contrat technique central pour la construction d'un projet Remotion rendable dans le cadre HyperFrames. Elle définit comment structurer un projet, enregistrer une composition avec `<Composition>`, utiliser `<Sequence>` et `<Series>` pour le timing des scènes, et gérer l'ordre des couches (z-order) dans un `<AbsoluteFill>`. Elle insiste sur le fait que la seule horloge disponible est `useCurrentFrame()`, interdisant les animations basées sur l'état, les horloges murales ou les animations CSS. La compétence détaille également les règles pour les props et schémas Zod, la gestion des médias avec `<OffthreadVideo>` / `<Audio>`, et les règles de déterminisme pour des rendus reproductibles (pas de `Date.now()`, pas de `Math.random()`, utiliser `delayRender` pour le chargement asynchrone). Enfin, elle inclut un guide de validation des compositions et une liste de vérification pour garantir que le code est correct avant le rendu final.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

HyperFrames Core

Le framework de sortie est Remotion. Une composition est un arbre de composants React enregistré avec <Composition> ; la trame courante est la seule horloge ; la lecture des médias appartient aux composants <Video> / <Audio> de Remotion, pas au DOM.

Cette compétence est le contrat technique : comment construire un projet. Le corps ci-dessous est le guide de construction ; les détails par sujet se trouvent dans references/, à lire à la demande. Les autres préoccupations vivent dans les compétences de domaine sœurs : hyperframes-animation, hyperframes-creative, media-use, hyperframes-cli, hyperframes-registry. La carte des capacités dans /hyperframes indique ce que chacune couvre.

Note de portage. Ce contrat a remplacé un précédent contrat basé sur HTML plus data-* plus GSAP-timeline en pause. Si vous trouvez un projet dont le fichier index.html porte data-composition-id / data-start / data-duration, ou un fichier de référence décrivant window.__timelines, vous avez affaire à l'ancien contrat. Lisez references/legacy-html-contract.md avant d'y toucher.

Références

FichierÀ lire pour…
references/minimal-composition.mddémarrer à partir du squelette de projet rendable le plus petit
references/project-structure.mdorganiser src/, diviser les scènes en composants, décider entre monolithique ou modulaire
references/timing.mdconvertir des secondes en trames, placer une <Sequence>, utiliser <Series> / <TransitionSeries>, chronométrer une scène par rapport à une autre
references/layers-and-order.mdempiler les couches, contrôler l'ordre z, faire chevaucher deux scènes sur le même intervalle
references/props-and-schemas.mddéclarer les props, écrire le schéma Zod, câbler defaultProps et calculateMetadata
references/media.mdplacer <Video> / <OffthreadVideo> / <Audio> / <Img>, rogner, régler le volume, utiliser staticFile
references/determinism-rules.mdgarder le rendu accessible et reproductible ; les interdictions ; le chargement asynchrone des assets avec delayRender
references/editing-recipes.mdles recettes de coupe / rognage / réorganisation / retiming / gel / caméra / masque / fondu / audio et leurs limites
references/legacy-html-contract.mdreconnaître et migrer un projet encore sur l'ancien contrat HTML + data-*
references/tailwind.mdtravailler dans un projet Tailwind v4
references/storyboard-format.mdrédiger un plan STORYBOARD.md (+ le manifeste parsé)
references/review-loop.mdexécuter les passes de revue plan → esquisse → construction sur un tableau live
references/production-loop.mdpasser d'un plan approuvé à une vidéo livrée
references/brief-contract.mdles règles de base du brief : dérivation du mode, registre de champs partagé, invariants de questions
references/brief-format.mdrédiger BRIEF.md
references/script-format.mdrédiger le SCRIPT.md optionnel de narration verrouillée
references/subagent-dispatch.mdmapper les verbes de dispatch de sous-agent à votre harnais
references/frame-worker-core.mdle contrat partagé du rôle de frame-worker

Pour les spécificités d'animation (configurations de ressort, easing, les adaptateurs runtime) allez voir hyperframes-animation.

Construire une composition

La forme d'un projet

package.json          # remotion, react, react-dom ; scripts pour studio/render
remotion.config.ts    # configuration de rendu (codec, format d'image, surcharges Tailwind/webpack)
tsconfig.json
public/               # tout ce que `staticFile()` résout
src/
  index.ts            # registerRoot(Root)
  Root.tsx            # chaque <Composition> vit ici
  <Nom>/
    index.tsx         # le composant de premier niveau de la composition
    scenes/*.tsx      # un composant par scène
    schema.ts         # schéma Zod + type de props inféré

src/index.ts est le point d'entrée et fait exactement une chose :

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

registerRoot(Root);

Enregistrer la composition

Tout élément rendable est un <Composition> dans Root.tsx. L'id est ce que le CLI rend par nom.

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 est la durée de rendu. C'est en trames, pas en secondes, et se tromper est l'erreur de rédaction la plus courante. Dérivez-la d'une constante FPS nommée plutôt que d'écrire 1350.

La trame est la seule horloge

Chaque valeur animée est une fonction pure de useCurrentFrame(). C'est le contrat qui rend un rendu accessible : le moteur de rendu saute à la trame 812 à froid et doit obtenir les mêmes pixels qu'il obtiendrait en lisant en continu.

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>
  );
};

Toujours serrer un interpolate qui mappe une plage de trames, sinon la valeur continue d'extrapoler au-delà de la plage et un fondu devient une opacité de 4 :

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

Le timing est <Sequence>

<Sequence> décale temporellement ses enfants : à l'intérieur, useCurrentFrame() renvoie 0 au début propre de la séquence. Ce rebasage local est tout l'intérêt, car un composant de scène n'a jamais besoin de savoir où il se situe sur la timeline maîtresse.

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

Pour une série de scènes consécutives, <Series> calcule les décalages afin qu'une modification de durée ne cascade pas en correction manuelle de chaque from ultérieur :

<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}> tire une scène plus tôt pour chevaucher sa prédécesseure, ce qui permet d'obtenir un span de fondu sans arithmétique. Tous les détails, plus <TransitionSeries> pour les transitions basées sur la présentation, dans references/timing.md.

Les couches remplacent les pistes

Il n'y a pas d'index de piste. L'empilement est l'ordre DOM à l'intérieur d'un <AbsoluteFill> : les frères ultérieurs s'affichent par-dessus. Une piste de voix-off, un fond musical et trois scènes visuelles sont cinq frères.

<AbsoluteFill>
  <Audio src={staticFile("music.mp3")} volume={0.18} />
  <Audio src={staticFile("vo.mp3")} />
  <Sequence durationInFrames={90}><Hook /></Sequence>
  <Sequence from={90}><Feature /></Sequence>
  <Overlay />                {/* s'affiche par-dessus tout ce qui précède */}
</AbsoluteFill>

<Sequence layout="none"> supprime le wrapper implicite <AbsoluteFill>. Utilisez-le lorsque l'enfant doit participer à la disposition flex ou grid du parent au lieu d'être positionné en absolu.

Les médias appartiennent à Remotion

N'utilisez jamais une balise <video>, <audio> ou <img> brute. Les composants de Remotion sont ce qui permet au moteur de rendu de chercher et d'extraire les trames de manière déterministe.

BesoinUtilisez
Vidéo dans le rendu<OffthreadVideo src> (préférez-le)
Vidéo nécessitant un contrôle au niveau DOM<Video src>
Audio<Audio src volume trimBefore trimAfter>
Image fixe<Img src>
Page intégrée<IFrame src>
Tout fichier sous public/staticFile("dossier/nom.ext")

<OffthreadVideo> extrait les trames avec FFmpeg en dehors du navigateur, ce qui est à la fois plus rapide et plus précis pour le rendu ; recourez à <Video> uniquement lorsque vous avez besoin de l'élément réel (par exemple pour piloter quelque chose avec currentTime). staticFile() est obligatoire pour les assets locaux. Une chaîne nue "/music.mp3" fonctionne dans Studio puis échoue dans un rendu Lambda. Le rognage, les rampes de volume et la vitesse de lecture sont dans references/media.md.

Props et schéma

Les entrées de composition sont des props React, typées par un schéma Zod afin que Studio affiche des contrôles modifiables et qu'une charge utile --props incorrecte échoue bruyamment au lieu de rendre une vidéo erronée.

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>;

Lorsque la durée dépend des props (une liste de fonctionnalités de longueur inconnue, un fichier audio de longueur inconnue), calculez-la dans calculateMetadata plutôt que de coder en dur une estimation. Voir references/props-and-schemas.md.

Règles non-négociables

Des bugs silencieux qu'une vérification de type ne détectera pas. Justification complète dans references/determinism-rules.md.

  • Pas d'horloge murale. Pas de Date.now(), pas de new Date(), pas de performance.now(). Le temps vient de useCurrentFrame().
  • Pas d'aléatoire non ensemencé. Math.random() donne une valeur différente par trame, ce qui stroboscope. Utilisez random(seed) de Remotion : même graine, même valeur, à chaque trame et chaque rendu.
  • Pas d'animation pilotée par l'état. useState / useReducer / useEffect ne doivent rien piloter de visuel. Le moteur de rendu monte les trames dans le désordre et dans des workers parallèles ; l'état accumulé en jouant en avant n'existe pas. Dérivez de frame à la place.
  • Pas d'animations CSS, de transitions ou de requestAnimationFrame. Elles s'exécutent sur l'horloge propre du navigateur, que le moteur de rendu n'avance pas. Chacune d'elles rend une première trame figée.
  • Attendez le travail asynchrone avec delayRender. Un fetch, une police, une disposition mesurée : appelez delayRender() avant et continueRender(handle) après, sinon la trame capture avant que le travail ne soit terminé.
  • Serrer vos interpolations. Un interpolate non serré extrapole en dehors de la plage d'entrée.
  • Positionnement absolu pour tout ce qui est animé. Un élément transformé à l'intérieur du flux normal entraîne ses frères dans son mouvement.

Modifier des compositions existantes

  • Lisez les fichiers d'abord. Préservez le timing, les props, les identifiants et les chemins d'assets non liés.
  • Respectez l'id de la <Composition> existante. Le CLI, tout script de rendu et l'IC adressent les compositions par cet identifiant. En renommer un est un changement cassant.
  • Ajouter une scène : préférez <Series> pour que les décalages se recalculent. Dans une liste <Sequence> avec décalages manuels, corrigez chaque from ultérieur.
  • Changer une durée : vérifiez durationInFrames sur la <Composition> également. Une scène qui dépasse la durée de la composition est silencieusement tronquée.
  • Ajouter un composant : gardez-le comme une fonction pure de props et de frame.

Validation

Les détails de la commande sont dans hyperframes-cli.

  • npx tsc --noEmit, pour que le schéma et les types de props correspondent effectivement
  • npx remotion still <id> out/probe.png --frame <n> à quelques milieux de scène, et examinez chacun
  • npx remotion studio pour la revue, afin que l'utilisateur puisse scruter et ajuster les props lui-même
  • npx remotion render <id> seulement après l'approbation de l'utilisateur

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 associés