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 exceptionmarginTop: -50pour 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ément | Taille par défaut |
|---|---|
| Titre principal | 140px |
| Sous-titre | 56px |
| Corps / description | 36px |
| Étiquette / pilule | 22px |
| Texte du contenu de la carte | 28px |
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: 120en l'appelant "centré" — c'est aligné en haut avec un espace vide - Ne choisissez PAS
fontSize: 32pour 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: 18pour 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ément | MINIMUM (plancher dur) | Plage recommandée |
|---|---|---|
| Titre principal | 80px | 100–160px |
| Sous-titre | 40px | 48–72px |
| Corps / description | 28px | 32–40px |
| Étiquette / pilule / badge | 18px | 20–24px |
| Texte du contenu de la carte | 22px | 24–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 :
| Version | content_width | dead_side | content_height | fill_h | Verdict |
|---|---|---|---|---|---|
| v1 : cartes 3 colonnes (365px) | 1151px | 384px | 416px | 38% | ❌ les deux axes échouent |
v2 : height: 720px forcée | 1542px | 189px | 864px | 80% | ✅ largeur, ❌ visuel (vide vide dans la carte) |
| v3 : lignes horizontales (1400px) | 1400px | 260px | 916px | 85% | ✅ 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éments | Contenu par élément | Mise en page correcte | Pourquoi |
|---|---|---|---|
| 3–5 éléments | icône + nom + 1 ligne | Lignes horizontales (1400px de large) | Le contenu court s'empile verticalement → remplit la hauteur naturellement |
| 3 éléments | icône + nom + 2–3 lignes | Cartes 3 colonnes (min 1100px de large) | Assez de contenu pour remplir la hauteur de la carte sans vide |
| 2 éléments | substantiel | Grandes cartes côte à côte ou écran partagé | |
| 1 élément | n'importe quoi | Hé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
-
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> -
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. -
Z-index du titre — toujours
zIndex: 20sur le conteneur du titre pour que la maquette ne chevauche jamais le texte -
Débordement du titre — toujours
whiteSpace: "nowrap"sur le texte du titre (empêche le retour à la ligne derrière la maquette) -
Pas de
overflow: hiddensur AbsoluteFill — coupe le curseur et les éléments SVG. Supprimez-le ou placez le curseur à l'extérieur. -
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.
-
Police — utilisez une police cohérente tout au long. Recommandée : Plus Jakarta Sans via
@remotion/google-fonts. Poids maximum disponible : 800 (écrirefontWeight: 900s'affiche comme 800). -
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 }}