Remotion Visual Production Skill
Basierend auf realen Produktionserfahrungen bei der Erstellung des SureCart 4.2-Launchvideos. Autor: Chandresh Vaghanani
Bevor du beginnst – 2 Fragen (Nicht verhandelbar)
Stelle diese 2 Fragen, bevor du Code schreibst. Halte es locker – eine Nachricht, zwei Fragen. Überspringe sie nicht, selbst wenn der Benutzer sagt „mach einfach“ oder „starte jetzt“. Diese 10 Sekunden verhindern stundenlange Nacharbeit.
Bevor ich loslege – zwei kurze Dinge:
1. Heller oder dunkler Hintergrund? (oder teile deine Website/einen Screenshot und ich extrahiere es daraus)
2. Hast du einen Produkt-Screenshot oder ein Mockup? (völlig optional – ich kann auch ohne eines bauen)
Das war's. Keine weiteren Fragen, es sei denn, der Benutzer gibt freiwillig mehr preis.
Was mit den Antworten zu tun ist:
- Wenn sie ein Mockup/Screenshot teilen – extrahiere Hintergrundfarbe, Akzentfarbe, Schriftstil, UI-Text. Verwende es.
- Wenn sie eine Website-URL teilen – rufe sie ab, extrahiere dasselbe. Rate nicht.
- Wenn sie nur hell/dunkel antworten – fahre mit den No-Info-Fallback-Standards unten fort.
- Wenn sie beide Fragen überspringen – fahre mit den No-Info-Fallback-Standards unten fort. Frage nicht erneut.
Andere Assets (Logo, Musik, zusätzliche Farben) – akzeptiere sie, falls angeboten, aber blockiere niemals darauf.
No-Info-Fallback-Standards
Wenn keine Markeninformationen verfügbar sind, ist der Instinkt der KI, Schriftgrößen zu verkleinern und Abstände hinzuzufügen. Dieser Instinkt ist für Video falsch. Wende stattdessen diese an:
Diese greifen automatisch, wenn kein Mockup, Screenshot oder keine Website bereitgestellt wird. Sie sorgen für ein professionelles Ergebnis, selbst ohne Markeninformationen.
Layout
justifyContent: "center"+alignItems: "center"bei jedem AbsoluteFill jeder Szene – keine AusnahmenmarginTop: -50, um den Inhalt leicht über die wahre Mitte zu ziehen- Mockup/Karten-Breite: 1200px (verwende das obere Ende – fülle den Rahmen)
- Container-Padding: max 40px – niemals mehr
- Inhalt muss mindestens 75% der 1080px Höhe einnehmen. Wenn nicht, vergrößere die Schriftgrößen oder verringere die Abstände.
Schriftgrößen (Fallback – oberes Ende des Bereichs)
| Element | Fallback-Größe |
|---|---|
| Hauptüberschrift | 140px |
| Unterüberschrift | 56px |
| Fließtext / Beschreibung | 36px |
| Label / Pill | 22px |
| Karteninhaltstext | 28px |
Farben (Fallback-Palette – sicher und professionell)
- Hintergrund:
#0a0a0f(fast schwarz, neutral) - Akzent:
#6366f1(Indigo – lesbar, modern, nicht produktspezifisch) - Text:
#ffffff - Gedämpfter Text:
rgba(255,255,255,0.55) - Kartenhintergrund:
rgba(255,255,255,0.06)
Dies sind nur AUSGANGSPUNKTE. Sobald der Benutzer Markenfarben teilt, ersetze sie vollständig.
Was NICHT zu tun ist, ohne Markeninformationen
- Verwende KEINE Neon-/Cyber-Farben – das ist eine persönliche Ästhetik, kein Markenfit
- Verwende NICHT
paddingTop: 120und nenne es „zentriert“ – es ist oben ausgerichtet mit totem Raum - Wähle NICHT
fontSize: 32für eine Überschrift, weil es „sauber aussieht“ – es ist auf Video unlesbar
Regel #1 – Canvas ist KEINE Website
Dies ist der häufigste Fehler bei KI-generierten Remotion-Videos.
Die Remotion-Leinwand ist 1920×1080px. Gestalte sie so, dass sie sie ausfüllt – nicht wie eine Webseite.
⚠️ Dies sind MINIMUM.
fontSize: 18für Fließtext zu schreiben, ist ein FEHLER, keine Stilwahl. Alles unterhalb der Minimum-Spalte bedeutet, dass der Text auf einem 1080p-Bildschirm unlesbar ist. Behandle diese Zahlen wie Typfehler – sie müssen behoben werden, bevor du fortfährst.
| Element | MINIMUM (harte Untergrenze) | Empfohlener Bereich |
|---|---|---|
| Hauptüberschrift | 80px | 100–160px |
| Unterüberschrift | 40px | 48–72px |
| Fließtext / Beschreibung | 28px | 32–40px |
| Label / Pill / Badge | 18px | 20–24px |
| Karteninhaltstext | 22px | 24–32px |
Regeln:
- Inhalt muss sich anfühlen, als fülle er den Bildschirm
- Mockup-Karten:
width: 1100–1200px, zentriert - Container-Padding: max 48px – NICHT 80–120px wie eine Webseite
- Wenn sich Text „zu groß für Komfort“ anfühlt – ist er wahrscheinlich richtig für Video
Regel #2 – Alle Animationen MÜSSEN useCurrentFrame() verwenden
// RICHTIG
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 20], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
// VERBOTEN – wird NICHT korrekt rendern
// CSS: transition: opacity 1s ease
// Tailwind: animate-fade-in
// CSS @keyframes
Füge immer extrapolateLeft: "clamp" und extrapolateRight: "clamp" bei jedem interpolate()-Aufruf hinzu, es sei denn, du benötigst explizit unbegrenzte Werte. Das Vergessen führt dazu, dass Werte außerhalb ihres Bereichs auslaufen und subtile Fehler verursachen.
Regel #3 – Deterministisches Verhalten
// VERBOTEN – unterschiedlicher Wert bei jedem Rendering-Durchlauf
const x = Math.random() * 100;
// RICHTIG – gleicher Wert jedes Mal, jeder Frame
import { random } from "remotion";
const x = random("particle-x-1") * 100; // String-Seed = deterministisch
Regel #4 – Assets
import { staticFile } from "remotion";
import { Img } from "remotion"; // NICHT natives <img>
import { Audio } from "@remotion/media";
// Verwende immer staticFile() für alles im public/-Ordner
<Audio src={staticFile("bg-music.mp3")} />
<Img src={staticFile("logo.png")} /> // <Img> stellt sicher, dass Asset geladen wird, bevor Frame gerendert wird
// Remote-URLs benötigen kein staticFile(), benötigen aber CORS
Regel #5 – Flüssige Vorschau-Wiedergabe
Füge premountFor={30} bei <Sequence>-Komponenten hinzu, damit schwere Komponenten 30 Frames vor ihrer Zeit vorgeladen werden:
<Sequence from={90} durationInFrames={120} premountFor={30}>
<HeavyScene />
</Sequence>
Easing-Rezepte
import { Easing } from "remotion";
// Knackiger UI-Eintritt (starke Ease-Out, kein Überschwingen) – die meisten Eintrittsanimationen
Easing.bezier(0.16, 1, 0.3, 1)
// Langsamer redaktioneller Ein- und Ausblender (ausgewogene Ease-In-Out) – Stimmungsübergänge
Easing.bezier(0.45, 0, 0.55, 1)
// Verspieltes Überschwingen – hüpfende/lustige Elemente
Easing.bezier(0.34, 1.56, 0.64, 1)
// Spring – kein Abprallen (Mockup-Eintritte, Karten, UI)
spring({ frame, fps, config: { damping: 200 } })
// Spring – knackig mit leichtem Abprallen (knackige Elemente)
spring({ frame, fps, config: { damping: 20, stiffness: 200 } })
// Spring – hüpfend/verspielt
spring({ frame, fps, config: { damping: 8 } })
Pre-Layout-Gates – Ausführen, BEVOR ein Szenen-Layout geschrieben wird
Dies sind keine Vorschläge. Führe alle drei Gates aus, bevor du das erste <div> einer Szene schreibst. Wenn ein Gate fehlschlägt, ändere das Layout – repariere es niemals mit festen Dimensionen oder zusätzlichem Inhalt.
Gate 1 – Canvas-Ausfüllung (beide Achsen, obligatorisch)
Width-Achse:
dead_side = (1920 − content_width) / 2
MUSS ≤ 300px sein. Wenn > 300px → Inhalt ist zu schmal. Verbreitere ihn oder ändere das Layout.
Height-Achse:
fill_h = content_height / 1080
MUSS ≥ 0.80 sein. Wenn < 0.80 → Inhalt ist zu kurz. Ändere die Layout-Form.
⚠️ Wenn die Höhe fehlschlägt, behebe es NICHT, indem du eine feste Höhe für Karten oder Container setzt. Eine feste Höhe erzeugt eine leere Leere in der Karte – der tote Raum wandert in das Element, anstatt beseitigt zu werden. Die einzige wirkliche Lösung ist, die Layout-Form zu ändern (Gate 2).
Reales Fehlerbeispiel – 3 kurze Feature-Karten:
| Version | content_width | dead_side | content_height | fill_h | Ergebnis |
|---|---|---|---|---|---|
| v1: 3-Spalten-Karten (365px) | 1151px | 384px | 416px | 38% | ❌ beide Achsen fehlgeschlagen |
v2: erzwungen height: 720px | 1542px | 189px | 864px | 80% | ✅ Breite, ❌ visuell (leere Leere in der Karte) |
| v3: horizontale Reihen (1400px) | 1400px | 260px | 916px | 85% | ✅ beide Achsen bestanden |
Gate 2 – Layout-Auswahl-Entscheidungstabelle
Das Inhaltsvolumen bestimmt die Layout-Form. Wähle das Layout aus dieser Tabelle AUS, bevor du Code schreibst.
| Elemente | Inhalt pro Element | Korrektes Layout | Warum |
|---|---|---|---|
| 3–5 Elemente | Icon + Name + 1 Zeile | Horizontale Reihen (1400px breit) | Kurzer Inhalt stapelt sich vertikal → füllt Höhe natürlich |
| 3 Elemente | Icon + Name + 2–3 Zeilen | 3-Spalten-Karten (min 1100px breit) | Genug Inhalt, um Kartenhöhe ohne Leere zu füllen |
| 2 Elemente | substanziell | Große Karten nebeneinander oder geteilter Bildschirm | |
| 1 Element | alles | Ganzbildschirm-Hero |
Wenn das natürliche Layout für deinen Inhalt nach Gate 1 eine Achse unter dem Schwellenwert lässt – ist dieses Layout falsch. Wähle eine andere Zeile in dieser Tabelle.
Wähle das Layout niemals nach Ästhetik oder Standardinstinkt. Inhaltsfit zuerst. Ästhetik zweitens.
Gate 3 – Inhaltsdichte-Limit
Pro Element Maximum: Icon + Name + 1 kurze Zeile. Harte Grenze. Keine Aufzählungspunkte. Keine Unterabschnitte. Keine Absätze. Keine zweiten Beschreibungszeilen.
Ein Betrachter hat ~5 Sekunden pro Szene. Er liest 1 Zeile. Er liest keine 4 Aufzählungspunkte.
Wenn sich Inhalt dünn anfühlt und du mehr hinzufügen möchtest, um Platz zu füllen – sagt dir Gate 2, dass die Layout-Form falsch ist, nicht dass Inhalt fehlt.
Fülle leeren Raum mit GRÖSSE (größere Schriftarten, größere Icons, größere Abstände zwischen Elementen) – niemals mit mehr Inhalt.
Universelle Szenenregeln
-
Vertikale Ausrichtung –
justifyContent: "center"+marginTop: -40bis-60(leicht über der wahren Mitte = modernes, hochwertiges Gefühl. NICHT oben ausgerichtet mit Padding.)❌ FALSCH – oben ausgerichtet, lässt unten leeren Raum:
<AbsoluteFill style={{ display: "flex", flexDirection: "column", paddingTop: 110 }}> <h1>Überschrift</h1> <p>Untertext</p> {/* große leere Leere unten */} </AbsoluteFill>✅ RICHTIG – vertikal zentriert, leicht über dem Mittelpunkt:
<AbsoluteFill style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", marginTop: -50 }}> <h1>Überschrift</h1> <p>Untertext</p> {/* Inhalt füllt den Rahmen – kein toter Raum */} </AbsoluteFill> -
Canvas-Ausfüllung – führe Pre-Layout-Gates aus, bevor du diese Szene schreibst. Gate 1 prüft sowohl Breite (
dead_side ≤ 300px) als auch Höhe (fill_h ≥ 0.80) zusammen. Gate 2 wählt die Layout-Form aus der Entscheidungstabelle. Gate 3 begrenzt den Inhalt pro Element. Alle drei Gates befinden sich oben im Abschnitt „Pre-Layout-Gates“ – sie ersetzen die alte breitenbasierte Prüfung, die hier war. -
Überschrift z-index – immer
zIndex: 20auf dem Überschriftscontainer, damit Mockup niemals Text überlappt -
Überschrift-Überlauf – immer
whiteSpace: "nowrap"auf dem Überschriftentext (verhindert Umbruch hinter Mockup) -
Kein
overflow: hiddenauf AbsoluteFill – schneidet Cursor- und SVG-Elemente ab. Entferne es oder platziere Cursor außerhalb. -
15 Frames Haltezeit – jede Szene muss mindestens 15 Frames vollständig sichtbare Haltezeit am ENDE haben, bevor der Übergang ausgelöst wird. Beginne niemals einen Übergang, während in der ausgehenden Szene noch eine Animation läuft.
-
Schriftart – verwende eine konsistente Schriftart durchgehend. Empfohlen: Plus Jakarta Sans via
@remotion/google-fonts. Maximal verfügbare Stärke: 800 (fontWeight: 900wird als 800 gerendert). -
Farbe – maximal 2–3 Markenfarben. Ein dunkler Hintergrund, ein primärer Akzent, weiß/gedämpftes Weiß für Text. Konsistent in allen Szenen.
Typografie-Hierarchie
// Supertitel / Label-Pill
{ fontSize: 20, letterSpacing: "4px", textTransform: "uppercase", fontWeight: 600 }
// Hauptüberschrift
{ fontSize: 112, fontWeight: 800 } // Bereich: 100–160px
// Untertext / Beschreibung
{ fontSize: 36, opacity: 0.7 } // Bereich: 32–40px
// Vertrauenszeile / kleine Badges
{ fontSize: 26, opacity: 0.5 } // Bereich: 24–28px
Schriftart-Setup
import { loadFont } from "@remotion/google-fonts/PlusJakartaSans";
// Auf oberster Ebene aufrufen – muss vor dem Rendern geladen sein
const { fontFamily } = loadFont("normal", {
weights: ["400", "600", "800"],
subsets: ["latin"],
});
Für andere Schriftarten: installiere via @remotion/google-fonts/Schriftartenname oder lege .woff2 in public/ ab und verwende loadFont von @remotion/fonts.
Szenenstruktur-Vorlage
Jede Szene folgt dieser festen Ebenenreihenfolge (unten → oben):
<AbsoluteFill style={{ background: brandBg }}