Communitygithub.com

chandreshpv/remotion-product-videos-claude-skill

Utilisez cette compétence pour créer des vidéos promotionnelles Remotion. Couvre le dimensionnement du canevas, la structure des scènes, l'entrée 3D de maquettes, les animations de curseur, les micro-animations, les transitions, l'audio et les bonnes pratiques de production.

Qu'est-ce que remotion-product-videos-claude-skill ?

Cette compétence spécialisée dans la création de vidéos promotionnelles avec Remotion est conçue pour les développeurs et créateurs de contenu utilisant des agents IA comme Claude Code, Cursor ou Codex. Elle offre un cadre de travail précis et des règles strictes pour produire des vidéos professionnelles, en évitant les erreurs courantes comme le design basé sur un site web ou des animations non déterministes. La compétence couvre le dimensionnement du canevas 1920×1080px, des animations avec `useCurrentFrame()`, des transitions fluides, et des configurations audio. Elle inclut également des recettes d'assouplissement d'animations (easing), des règles de mise en page pour remplir l'écran, et des scripts pour charger des polices Google Font. L'objectif est de garantir un rendu déterministe, lisible sur 1080p, et une expérience de visionnage optimale.

Compatible avec✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/chandreshpv/remotion-product-videos-claude-skill/tree/main

Demander à votre IA préférée

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

Documentation

Compétence de Production Visuelle Remotion

Créée à partir de l'expérience de production réelle de la vidéo de lancement de SureCart 4.2. Auteur : Chandresh Vaghanani


Avant de Commencer — 2 Questions (Non Négociables)

Posez ces 2 questions avant d'écrire du code. Restez informel — un message, deux questions. Ne les sautez pas, même si l'utilisateur dit "vas-y" ou "commence maintenant". Ces 10 secondes évitent des heures de reprise.

Avant de commencer — deux petites choses :
1. Fond clair ou foncé ? (ou partagez votre site Web/capture d'écran et je le déduirai)
2. Avez-vous une capture d'écran ou une maquette du produit ? (totalement facultatif — je peux construire sans)

C'est tout. Pas d'autres questions à moins que l'utilisateur n'en propose.

Que faire avec les réponses :

  • S'ils partagent une maquette/capture d'écran — extrayez la couleur de fond, la couleur d'accent, le style de police, le texte UI. Utilisez-les.
  • S'ils partagent une URL de site Web — récupérez-la, extrayez la même chose. Ne devinez pas.
  • S'ils répondent clair/foncé uniquement — procédez avec les valeurs par défaut de secours sans info ci-dessous.
  • S'ils ignorent les deux questions — procédez avec les valeurs par défaut de secours sans info ci-dessous. Ne demandez pas à nouveau.

Autres ressources (logo, musique, couleurs supplémentaires) — acceptez si proposées, mais ne bloquez jamais dessus.


Valeurs par Défaut de Secours Sans Info

Lorsque les informations de marque ne sont pas disponibles, l'instinct de l'IA est de réduire les polices et d'ajouter du remplissage. Cet instinct est erroné pour la vidéo. Appliquez plutôt ceci :

Ces valeurs s'appliquent automatiquement si aucune maquette, capture d'écran ou site Web n'est fourni. Elles garantissent un résultat professionnel même sans aucune information de marque.

Mise en Page

  • justifyContent: "center" + alignItems: "center" sur chaque AbsoluteFill de scène — sans exception
  • marginTop: -50 pour décaler le contenu légèrement au-dessus du vrai centre
  • Largeur de la maquette/carte : 1200px (utilisez la limite supérieure — remplissez le cadre)
  • Remplissage du conteneur : max 40px — jamais plus
  • Le contenu doit occuper au moins 75% de la hauteur de 1080px. Si ce n'est pas le cas, augmentez les tailles de police ou réduisez les espaces.

Tailles de Police (par défaut — limite supérieure de la plage)

ÉlémentTaille par défaut
Titre principal140px
Sous-titre56px
Corps / description36px
Étiquette / pilule22px
Texte du contenu de la carte28px

Couleurs (palette par défaut — sûre et professionnelle)

  • Fond : #0a0a0f (presque noir, neutre)
  • Accent : #6366f1 (indigo — lisible, moderne, non spécifique au produit)
  • Texte : #ffffff
  • Texte atténué : rgba(255,255,255,0.55)
  • Fond de carte : rgba(255,255,255,0.06)

Ce ne sont que des POINTS DE DÉPART. Dès que l'utilisateur partage les couleurs de la marque, remplacez-les entièrement.

Ce qu'il NE FAUT PAS faire sans informations de marque

  • N'utilisez PAS de couleurs néon/cyber — c'est une esthétique personnelle, pas une correspondance de marque
  • N'utilisez PAS paddingTop: 120 en l'appelant "centré" — c'est aligné en haut avec un espace vide
  • Ne choisissez PAS fontSize: 32 pour un titre parce que ça "a l'air propre" — c'est illisible sur une vidéo

Règle n°1 — Le Canevas N'est PAS un Site Web

C'est l'erreur la plus courante dans les vidéos Remotion générées par IA.

Le canevas Remotion est 1920×1080px. Concevez pour le remplir — pas comme une page web.

⚠️ Ce sont des MINIMUMS. Écrire fontSize: 18 pour le texte du corps est un BUG, pas un choix de style. Tout ce qui est en dessous de la colonne minimum signifie que le texte est illisible sur un écran 1080p. Traitez ces nombres comme des erreurs de type — ils doivent être corrigés avant de continuer.

ÉlémentMINIMUM (plancher dur)Plage recommandée
Titre principal80px100–160px
Sous-titre40px48–72px
Corps / description28px32–40px
Étiquette / pilule / badge18px20–24px
Texte du contenu de la carte22px24–32px

Règles :

  • Le contenu doit donner l'impression de remplir l'écran
  • Cartes de maquette : width: 1100–1200px, centrées
  • Remplissage du conteneur : max 48px — PAS 80–120px comme une page web
  • Si le texte semble "trop grand pour être confortable" — c'est probablement correct pour la vidéo

Règle n°2 — Toutes les Animations DOIVENT Utiliser useCurrentFrame()

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

// INTERDIT — ne se rendra PAS correctement
// CSS: transition: opacity 1s ease
// Tailwind: animate-fade-in
// CSS @keyframes

Incluez toujours extrapolateLeft: "clamp" et extrapolateRight: "clamp" sur chaque appel interpolate() sauf si vous avez explicitement besoin de valeurs non bornées. Oublier cela provoque des valeurs qui débordent de leur plage et créent des bugs subtils.


Règle n°3 — Déterminisme

// INTERDIT — valeur différente à chaque passe de rendu
const x = Math.random() * 100;

// CORRECT — même valeur à chaque fois, à chaque image
import { random } from "remotion";
const x = random("particle-x-1") * 100; // chaîne de caractères seed = déterministe

Règle n°4 — Ressources

import { staticFile } from "remotion";
import { Img } from "remotion";        // PAS native <img>
import { Audio } from "@remotion/media";

// Utilisez toujours staticFile() pour tout ce qui se trouve dans le dossier public/
<Audio src={staticFile("bg-music.mp3")} />
<Img src={staticFile("logo.png")} />   // <Img> garantit que la ressource se charge avant le rendu de l'image

// Les URL distantes n'ont pas besoin de staticFile() mais nécessitent CORS

Règle n°5 — Lecture Fluide de l'Aperçu

Ajoutez premountFor={30} sur les composants <Sequence> pour que les composants lourds se préchargent 30 images avant leur temps :

<Sequence from={90} durationInFrames={120} premountFor={30}>
  <HeavyScene />
</Sequence>

Recettes d'Assouplissement

import { Easing } from "remotion";

// Entrée UI nette (assouplissement fort, pas de dépassement) — la plupart des animations d'entrée
Easing.bezier(0.16, 1, 0.3, 1)

// Fade éditorial lent (assouplissement équilibré entrée-sortie) — transitions d'ambiance
Easing.bezier(0.45, 0, 0.55, 1)

// Rebond ludique — éléments rebondissants/amusants
Easing.bezier(0.34, 1.56, 0.64, 1)

// Ressort — pas de rebond (entrées de maquette, cartes, UI)
spring({ frame, fps, config: { damping: 200 } })

// Ressort — vif avec léger rebond (éléments percutants)
spring({ frame, fps, config: { damping: 20, stiffness: 200 } })

// Ressort — rebondissant/ludique
spring({ frame, fps, config: { damping: 8 } })

Portes de Pré-Mise en Page — À Exécuter AVANT d'Écrire une Mise en Page de Scène

Ce ne sont pas des suggestions. Exécutez les trois portes avant d'écrire le premier <div> de n'importe quelle scène. Si une porte échoue, modifiez la mise en page — ne corrigez jamais avec des dimensions fixes ou du contenu supplémentaire.


Porte 1 — Remplissage du Canevas (les deux axes, obligatoire)

Axe largeur :
  dead_side = (1920 − content_width) / 2
  DOIT être ≤ 300px. Si > 300px → le contenu est trop étroit. Élargissez-le ou modifiez la mise en page.

Axe hauteur :
  fill_h = content_height / 1080
  DOIT être ≥ 0.80. Si < 0.80 → le contenu est trop court. Modifiez la forme de la mise en page.

⚠️ Si la hauteur échoue, ne la corrigez PAS en définissant une hauteur fixe sur les cartes ou conteneurs. Une hauteur fixe crée un vide vide à l'intérieur de la carte — l'espace mort se déplace à l'intérieur de l'élément au lieu d'être éliminé. La seule vraie solution est de changer la forme de la mise en page (Porte 2).

Exemple réel d'échec — 3 courtes cartes de fonctionnalités :

Versioncontent_widthdead_sidecontent_heightfill_hVerdict
v1 : cartes 3 colonnes (365px)1151px384px416px38%❌ les deux axes échouent
v2 : height: 720px forcée1542px189px864px80%✅ largeur, ❌ visuel (vide vide dans la carte)
v3 : lignes horizontales (1400px)1400px260px916px85%✅ les deux axes passent

Porte 2 — Tableau de Décision de Sélection de Mise en Page

Le volume de contenu détermine la forme de la mise en page. Choisissez la mise en page à partir de ce tableau AVANT d'écrire du code.

ÉlémentsContenu par élémentMise en page correctePourquoi
3–5 élémentsicône + nom + 1 ligneLignes horizontales (1400px de large)Le contenu court s'empile verticalement → remplit la hauteur naturellement
3 élémentsicône + nom + 2–3 lignesCartes 3 colonnes (min 1100px de large)Assez de contenu pour remplir la hauteur de la carte sans vide
2 élémentssubstantielGrandes cartes côte à côte ou écran partagé
1 élémentn'importe quoiHéros plein écran

Si la mise en page naturelle de votre contenu laisse l'un ou l'autre axe en dessous du seuil après la Porte 1 — cette mise en page est erronée. Choisissez une autre ligne dans ce tableau.

Ne choisissez jamais la mise en page par esthétique ou instinct par défaut. L'adaptation du contenu d'abord. L'esthétique en second.


Porte 3 — Limite de Densité de Contenu

Maximum par élément : icône + nom + 1 ligne courte. Arrêt strict. Pas de puces. Pas de sous-sections. Pas de paragraphes. Pas de deuxièmes lignes de description.

Un spectateur a ~5 secondes par scène. Il lit 1 ligne. Il ne lit pas 4 puces.

Si le contenu semble mince et que vous voulez en ajouter pour remplir l'espace — c'est la Porte 2 qui vous dit que la forme de la mise en page est erronée, pas que le contenu manque.

Remplissez l'espace vide avec la TAILLE (polices plus grandes, icônes plus grandes, espaces plus grands entre les éléments) — jamais avec plus de contenu.


Règles Universelles de Scène

  1. Alignement vertical — justifyContent: "center" + marginTop: -40 à -60 (légèrement au-dessus du vrai centre = sensation moderne et premium. PAS aligné en haut avec remplissage.)

    ❌ FAUX — aligné en haut, laisse un espace vide en bas :

    <AbsoluteFill style={{ display: "flex", flexDirection: "column", paddingTop: 110 }}>
      <h1>Titre</h1>
      <p>Sous-texte</p>
      {/* grand vide en bas */}
    </AbsoluteFill>
    

    ✅ CORRECT — verticalement centré, légèrement au-dessus du point médian :

    <AbsoluteFill style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", marginTop: -50 }}>
      <h1>Titre</h1>
      <p>Sous-texte</p>
      {/* le contenu remplit le cadre — pas d'espace mort */}
    </AbsoluteFill>
    
  2. Remplissage du canevas — exécutez les Portes de Pré-Mise en Page avant d'écrire cette scène. La Porte 1 vérifie à la fois la largeur (dead_side ≤ 300px) et la hauteur (fill_h ≥ 0.80). La Porte 2 sélectionne la forme de la mise en page à partir du tableau de décision. La Porte 3 plafonne le contenu par élément. Les trois portes se trouvent dans la section Portes de Pré-Mise en Page ci-dessus — elles remplacent l'ancienne vérification de largeur uniquement qui se trouvait ici.

  3. Z-index du titre — toujours zIndex: 20 sur le conteneur du titre pour que la maquette ne chevauche jamais le texte

  4. Débordement du titre — toujours whiteSpace: "nowrap" sur le texte du titre (empêche le retour à la ligne derrière la maquette)

  5. Pas de overflow: hidden sur AbsoluteFill — coupe le curseur et les éléments SVG. Supprimez-le ou placez le curseur à l'extérieur.

  6. Pause de 15 images — chaque scène doit avoir au moins 15 images entièrement visibles à la FIN avant que la transition ne se déclenche. Ne commencez jamais une transition alors qu'une animation est encore en cours dans la scène sortante.

  7. Police — utilisez une police cohérente tout au long. Recommandée : Plus Jakarta Sans via @remotion/google-fonts. Poids maximum disponible : 800 (écrire fontWeight: 900 s'affiche comme 800).

  8. Couleur — 2 à 3 couleurs de marque maximum. Un fond sombre, un accent principal, blanc/blanc atténué pour le texte. Cohérent dans toutes les scènes.

Hiérarchie Typographique

// Super-titre / Étiquette pilule
{ fontSize: 20, letterSpacing: "4px", textTransform: "uppercase", fontWeight: 600 }

// Titre principal
{ fontSize: 112, fontWeight: 800 }  // plage : 100–160px

// Sous-texte / description
{ fontSize: 36, opacity: 0.7 }  // plage : 32–40px

// Ligne de confiance / petits badges
{ fontSize: 26, opacity: 0.5 }  // plage : 24–28px

Configuration de Police

import { loadFont } from "@remotion/google-fonts/PlusJakartaSans";

// Appelez au niveau supérieur — doit se charger avant le rendu
const { fontFamily } = loadFont("normal", {
  weights: ["400", "600", "800"],
  subsets: ["latin"],
});

Pour d'autres polices : installez via @remotion/google-fonts/NomDeLaPolice ou déposez le fichier .woff2 dans public/ et utilisez loadFont de @remotion/fonts.


Modèle de Structure de Scène

Chaque scène suit cet ordre de couches fixe (bas → haut) :

<AbsoluteFill style={{ background: brandBg }}

Skills associés