diff --git a/remotion/src/Root.tsx b/remotion/src/Root.tsx
index 0cd1887..689b92c 100644
--- a/remotion/src/Root.tsx
+++ b/remotion/src/Root.tsx
@@ -12,6 +12,7 @@ import {F01} from './folge01/Folge01';
import {F02} from './folge02/Folge02';
import {F03} from './folge03/Folge03';
import {F08} from './folge08/Folge08';
+import {F09} from './folge09/Folge09';
import {Banner, BannerRahmen, Profilbild} from './kanal/KanalBilder';
import {VorschauF01} from './kanal/Vorschaubild';
import {ShortKompositionen} from './shorts/Short';
@@ -37,6 +38,7 @@ export const Root: React.FC = () => (
+
diff --git a/remotion/src/baukasten/geraeusche.json b/remotion/src/baukasten/geraeusche.json
index bd76415..643b37b 100644
--- a/remotion/src/baukasten/geraeusche.json
+++ b/remotion/src/baukasten/geraeusche.json
@@ -21,5 +21,7 @@
"kribbeln": {"sekunden": 2, "beschreibung": "Cute magical sparkle twinkle, soft glockenspiel shimmer, cartoon, happy."},
"schlaff": {"sekunden": 2, "beschreibung": "Soft short descending cartoon slide whistle, a little sad but cute and gentle."},
"klick": {"sekunden": 1, "beschreibung": "One crisp, clearly audible click of a small plastic push button switching on a battery lamp, like a light switch, close up, no voice, no music."},
+ "wind": {"sekunden": 20, "loop": true, "beschreibung": "Friendly autumn wind in an open meadow: soft steady breeze with gentle gusts, dry leaves rustling and tumbling over grass, calm and pleasant, not stormy. No voices, no music."},
+ "plumps": {"sekunden": 1, "beschreibung": "A soft light thud of a paper kite falling flat onto grass, gentle cartoon plop with a little rustle, no voice."},
"niesen": {"sekunden": 1.5, "beschreibung": "A single cute, funny cartoon sneeze 'ha-tschi!' from a friendly young animal character, light and playful, like in a preschool cartoon. No speech, no music."}
}
diff --git a/remotion/src/folge09/Folge09.tsx b/remotion/src/folge09/Folge09.tsx
new file mode 100644
index 0000000..14ea4a8
--- /dev/null
+++ b/remotion/src/folge09/Folge09.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import {INTRO_OPTIONEN, Intro, OUTRO, Outro, introZeilen} from '../baukasten/buch';
+import {baueFolge, type SzenenEintrag} from '../baukasten/folge';
+import {mitKlang} from '../baukasten/geraeusche';
+import {TITEL, plane} from './plan';
+import {S2, Szene2} from './szene2';
+import {S3, Szene3} from './szene3';
+import {S4, Szene4} from './szene4';
+import {S5, Szene5} from './szene5';
+import {S6, Szene6} from './szene6';
+import {S7, Szene7} from './szene7';
+
+// Folge 9 „Lulu und der Drachen“ (läuft So 15.11.) – per Code aus der Figuren-Bibliothek,
+// Drehbuch drehbuecher/neu-lulu-und-der-drachen/de.md. Wind von links nach rechts.
+
+const INTRO = plane('intro', introZeilen(TITEL), INTRO_OPTIONEN);
+const wind = {atmo: 'wind', atmoLaut: 0.14};
+
+export const SZENEN: SzenenEintrag[] = [
+ {
+ name: 'Intro',
+ datei: 'Folge09.tsx',
+ plan: INTRO,
+ K: mitKlang(() => , INTRO, {
+ toene: [{name: 'buch_auf', bei: 'buch', versatz: 0.7, lautstaerke: 0.35}],
+ }),
+ musik: {datei: 'musik/folge01/intro.mp3', lautstaerke: 0.35, rein: 0.2, raus: 1.2},
+ },
+ {name: 'Mein Drachen', datei: 'szene2.tsx', plan: S2, K: mitKlang(Szene2, S2, wind)},
+ {name: 'Plumps', datei: 'szene3.tsx', plan: S3, K: mitKlang(Szene3, S3, {...wind, toene: [{name: 'plumps', bei: 'plumps', versatz: 1.6, lautstaerke: 0.4}, {name: 'plumps', bei: 'plumps', versatz: 3.6, lautstaerke: 0.4}]})},
+ {name: 'Ganz hoch', datei: 'szene4.tsx', plan: S4, K: mitKlang(Szene4, S4, {...wind, toene: [{name: 'plumps', bei: 'fliegen', versatz: 4.2, lautstaerke: 0.4}]})},
+ {name: 'Pino sieht es', datei: 'szene5.tsx', plan: S5, K: mitKlang(Szene5, S5, wind)},
+ {name: 'Er fliegt', datei: 'szene6.tsx', plan: S6, K: mitKlang(Szene6, S6, wind), musik: {datei: 'musik/folge01/lied.mp3', lautstaerke: 0.3, ducken: 0.6, rein: 3, raus: 2}},
+ {name: 'Abendwind', datei: 'szene7.tsx', plan: S7, K: mitKlang(Szene7, S7, {atmo: 'garten_abend', atmoLaut: 0.1}), musik: {datei: 'musik/folge01/schlaflied.mp3', lautstaerke: 0.3, rein: 3, raus: 0.1}},
+ {
+ name: 'Outro',
+ datei: 'Folge09.tsx',
+ plan: OUTRO,
+ K: mitKlang(() => , OUTRO, {toene: [{name: 'buch_zu', bei: 'buch', versatz: 3.2, lautstaerke: 0.45}]}),
+ musik: {datei: 'musik/folge01/schlaflied.mp3', lautstaerke: 0.3, ab: S7.dauer / 30, rein: 0.1, raus: 2},
+ },
+];
+
+export const F09 = baueFolge('F09', SZENEN);
diff --git a/remotion/src/folge09/plan.ts b/remotion/src/folge09/plan.ts
new file mode 100644
index 0000000..fed0278
--- /dev/null
+++ b/remotion/src/folge09/plan.ts
@@ -0,0 +1,29 @@
+import {SPRACHE, type FolgenTexte} from '../baukasten/sprache';
+import {plane as basis, type PlanOptionen, type Zeile} from '../baukasten/zeit';
+import DE from './texte/de.json';
+import ES from './texte/es.json';
+import FR from './texte/fr.json';
+import STIMMEN_DE from './stimmen/de.json';
+import STIMMEN_ES from './stimmen/es.json';
+import STIMMEN_FR from './stimmen/fr.json';
+
+// Sprechtexte stehen nur in texte/.json (Schlüssel „szene/zeile“),
+// die Szenen enthalten nur Ablauf und Bewegung. Aufnahmen je Sprache in
+// stimmen/.json bzw. public/stimmen/folge09// (erzeugt von
+// werkzeuge/stimmen.mts).
+
+export const TEXTE: FolgenTexte = {de: DE, es: ES, fr: FR}[SPRACHE];
+const AUFNAHMEN = {de: STIMMEN_DE, es: STIMMEN_ES, fr: STIMMEN_FR}[SPRACHE];
+
+export const TITEL = TEXTE.titel;
+
+// Zeitplan einer Szene dieser Folge, mit den Texten der gewählten Sprache
+export const plane = (szene: string, zeilen: Zeile[], opt: PlanOptionen = {}) =>
+ basis(
+ zeilen.map((z) => {
+ if (z.text !== undefined || !z.wer) return z;
+ const text = TEXTE.zeilen[`${szene}/${z.id}`];
+ return {...z, text: text ?? `[fehlt: ${szene}/${z.id}]`};
+ }),
+ {...opt, szene, aufnahmen: AUFNAHMEN, ordner: `stimmen/folge09/${SPRACHE}`},
+ );
diff --git a/remotion/src/folge09/stimmen/de.json b/remotion/src/folge09/stimmen/de.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/remotion/src/folge09/stimmen/de.json
@@ -0,0 +1 @@
+{}
diff --git a/remotion/src/folge09/stimmen/es.json b/remotion/src/folge09/stimmen/es.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/remotion/src/folge09/stimmen/es.json
@@ -0,0 +1 @@
+{}
diff --git a/remotion/src/folge09/stimmen/fr.json b/remotion/src/folge09/stimmen/fr.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/remotion/src/folge09/stimmen/fr.json
@@ -0,0 +1 @@
+{}
diff --git a/remotion/src/folge09/szene2.tsx b/remotion/src/folge09/szene2.tsx
new file mode 100644
index 0000000..8a08c90
--- /dev/null
+++ b/remotion/src/folge09/szene2.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import {interpolate, useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {Drachen} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {LuluImWind, PLATZ, WindGarten, drachenUeberNoa} from './teile';
+
+// Szene 2: Mein Drachen. Windiger Nachmittag; Noa hält ihren roten Papierdrachen hoch, die drei
+// Schleifen am Schwanz leuchten beim Zählen nacheinander auf.
+
+export const S2 = plane('s2', [
+ {id: 'bild0', dauer: 2.6},
+ {id: 'n1', wer: 'NOA'},
+ {id: 'p1', wer: 'PINO'},
+ {id: 'n2', wer: 'NOA'},
+ {id: 'e1', wer: 'ERZ'},
+ {id: 'z1', wer: 'ERZ', pause: 1.5},
+ {id: 'z2', wer: 'ERZ', pause: 1.5},
+ {id: 'z3', wer: 'ERZ', pause: 1.0},
+ {id: 'e2', wer: 'ERZ'},
+ {id: 'bild1', dauer: 1.2},
+]);
+
+const klemm = {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'} as const;
+
+export const Szene2: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S2;
+ const d = drachenUeberNoa(PLATZ.noa);
+ const leuchte = (id: 'z1' | 'z2' | 'z3') => interpolate(f, [z[id].start, z[id].start + 6, z[id].frei, z[id].frei + 8], [0, 1, 1, 0.25], klemm);
+ const kam = kamFahrt(f, [
+ [0, 1060, 540, 1.0],
+ [z.bild0.ende, 1060, 600, 1.15],
+ [z.n2.ende, 1000, 560, 1.2],
+ [z.e1.start + 20, d.x, d.y + 60, 2.2], // Nahaufnahme Drachen zum Zählen
+ [z.e2.ende, d.x, d.y + 60, 2.2],
+ [dauer, 1060, 600, 1.15],
+ ]);
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/szene3.tsx b/remotion/src/folge09/szene3.tsx
new file mode 100644
index 0000000..eb6199f
--- /dev/null
+++ b/remotion/src/folge09/szene3.tsx
@@ -0,0 +1,58 @@
+import React from 'react';
+import {useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {type DrachenLage, LIEGE_HOEHE, plumps} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {DRACHEN_IM_GRAS, LuluImWind, PLATZ, SchnurUndDrachen, WindGarten} from './teile';
+
+// Szene 3: Plumps! Noa steht mitten auf der Wiese, aber verkehrt herum (schaut gegen den Wind nach links),
+// der Drachen liegt windaufwärts vor ihr im Gras (bei Lulu). Ein Windstoß hebt ihn kurz an – plumps, zweimal. Noa ist enttäuscht;
+// Pino tröstet, Lulu spürt oben den Wind. Beim „Puste mal!“ fegt eine Böe Blätter durchs Bild.
+
+export const S3 = plane('s3', [
+ {id: 'plumps', dauer: 4.2},
+ {id: 'n1', wer: 'NOA'},
+ {id: 'e1', wer: 'ERZ', pause: 4},
+ {id: 'e2', wer: 'ERZ'},
+ {id: 'p1', wer: 'PINO'},
+ {id: 'l1', wer: 'LULU'},
+ {id: 'e3', wer: 'ERZ', pause: 3},
+ {id: 'e4', wer: 'ERZ'},
+ {id: 'bild1', dauer: 1.0},
+]);
+
+export const Szene3: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S3;
+ const p0 = z.plumps.start + 6;
+ const halb = (z.plumps.ende - p0) / 2;
+ const lage: DrachenLage = f < p0 + halb ? plumps(f, p0, halb, DRACHEN_IM_GRAS.x, BODEN) : plumps(f, p0 + halb, halb, DRACHEN_IM_GRAS.x, BODEN);
+ const traurig = f >= z.n1.start && f < z.p1.ende;
+ const boeen = f >= z.e3.ende && f < z.e3.frei + 20 ? 1 : 0;
+ const kam = kamFahrt(f, [
+ [0, 1060, 600, 1.15],
+ [z.n1.start, PLATZ.noa, 640, 1.5], // Noa
+ [z.e2.ende, 960, 640, 1.3],
+ [z.l1.start, PLATZ.lulu - 60, 420, 1.35], // Lulu oben im Wind
+ [z.e3.start, 1060, 560, 1.05],
+ [dauer, 1060, 560, 1.05],
+ ]);
+ return (
+ <>
+
+
+
+ {/* Noa schaut nach links: die Schnur läuft hinter ihr zum Drachen */}
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/szene4.tsx b/remotion/src/folge09/szene4.tsx
new file mode 100644
index 0000000..25d621e
--- /dev/null
+++ b/remotion/src/folge09/szene4.tsx
@@ -0,0 +1,61 @@
+import React from 'react';
+import {useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {type DrachenLage, steigen, trudeln} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {DRACHEN_IM_GRAS, LuluHebt, PLATZ, SchnurUndDrachen, WindGarten, drachenBeiLulu, hebenPlan} from './teile';
+
+// Szene 4: Ganz hoch. Lulu holt den Drachen mit dem Maul aus dem Gras und hebt ihn ganz hoch; Noa hält
+// die Schnur – steht aber noch verkehrt herum. Lulu lässt los, der Drachen steigt kurz, dreht sich im Kreis
+// und trudelt ins Gras. „Wer ist ganz unten?“ – „Pino!“
+
+export const S4 = plane('s4', [
+ {id: 'n1', wer: 'NOA'},
+ {id: 'l1', wer: 'LULU'},
+ {id: 'heben', dauer: 6.6},
+ {id: 'fliegen', dauer: 4.6},
+ {id: 'l2', wer: 'LULU'},
+ {id: 'n2', wer: 'NOA'},
+ {id: 'e1', wer: 'ERZ', pause: 3},
+ {id: 'e2', wer: 'ERZ'},
+ {id: 'bild1', dauer: 0.8},
+]);
+
+export const Szene4: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S4;
+ const plan = hebenPlan(z.heben.start);
+ const los = z.fliegen.start;
+ let lage: DrachenLage;
+ if (f < los) lage = drachenBeiLulu(f, plan);
+ else {
+ const von = drachenBeiLulu(los - 1, plan);
+ const oben = {x: von.x + 60, y: von.y - 140};
+ lage = f < los + 45 ? steigen(f, los, 45, von, oben) : trudeln(f, los + 45, z.fliegen.ende - los - 45, oben, BODEN, DRACHEN_IM_GRAS.x - oben.x);
+ }
+ const kam = kamFahrt(f, [
+ [0, 1080, 600, 1.15],
+ [z.heben.start + 10, PLATZ.lulu, 560, 1.2],
+ [z.fliegen.start, PLATZ.lulu + 100, 470, 1.0],
+ [z.n2.start, 1080, 600, 1.15],
+ [z.e1.start + 40, PLATZ.pino + 80, 820, 1.9], // „Und wer ist ganz unten?“ – Pino
+ [dauer, PLATZ.pino + 80, 820, 1.9],
+ ]);
+ return (
+ <>
+
+
+ = z.l2.start ? 'lulu_A4_staunen' : f >= los ? 'lulu_A3_lachen' : undefined} />
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/szene5.tsx b/remotion/src/folge09/szene5.tsx
new file mode 100644
index 0000000..a6bc23d
--- /dev/null
+++ b/remotion/src/folge09/szene5.tsx
@@ -0,0 +1,54 @@
+import React from 'react';
+import {useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {LIEGE_HOEHE} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {DRACHEN_IM_GRAS, LuluImWind, PLATZ, SchnurUndDrachen, WindGarten} from './teile';
+
+// Szene 5: Pino sieht es. Ganz unten bei Pino wirbeln die Blätter alle nach rechts, das Gras biegt sich.
+// Pino zeigt erst dorthin, wohin die Blätter tanzen, dann dorthin, woher der Wind kommt.
+
+export const S5 = plane('s5', [
+ {id: 'bild0', dauer: 2.4},
+ {id: 'p1', wer: 'PINO'},
+ {id: 'e1', wer: 'ERZ'},
+ {id: 'e2', wer: 'ERZ', pause: 4},
+ {id: 'e3', wer: 'ERZ'},
+ {id: 'bild1', dauer: 0.8},
+]);
+
+export const Szene5: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S5;
+ // „… tanzen alle dahin!“ zeigt nach rechts, „Der Wind kommt von da drüben!“ nach links
+ const umdrehen = z.p1.start + (z.p1.ende - z.p1.start) * 0.55;
+ const kam = kamFahrt(f, [
+ [0, PLATZ.pino + 80, 830, 2.2],
+ [z.e1.start, PLATZ.pino + 120, 800, 1.9],
+ [z.e3.start, 1060, 560, 1.05], // Blätter, Bäume, Lulus Schal
+ [dauer, 1060, 560, 1.05],
+ ]);
+ return (
+ <>
+
+
+
+
+
+ = umdrehen && f < z.e1.start + 20}
+ stauchY={atmen(f, 1, 0.015)}
+ />
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/szene6.tsx b/remotion/src/folge09/szene6.tsx
new file mode 100644
index 0000000..3ff4645
--- /dev/null
+++ b/remotion/src/folge09/szene6.tsx
@@ -0,0 +1,74 @@
+import React from 'react';
+import {useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {type DrachenLage, pendeln, steigen} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {LuluHebt, LuluImWind, PLATZ, SchnurUndDrachen, WindGarten, drachenBeiLulu, hebenPlan} from './teile';
+
+// Szene 6: Er fliegt! Pino ruft „Dreh dich um!“, Noa dreht sich mit dem Rücken zum Wind. Lulu hebt den
+// Drachen noch einmal hoch und lässt los: Er steigt nach rechts hoch über die Wiese und tanzt im Wind
+// (ruhiger Moment ohne Worte). Rätsel „Wer hat so einen langen Hals?“ – „Lulu!“
+
+export const S6 = plane('s6', [
+ {id: 'p1', wer: 'PINO'},
+ {id: 'e1', wer: 'ERZ'},
+ {id: 'heben', dauer: 6.6},
+ {id: 'steigen', dauer: 4.0},
+ {id: 'n1', wer: 'NOA'},
+ {id: 'p2', wer: 'PINO'},
+ {id: 'e2', wer: 'ERZ'},
+ {id: 'tanzen', dauer: 12},
+ {id: 'e3', wer: 'ERZ', pause: 3},
+ {id: 'e4', wer: 'ERZ'},
+ {id: 'l1', wer: 'LULU'},
+ {id: 'p3', wer: 'PINO'},
+ {id: 'e5', wer: 'ERZ'},
+ {id: 'bild1', dauer: 1.6},
+]);
+
+const HIMMEL = {x: 1700, y: 120}; // rechts über der Wiese, höher als der Apfelbaum
+
+export const Szene6: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S6;
+ const plan = hebenPlan(z.heben.start);
+ const los = z.steigen.start;
+ const dreht = z.e1.start + 10; // Noa dreht sich um: jetzt schaut sie nach rechts, der Wind kommt von hinten
+ let lage: DrachenLage;
+ if (f < los) lage = drachenBeiLulu(f, plan);
+ else if (f < z.steigen.ende) lage = steigen(f, los, z.steigen.ende - los, drachenBeiLulu(los - 1, plan), HIMMEL);
+ else lage = pendeln(f, HIMMEL, 1);
+ const kam = kamFahrt(f, [
+ [0, PLATZ.pino + 120, 780, 1.7],
+ [z.e1.start, 1150, 600, 1.15],
+ [z.steigen.start, 1300, 440, 0.98],
+ [z.e2.start, PLATZ.noa, 620, 1.3], // Noa ist stolz
+ [z.tanzen.start + 30, 1420, 340, 1.0], // Drachen tanzt
+ [z.e3.start, 1250, 380, 1.0],
+ [z.l1.start, 1100, 560, 1.05],
+ [dauer, 1150, 500, 0.98],
+ ]);
+ const stolz = f >= z.n1.start;
+ return (
+ <>
+
+ = z.steigen.start ? 0.3 : 0} />
+ {f < los ? : = z.e4.start && f < z.l1.start ? undefined : undefined} stauchY={f >= z.e4.start && f < z.e4.ende + 20 ? 1.05 : 1} />}
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/szene7.tsx b/remotion/src/folge09/szene7.tsx
new file mode 100644
index 0000000..0706ab8
--- /dev/null
+++ b/remotion/src/folge09/szene7.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import {useCurrentFrame} from 'remotion';
+import {Figur, Kamera} from '../baukasten/figur';
+import {Drachen, LIEGE_HOEHE} from '../baukasten/drachen';
+import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
+import {BODEN} from '../baukasten/orte';
+import {Untertitel} from '../baukasten/untertitel';
+import {plane} from './plan';
+import {PLATZ, WindGarten} from './teile';
+
+// Szene 7: Abendwind. Warmes Abendlicht, der Wind wird leise. Die drei sitzen im Gras, der Drachen liegt
+// daneben. Ruhiger Schluss: „Der Wind wird leise. Die Blätter liegen still. Pino gähnt.“
+
+export const S7 = plane('s7', [
+ {id: 'bild0', dauer: 2.6},
+ {id: 'n1', wer: 'NOA'},
+ {id: 'e1', wer: 'ERZ', pause: 3},
+ {id: 'e2', wer: 'ERZ'},
+ {id: 'e3', wer: 'ERZ', leise: true},
+ {id: 't1', wer: 'NOA_LULU', leise: true},
+ {id: 'p1', wer: 'PINO', leise: true},
+ {id: 'bild1', dauer: 2.2},
+]);
+
+export const Szene7: React.FC = () => {
+ const f = useCurrentFrame();
+ const {z, dauer} = S7;
+ // der Wind lässt nach: anfangs noch ein paar Blätter, ab „Der Wind wird leise“ fast still
+ const wind = f < z.e3.start ? 0.5 : Math.max(0.05, 0.5 - (f - z.e3.start) / 120);
+ const kam = kamFahrt(f, [
+ [0, 1150, 560, 1.0],
+ [z.bild0.ende, 1100, 640, 1.2],
+ [z.e3.start, 1000, 700, 1.35],
+ [dauer, 920, 760, 1.6],
+ ]);
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/remotion/src/folge09/teile.tsx b/remotion/src/folge09/teile.tsx
new file mode 100644
index 0000000..ea6db8f
--- /dev/null
+++ b/remotion/src/folge09/teile.tsx
@@ -0,0 +1,113 @@
+import React from 'react';
+import {random, useCurrentFrame} from 'remotion';
+import {ClipFigur, Figur, GROESSE, NOA_HOEHE} from '../baukasten/figur';
+import {Drachen, type DrachenLage, drachenHalt} from '../baukasten/drachen';
+import {Drachenschnur, spulenPunkt} from '../baukasten/drachenschnur';
+import {luluMaulC9, punkt} from '../baukasten/helfer';
+import {Blaetterwind} from '../baukasten/natur';
+import {BODEN, Ort} from '../baukasten/orte';
+
+// Bildteile für Folge 9 „Lulu und der Drachen“. Der Wind weht die ganze Folge von links nach rechts:
+// Blätter, Grashalme, Drachenschwanz und Lulus Schal (Clip lulu_C11_schal-wind) zeigen alle nach rechts.
+// Feste Plätze mitten auf der Wiese, weit weg vom Apfelbaum (links bei x ≈ 340).
+
+// Lulu steht links (windaufwärts), Noa rechts: Steigt der Drachen nach rechts (mit dem Wind), läuft die
+// Schnur von Noa nach rechts oben – nie an Lulus Hals vorbei. Pino ganz links am Boden.
+export const PLATZ = {noa: 1340, lulu: 1000, pino: 600};
+export const LULU_Y = BODEN - 6;
+// Lulu senkt den Hals (Clip C9) bis Clipbild 105: dann ist ihr Maul hier, knapp über dem Drachen im Gras
+const C9_TEMPO = 1.25;
+export const C9_START = 17;
+export const C9_UNTEN = 105;
+export const c9 = (bilder: number) => (bilder * 30) / 24 / C9_TEMPO;
+const MAUL_UNTEN = luluMaulC9(C9_UNTEN);
+export const DRACHEN_IM_GRAS = {x: punkt('lulu', PLATZ.lulu, LULU_Y, MAUL_UNTEN.cx, MAUL_UNTEN.cy).x, y: BODEN - 40};
+// In der Pose lulu_A_apfel hält Lulu den Apfel bei 574/193 (Leinwand) – dort hält sie jetzt den Drachen
+export const DRACHEN_IM_MAUL = punkt('lulu', PLATZ.lulu, LULU_Y, 574.5, 193);
+// In der Pose noa_A_haende-oben sind die Fäustlinge um 674/218 – der Drachen liegt dazwischen
+export const drachenUeberNoa = (noaX: number) => punkt('noa', noaX, BODEN, 674.5, 80); // über dem Kopf, nicht vor dem Gesicht
+
+// Windiger Herbstgarten: Blätter wehen nach rechts, Grashalme biegen sich im Takt der Böen
+export const WindGarten: React.FC<{abend?: boolean; wind?: number; boeen?: number}> = ({abend = false, wind = 1, boeen = 0}) => {
+ const f = useCurrentFrame();
+ const boe = 0.6 + 0.4 * Math.sin(f * 0.05) + boeen;
+ return (
+ <>
+
+ {wind > 0 && }
+
+ >
+ );
+};
+
+// Lulu im Wind: Clip mit wehendem Schal (Schleife), sonst eine Pose
+export const LuluImWind: React.FC<{pose?: string; stauchY?: number}> = ({pose, stauchY}) =>
+ pose ? (
+
+ ) : (
+
+ );
+
+// Drachen samt Schnur zu Noas Spule (Pose noa_A_drachenschnur). Schaut Noa nach links (spiegeln),
+// läuft die Schnur hinter ihr – deshalb vor ihr zeichnen lassen (vorNoa = false).
+export const SchnurUndDrachen: React.FC<{lage: DrachenLage; noaX: number; spiegeln: boolean; schnur?: boolean; flattern?: number; leuchten?: [number, number, number]}> = ({
+ lage,
+ noaX,
+ spiegeln,
+ schnur = true,
+ flattern,
+ leuchten,
+}) => {
+ const hoch = lage.y < BODEN - 160;
+ const schwanz = lage.liegt ? 0 : hoch ? 30 : 12;
+ return (
+ <>
+ {schnur && (
+
+ )}
+
+ >
+ );
+};
+
+// Lulu holt den Drachen aus dem Gras und hält ihn mit dem Maul hoch (wie den Apfel in Folge 1):
+// Hals runter (Clip C9 vorwärts), Drachen ins Maul, Hals hoch (Clip rückwärts), dann die Pose
+// lulu_A_apfel – der Drachen liegt genau über dem gemalten Apfel. Die Schnur hält immer Noa.
+export const hebenPlan = (start: number) => {
+ const unten = start + c9(C9_UNTEN - C9_START);
+ const hoch = unten + 10;
+ const oben = hoch + c9(C9_UNTEN);
+ return {start, unten, hoch, oben};
+};
+
+export const drachenBeiLulu = (f: number, plan: ReturnType): DrachenLage => {
+ if (f < plan.unten) return {x: DRACHEN_IM_GRAS.x, y: BODEN - 36, drehung: 90, liegt: true};
+ if (f >= plan.oben) return {x: DRACHEN_IM_MAUL.x, y: DRACHEN_IM_MAUL.y + 95, drehung: -15};
+ const bild = f < plan.hoch ? C9_UNTEN : C9_UNTEN - ((f - plan.hoch) * 1.25 * 24) / 30;
+ const m = luluMaulC9(bild);
+ const maul = punkt('lulu', PLATZ.lulu, LULU_Y, m.cx, m.cy);
+ // am Maul hängt der Drachen an seiner oberen Spitze, also unter dem Maul (nicht vor dem Gesicht)
+ return {x: maul.x, y: maul.y + 95, drehung: -15 * Math.min(1, Math.max(0, (f - plan.hoch) / 20))};
+};
+
+// `danach`: was Lulu nach dem Loslassen zeigt ('wind' = Schal-Clip) – nie die Apfel-Pose ohne Drachen!
+export const LuluHebt: React.FC<{plan: ReturnType; danach?: string}> = ({plan, danach}) => {
+ const f = useCurrentFrame();
+ if (f < plan.start) return ;
+ if (f < plan.hoch) return ;
+ if (f < plan.oben) return ;
+ if (danach === 'wind') return ;
+ return danach ? : ;
+};
diff --git a/remotion/src/folge09/texte/de.json b/remotion/src/folge09/texte/de.json
new file mode 100644
index 0000000..96f4395
--- /dev/null
+++ b/remotion/src/folge09/texte/de.json
@@ -0,0 +1,46 @@
+{
+ "titel": "Lulu und der Drachen",
+ "zeilen": {
+ "s2/n1": "Schaut mal! Mein Drachen aus Papier! Den hab ich selbst gebastelt.",
+ "s2/p1": "Ein Drachen? Kann der fliegen?",
+ "s2/n2": "Wenn der Wind ihn trägt.",
+ "s2/e1": "Der Drachen hat einen langen Schwanz mit Schleifen. Zählst du mit?",
+ "s2/z1": "Eins …",
+ "s2/z2": "zwei …",
+ "s2/z3": "drei!",
+ "s2/e2": "Drei Schleifen: gelb, grün und blau.",
+ "s3/n1": "Oh nein. Er will nicht fliegen.",
+ "s3/e1": "Schau mal Noa an. Wie fühlt sie sich jetzt?",
+ "s3/e2": "Noa ist traurig. Sie hat sich so gefreut. Und jetzt klappt es nicht. Das nennt man enttäuscht.",
+ "s3/p1": "Oh, Noa. Das ist schade. Komm, wir helfen dir!",
+ "s3/l1": "Hier oben weht ganz viel Wind! Meine Ohren flattern!",
+ "s3/e3": "Unten am Boden ist nur wenig Wind. Oben weht viel mehr. Puste mal ganz fest, wie der Wind!",
+ "s3/e4": "Huiii! Das war viel Wind!",
+ "s4/n1": "Lulu, kannst du den Drachen ganz hoch halten?",
+ "s4/l1": "Na klar! Ganz, ganz hoch!",
+ "s4/l2": "Hoppla! Er dreht sich im Kreis.",
+ "s4/n2": "Woher kommt der Wind denn bloß?",
+ "s4/e1": "Lulu ist ganz oben. Noa ist in der Mitte. Und wer ist ganz unten?",
+ "s4/e2": "Pino!",
+ "s5/p1": "Schaut mal! Die Blätter tanzen alle dahin! Der Wind kommt von da drüben!",
+ "s5/e1": "Pino ist ganz unten. Er sieht, was die Großen nicht sehen.",
+ "s5/e2": "Woran siehst du, dass es windig ist?",
+ "s5/e3": "Vielleicht hast du die Blätter gesehen. Oder die Bäume. Oder Lulus Schal. So sieht man den Wind.",
+ "s6/p1": "Noa, dreh dich um! Der Wind muss von hinten kommen.",
+ "s6/e1": "Noa dreht sich um. Jetzt pustet der Wind in ihren Rücken.",
+ "s6/n1": "Er fliegt! Er fliegt!",
+ "s6/p2": "Juhu!",
+ "s6/e2": "Schau mal Noa an. Sie ist stolz. Sie hat es nochmal probiert.",
+ "s6/e3": "Wer hat so einen langen Hals? Wer ist dem Drachen ganz nah?",
+ "s6/e4": "Lulu!",
+ "s6/l1": "Danke, Pino! Du hast den Wind gefunden.",
+ "s6/p3": "Und du hast den Drachen ganz hoch gehalten!",
+ "s6/e5": "Lulu sieht weit. Pino sieht nah. Und Noa hält die Schnur. Zusammen klappt es.",
+ "s7/n1": "Morgen fliegen wir wieder.",
+ "s7/e1": "Und du? Was möchtest du mal fliegen lassen?",
+ "s7/e2": "Vielleicht ein Blatt. Oder eine Feder.",
+ "s7/e3": "Der Wind wird leise. Die Blätter liegen still. Pino gähnt.",
+ "s7/t1": "Tschüss! Bis bald!",
+ "s7/p1": "Tschüss …"
+ }
+}
\ No newline at end of file
diff --git a/remotion/src/folge09/texte/es.json b/remotion/src/folge09/texte/es.json
new file mode 100644
index 0000000..fc43f38
--- /dev/null
+++ b/remotion/src/folge09/texte/es.json
@@ -0,0 +1,46 @@
+{
+ "titel": "Lulu y la cometa",
+ "zeilen": {
+ "s2/n1": "¡Mirad! ¡Mi cometa de papel! La he hecho yo sola.",
+ "s2/p1": "¿Una cometa? ¿Puede volar?",
+ "s2/n2": "Si el viento la lleva.",
+ "s2/e1": "La cometa tiene una cola larga con lazos. ¿Cuentas conmigo?",
+ "s2/z1": "Uno …",
+ "s2/z2": "dos …",
+ "s2/z3": "¡tres!",
+ "s2/e2": "Tres lazos: amarillo, verde y azul.",
+ "s3/n1": "Oh, no. No quiere volar.",
+ "s3/e1": "Mira a Noa. ¿Cómo se siente ahora?",
+ "s3/e2": "Noa está triste. Le hacía mucha ilusión. Y ahora no sale bien. Eso se llama estar desilusionada.",
+ "s3/p1": "Oh, Noa. ¡Qué pena! ¡Ven, te ayudamos!",
+ "s3/l1": "¡Aquí arriba sopla mucho viento! ¡Mis orejas se mueven!",
+ "s3/e3": "Abajo, en el suelo, hay poco viento. Arriba sopla mucho más. ¡Sopla muy fuerte, como el viento!",
+ "s3/e4": "¡Fuuuu! ¡Cuánto viento!",
+ "s4/n1": "Lulu, ¿puedes sujetar la cometa muy alto?",
+ "s4/l1": "¡Claro! ¡Muy, muy alto!",
+ "s4/l2": "¡Huy! Da vueltas y vueltas.",
+ "s4/n2": "¿De dónde viene el viento?",
+ "s4/e1": "Lulu está muy arriba. Noa está en el medio. ¿Y quién está muy abajo?",
+ "s4/e2": "¡Pino!",
+ "s5/p1": "¡Mirad! ¡Las hojas bailan todas hacia allá! ¡El viento viene de allí!",
+ "s5/e1": "Pino está muy abajo. Ve lo que los mayores no ven.",
+ "s5/e2": "¿Cómo sabes que hace viento?",
+ "s5/e3": "Quizás has visto las hojas. O los árboles. O la bufanda de Lulu. Así se ve el viento.",
+ "s6/p1": "¡Noa, date la vuelta! El viento tiene que venir por detrás.",
+ "s6/e1": "Noa se da la vuelta. Ahora el viento le sopla en la espalda.",
+ "s6/n1": "¡Vuela! ¡Vuela!",
+ "s6/p2": "¡Bieeen!",
+ "s6/e2": "Mira a Noa. Está orgullosa. Lo ha intentado otra vez.",
+ "s6/e3": "¿Quién tiene un cuello tan largo? ¿Quién está muy cerca de la cometa?",
+ "s6/e4": "¡Lulu!",
+ "s6/l1": "¡Gracias, Pino! Tú has encontrado el viento.",
+ "s6/p3": "¡Y tú has sujetado la cometa muy alto!",
+ "s6/e5": "Lulu ve lejos. Pino ve cerca. Y Noa sujeta el hilo. Juntos sale bien.",
+ "s7/n1": "Mañana la volamos otra vez.",
+ "s7/e1": "¿Y tú? ¿Qué te gustaría hacer volar?",
+ "s7/e2": "Quizás una hoja. O una pluma.",
+ "s7/e3": "El viento se calma. Las hojas se quedan quietas. Pino bosteza.",
+ "s7/t1": "¡Adiós! ¡Hasta pronto!",
+ "s7/p1": "Adiós …"
+ }
+}
\ No newline at end of file
diff --git a/remotion/src/folge09/texte/fr.json b/remotion/src/folge09/texte/fr.json
new file mode 100644
index 0000000..eda8ee8
--- /dev/null
+++ b/remotion/src/folge09/texte/fr.json
@@ -0,0 +1,46 @@
+{
+ "titel": "Lulu et le cerf-volant",
+ "zeilen": {
+ "s2/n1": "Regardez ! Mon cerf-volant en papier ! Je l’ai fabriqué toute seule.",
+ "s2/p1": "Un cerf-volant ? Il peut voler ?",
+ "s2/n2": "Si le vent le porte.",
+ "s2/e1": "Le cerf-volant a une longue queue avec des nœuds. Tu comptes avec moi ?",
+ "s2/z1": "Un …",
+ "s2/z2": "deux …",
+ "s2/z3": "trois !",
+ "s2/e2": "Trois nœuds : jaune, vert et bleu.",
+ "s3/n1": "Oh non. Il ne veut pas voler.",
+ "s3/e1": "Regarde Noa. Comment se sent-elle maintenant ?",
+ "s3/e2": "Noa est triste. Elle se réjouissait tellement. Et ça ne marche pas. On dit qu’elle est déçue.",
+ "s3/p1": "Oh, Noa. C’est dommage. Viens, on va t’aider !",
+ "s3/l1": "Ici en haut, il y a beaucoup de vent ! Mes oreilles flottent !",
+ "s3/e3": "En bas, par terre, il y a peu de vent. En haut, il y en a beaucoup plus. Souffle très fort, comme le vent !",
+ "s3/e4": "Fouuu ! Ça, c’était du vent !",
+ "s4/n1": "Lulu, tu peux tenir le cerf-volant tout en haut ?",
+ "s4/l1": "Bien sûr ! Tout, tout en haut !",
+ "s4/l2": "Oh là là ! Il tourne en rond.",
+ "s4/n2": "Mais d’où vient le vent ?",
+ "s4/e1": "Lulu est tout en haut. Noa est au milieu. Et qui est tout en bas ?",
+ "s4/e2": "Pino !",
+ "s5/p1": "Regardez ! Les feuilles dansent toutes par là ! Le vent vient de là-bas !",
+ "s5/e1": "Pino est tout en bas. Il voit ce que les grands ne voient pas.",
+ "s5/e2": "À quoi vois-tu qu’il y a du vent ?",
+ "s5/e3": "Peut-être que tu as vu les feuilles. Ou les arbres. Ou l’écharpe de Lulu. C’est comme ça qu’on voit le vent.",
+ "s6/p1": "Noa, retourne-toi ! Le vent doit venir de derrière.",
+ "s6/e1": "Noa se retourne. Maintenant, le vent souffle dans son dos.",
+ "s6/n1": "Il vole ! Il vole !",
+ "s6/p2": "Youpi !",
+ "s6/e2": "Regarde Noa. Elle est fière. Elle a réessayé.",
+ "s6/e3": "Qui a un cou si long ? Qui est tout près du cerf-volant ?",
+ "s6/e4": "Lulu !",
+ "s6/l1": "Merci, Pino ! C’est toi qui as trouvé le vent.",
+ "s6/p3": "Et toi, tu as tenu le cerf-volant tout en haut !",
+ "s6/e5": "Lulu voit loin. Pino voit de près. Et Noa tient la ficelle. Ensemble, ça marche.",
+ "s7/n1": "Demain, on le fait voler encore.",
+ "s7/e1": "Et toi ? Qu’est-ce que tu aimerais faire voler ?",
+ "s7/e2": "Peut-être une feuille. Ou une plume.",
+ "s7/e3": "Le vent se calme. Les feuilles ne bougent plus. Pino bâille.",
+ "s7/t1": "Au revoir ! À bientôt !",
+ "s7/p1": "Au revoir …"
+ }
+}
\ No newline at end of file