@devinilabs/reelstack 1.3.2 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2649 @@
1
+ /**
2
+ * REFERENCE — LilAgentsReel (Family: glass)
3
+ *
4
+ * Canonical example of the glass family's motion vocabulary, frame-locked
5
+ * BEAT structure, and scene choreography. Bundled with ReelStack v1.4+
6
+ * for STUDY and as the source for the scaffold-from-reference flow.
7
+ *
8
+ * Asset imports stripped (look for REFERENCE-STRIP markers). Bring your own
9
+ * voiceover, brand SVGs, captures.
10
+ *
11
+ * License: study + adapt patterns OK. Verbatim re-publication as your own
12
+ * template NOT OK. See ReelStack LICENSE.
13
+ *
14
+ * Source: my-video/src/LilAgentsReel.tsx
15
+ * Bundled at: 2026-05-12T19:40:04.823Z
16
+ */
17
+ import React from "react";
18
+ import {
19
+ AbsoluteFill,
20
+ OffthreadVideo,
21
+ Sequence,
22
+ interpolate,
23
+ spring,
24
+ staticFile,
25
+ useCurrentFrame,
26
+ useVideoConfig,
27
+ } from "remotion";
28
+ import {
29
+ C,
30
+ FONT,
31
+ MONO,
32
+ ease,
33
+ glassBase,
34
+ CausticBlobs,
35
+ HairlineGrid,
36
+ GlassCard,
37
+ EyebrowPill,
38
+ StaggeredWords,
39
+ Counter,
40
+ SonarRings,
41
+ ParticleBurst,
42
+ LightBeam,
43
+ FloatingGlyphs,
44
+ } from "./GraphifyReel";
45
+
46
+ // ═══════════════════════════════════════════════════════════════
47
+ // TIMING — 72s @ 30fps = 2160 frames, audio-locked from whisper SRT
48
+ // ═══════════════════════════════════════════════════════════════
49
+ export const LILAGENTS_TOTAL = 2160;
50
+
51
+ export const BEAT = {
52
+ hook: 0, // 0s — "tiny Claude agents walk on your dock"
53
+ dock: 164, // 5.48s — "actual little animator guys vibing"
54
+ name: 268, // 8.92s — "Lil Agents, by Ryan Stephen"
55
+ oss: 448, // 14.92s — "Open source MIT licensed"
56
+ chars: 541, // 18.04s — "Bruce and Jazz, stroll"
57
+ trans: 710, // 23.68s — "peaceful... but here's where it gets fun"
58
+ click: 836, // 27.88s — "click → terminal pops"
59
+ think: 1093, // 36.44s — "thought bubbles, sound on finish"
60
+ local: 1391, // 46.36s — "adorable. no signup. local"
61
+ alive: 1681, // 56.04s — "AI smarter. feel alive. buddy"
62
+ cta: 2016, // 67.20s — "like, subscribe, comment 'friend'"
63
+ end: 2160,
64
+ } as const;
65
+
66
+ // Lil Agents brand palette (from app themes: Peach, Midnight, Cloud, Moss)
67
+ const LA = {
68
+ peach: "#FFB088",
69
+ peachDeep: "#E89B6E",
70
+ midnight: "#3B3F8F",
71
+ cloud: "#A8C8E8",
72
+ moss: "#7DB87D",
73
+ bruce: "#E89BC4", // Bruce — pink/rose
74
+ jazz: "#7FE8D4", // Jazz — cyan
75
+ dockBg: "rgba(28,22,46,0.78)",
76
+ terminal: "#0F1116",
77
+ terminalText: "#A8FFD9",
78
+ } as const;
79
+
80
+ const SAFE_TOP = 290;
81
+
82
+ // ═══════════════════════════════════════════════════════════════
83
+ // EXTRA MOTION PRIMITIVES (Lil Agents specific)
84
+ // ═══════════════════════════════════════════════════════════════
85
+
86
+ // Floating thought bubble — rounded rectangle with tail
87
+ const ThoughtBubble: React.FC<{
88
+ x: number;
89
+ y: number;
90
+ text: string;
91
+ startFrame: number;
92
+ duration?: number;
93
+ color?: string;
94
+ scale?: number;
95
+ }> = ({ x, y, text, startFrame, duration = 90, color = C.iriCyan, scale = 1 }) => {
96
+ const frame = useCurrentFrame();
97
+ const local = frame - startFrame;
98
+ const op = interpolate(local, [0, 18, duration - 24, duration], [0, 1, 1, 0], {
99
+ extrapolateLeft: "clamp",
100
+ extrapolateRight: "clamp",
101
+ });
102
+ const popScale = spring({
103
+ frame: local,
104
+ fps: 30,
105
+ config: { damping: 10, stiffness: 140 },
106
+ from: 0.5,
107
+ to: 1,
108
+ });
109
+ const float = Math.sin((frame + startFrame) * 0.06) * 6;
110
+ if (local < 0 || local > duration) return null;
111
+ return (
112
+ <div
113
+ style={{
114
+ position: "absolute",
115
+ left: x,
116
+ top: y + float,
117
+ opacity: op,
118
+ transform: `scale(${popScale * scale})`,
119
+ transformOrigin: "left bottom",
120
+ willChange: "transform, opacity",
121
+ }}
122
+ >
123
+ <div
124
+ style={{
125
+ ...glassBase,
126
+ background: C.glassFillStrong,
127
+ borderRadius: 28,
128
+ padding: "14px 22px",
129
+ fontFamily: FONT,
130
+ fontSize: 26,
131
+ fontWeight: 600,
132
+ color: C.ink,
133
+ letterSpacing: "-0.015em",
134
+ whiteSpace: "nowrap",
135
+ boxShadow: [
136
+ "0 14px 32px -8px rgba(120,100,180,0.32)",
137
+ `0 0 24px ${color}55`,
138
+ "inset 0 1.5px 0 rgba(255,255,255,0.95)",
139
+ ].join(", "),
140
+ }}
141
+ >
142
+ {text}
143
+ </div>
144
+ {/* Tail dots */}
145
+ <div
146
+ style={{
147
+ position: "absolute",
148
+ left: 16,
149
+ top: "100%",
150
+ display: "flex",
151
+ flexDirection: "column",
152
+ gap: 4,
153
+ marginTop: 4,
154
+ }}
155
+ >
156
+ <div
157
+ style={{
158
+ width: 14,
159
+ height: 14,
160
+ borderRadius: "50%",
161
+ background: C.glassFillStrong,
162
+ border: `1.5px solid ${C.glassBorder}`,
163
+ backdropFilter: "blur(20px)",
164
+ boxShadow: `0 0 16px ${color}44`,
165
+ }}
166
+ />
167
+ <div
168
+ style={{
169
+ width: 8,
170
+ height: 8,
171
+ borderRadius: "50%",
172
+ background: C.glassFillStrong,
173
+ border: `1.5px solid ${C.glassBorder}`,
174
+ backdropFilter: "blur(20px)",
175
+ }}
176
+ />
177
+ </div>
178
+ </div>
179
+ );
180
+ };
181
+
182
+ // Walking character glyph — abstract pixel/blob silhouette
183
+ const WalkingGlyph: React.FC<{
184
+ color: string;
185
+ delay: number;
186
+ size?: number;
187
+ speed?: number;
188
+ trackWidth?: number;
189
+ }> = ({ color, delay, size = 70, speed = 0.5, trackWidth = 600 }) => {
190
+ const frame = useCurrentFrame();
191
+ const local = Math.max(0, frame - delay);
192
+ const t = local * speed * 0.02;
193
+ // Ping-pong walk
194
+ const xRaw = (Math.sin(t) + 1) / 2; // 0..1
195
+ const x = xRaw * trackWidth - trackWidth / 2;
196
+ const dir = Math.cos(t) > 0 ? 1 : -1;
197
+ const bob = Math.abs(Math.sin(t * 8)) * 4;
198
+ return (
199
+ <div
200
+ style={{
201
+ position: "absolute",
202
+ left: "50%",
203
+ top: 0,
204
+ transform: `translate(${x}px, ${-bob}px) scaleX(${dir})`,
205
+ width: size,
206
+ height: size * 1.2,
207
+ willChange: "transform",
208
+ }}
209
+ >
210
+ {/* Body */}
211
+ <div
212
+ style={{
213
+ position: "absolute",
214
+ inset: 0,
215
+ borderRadius: "50% 50% 38% 38%",
216
+ background: `linear-gradient(160deg, ${color} 0%, ${color}cc 100%)`,
217
+ boxShadow: [
218
+ `0 ${size * 0.18}px ${size * 0.3}px ${color}88`,
219
+ `inset 0 ${size * 0.06}px 0 rgba(255,255,255,0.4)`,
220
+ `inset 0 -${size * 0.04}px 0 rgba(0,0,0,0.18)`,
221
+ ].join(", "),
222
+ }}
223
+ />
224
+ {/* Eyes */}
225
+ <div
226
+ style={{
227
+ position: "absolute",
228
+ top: size * 0.32,
229
+ left: size * 0.22,
230
+ width: size * 0.14,
231
+ height: size * 0.14,
232
+ borderRadius: "50%",
233
+ background: "#0E0E12",
234
+ boxShadow: `0 0 0 ${size * 0.04}px rgba(255,255,255,0.85)`,
235
+ }}
236
+ />
237
+ <div
238
+ style={{
239
+ position: "absolute",
240
+ top: size * 0.32,
241
+ right: size * 0.22,
242
+ width: size * 0.14,
243
+ height: size * 0.14,
244
+ borderRadius: "50%",
245
+ background: "#0E0E12",
246
+ boxShadow: `0 0 0 ${size * 0.04}px rgba(255,255,255,0.85)`,
247
+ }}
248
+ />
249
+ {/* Cheek blush */}
250
+ <div
251
+ style={{
252
+ position: "absolute",
253
+ top: size * 0.55,
254
+ left: size * 0.12,
255
+ width: size * 0.16,
256
+ height: size * 0.08,
257
+ borderRadius: "50%",
258
+ background: "rgba(255,150,150,0.4)",
259
+ filter: "blur(2px)",
260
+ }}
261
+ />
262
+ </div>
263
+ );
264
+ };
265
+
266
+ // Mac dock — glass shelf with app icons
267
+ const MacDock: React.FC<{
268
+ startFrame: number;
269
+ showCharacters?: boolean;
270
+ }> = ({ startFrame, showCharacters = true }) => {
271
+ const frame = useCurrentFrame();
272
+ const local = frame - startFrame;
273
+ const dockY = interpolate(local, [0, 36], [120, 0], {
274
+ extrapolateLeft: "clamp",
275
+ extrapolateRight: "clamp",
276
+ easing: ease.expoOut,
277
+ });
278
+ const dockOp = interpolate(local, [0, 24], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
279
+
280
+ const icons = [
281
+ { color: "#5A87FF", radius: 16 }, // safari blue
282
+ { color: "#FF7A5C", radius: 16 }, // mail orange
283
+ { color: "#34C759", radius: 16 }, // messages green
284
+ { color: "#FFB800", radius: 16 }, // notes yellow
285
+ { color: "#A855F7", radius: 16 }, // music purple
286
+ { color: "#FF3B30", radius: 16 }, // photos red
287
+ { color: "#1F2937", radius: 16 }, // terminal dark
288
+ { color: LA.peach, radius: 16 }, // lil-agents
289
+ ];
290
+
291
+ return (
292
+ <div
293
+ style={{
294
+ position: "absolute",
295
+ left: 0,
296
+ right: 0,
297
+ bottom: 360,
298
+ display: "flex",
299
+ justifyContent: "center",
300
+ opacity: dockOp,
301
+ transform: `translateY(${dockY}px)`,
302
+ willChange: "transform, opacity",
303
+ }}
304
+ >
305
+ {/* Walking characters track — sits ABOVE the dock */}
306
+ {showCharacters && (
307
+ <div
308
+ style={{
309
+ position: "absolute",
310
+ left: 0,
311
+ right: 0,
312
+ bottom: 130,
313
+ height: 90,
314
+ display: "flex",
315
+ justifyContent: "center",
316
+ pointerEvents: "none",
317
+ }}
318
+ >
319
+ <div style={{ position: "relative", width: 800, height: 90 }}>
320
+ <WalkingGlyph color={LA.bruce} delay={startFrame + 12} size={66} speed={0.4} trackWidth={520} />
321
+ <WalkingGlyph color={LA.jazz} delay={startFrame + 26} size={66} speed={0.55} trackWidth={520} />
322
+ </div>
323
+ </div>
324
+ )}
325
+
326
+ {/* Dock shelf */}
327
+ <div
328
+ style={{
329
+ ...glassBase,
330
+ background: LA.dockBg,
331
+ backdropFilter: "blur(28px) saturate(160%)",
332
+ WebkitBackdropFilter: "blur(28px) saturate(160%)",
333
+ borderRadius: 32,
334
+ padding: "16px 22px",
335
+ display: "flex",
336
+ alignItems: "center",
337
+ gap: 14,
338
+ border: "1.5px solid rgba(255,255,255,0.12)",
339
+ boxShadow: [
340
+ "0 30px 60px -15px rgba(20,15,40,0.55)",
341
+ "inset 0 1.5px 0 rgba(255,255,255,0.18)",
342
+ "inset 0 -1px 0 rgba(0,0,0,0.3)",
343
+ ].join(", "),
344
+ }}
345
+ >
346
+ {icons.map((ic, i) => {
347
+ const popLocal = local - 16 - i * 4;
348
+ const popScale = spring({
349
+ frame: popLocal,
350
+ fps: 30,
351
+ config: { damping: 11, stiffness: 140 },
352
+ from: 0.5,
353
+ to: 1,
354
+ });
355
+ // Last icon pulses (lil-agents)
356
+ const pulse = i === 7 ? 1 + Math.sin(frame * 0.12) * 0.06 : 1;
357
+ return (
358
+ <div
359
+ key={i}
360
+ style={{
361
+ width: 64,
362
+ height: 64,
363
+ borderRadius: ic.radius,
364
+ background: ic.color,
365
+ transform: `scale(${popScale * pulse})`,
366
+ boxShadow: i === 7 ? `0 0 24px ${ic.color}` : "0 6px 12px rgba(0,0,0,0.35)",
367
+ position: "relative",
368
+ }}
369
+ >
370
+ {i === 7 && (
371
+ <div
372
+ style={{
373
+ position: "absolute",
374
+ inset: 6,
375
+ borderRadius: 12,
376
+ background: "rgba(255,255,255,0.35)",
377
+ border: "1px solid rgba(255,255,255,0.5)",
378
+ }}
379
+ />
380
+ )}
381
+ </div>
382
+ );
383
+ })}
384
+ </div>
385
+ </div>
386
+ );
387
+ };
388
+
389
+ // Sound wave — radiating arcs from a point
390
+ const SoundWaves: React.FC<{ startFrame: number; cx?: number; cy?: number }> = ({
391
+ startFrame,
392
+ cx = 540,
393
+ cy = 960,
394
+ }) => {
395
+ const frame = useCurrentFrame();
396
+ const arcs = [0, 16, 32];
397
+ return (
398
+ <svg
399
+ width={1080}
400
+ height={1920}
401
+ style={{ position: "absolute", inset: 0, pointerEvents: "none" }}
402
+ >
403
+ {arcs.map((delay, i) => {
404
+ const local = frame - startFrame - delay;
405
+ const cycle = local % 70;
406
+ if (local < 0) return null;
407
+ const r = interpolate(cycle, [0, 70], [40, 220], {
408
+ extrapolateLeft: "clamp",
409
+ extrapolateRight: "clamp",
410
+ easing: ease.expoOut,
411
+ });
412
+ const op = interpolate(cycle, [0, 20, 70], [0, 0.7, 0], {
413
+ extrapolateLeft: "clamp",
414
+ extrapolateRight: "clamp",
415
+ });
416
+ return (
417
+ <g key={i}>
418
+ <path
419
+ d={`M ${cx + r} ${cy} A ${r} ${r} 0 0 1 ${cx} ${cy + r}`}
420
+ fill="none"
421
+ stroke={i % 2 === 0 ? C.iriViolet : C.iriCyan}
422
+ strokeWidth={3}
423
+ strokeLinecap="round"
424
+ opacity={op}
425
+ />
426
+ <path
427
+ d={`M ${cx - r} ${cy} A ${r} ${r} 0 0 0 ${cx} ${cy + r}`}
428
+ fill="none"
429
+ stroke={i % 2 === 0 ? C.iriViolet : C.iriCyan}
430
+ strokeWidth={3}
431
+ strokeLinecap="round"
432
+ opacity={op}
433
+ />
434
+ <path
435
+ d={`M ${cx + r} ${cy} A ${r} ${r} 0 0 0 ${cx} ${cy - r}`}
436
+ fill="none"
437
+ stroke={i % 2 === 0 ? C.iriRose : C.iriGold}
438
+ strokeWidth={3}
439
+ strokeLinecap="round"
440
+ opacity={op}
441
+ />
442
+ <path
443
+ d={`M ${cx - r} ${cy} A ${r} ${r} 0 0 1 ${cx} ${cy - r}`}
444
+ fill="none"
445
+ stroke={i % 2 === 0 ? C.iriRose : C.iriGold}
446
+ strokeWidth={3}
447
+ strokeLinecap="round"
448
+ opacity={op}
449
+ />
450
+ </g>
451
+ );
452
+ })}
453
+ </svg>
454
+ );
455
+ };
456
+
457
+ // ═══════════════════════════════════════════════════════════════
458
+ // SCENE 1 — HOOK (0-164, 5.48s)
459
+ // "Ok, someone just made tiny Claude agents that walk around on your mac dock."
460
+ // ═══════════════════════════════════════════════════════════════
461
+ const HookScene: React.FC = () => {
462
+ const frame = useCurrentFrame();
463
+
464
+ const cardScale = spring({
465
+ frame: frame - 8,
466
+ fps: 30,
467
+ config: { damping: 13, stiffness: 120 },
468
+ from: 0.6,
469
+ to: 1,
470
+ });
471
+ const cardOp = interpolate(frame, [8, 32], [0, 1], { extrapolateRight: "clamp" });
472
+
473
+ const ringAngle = (frame * 1.4) % 360;
474
+
475
+ return (
476
+ <AbsoluteFill>
477
+ {/* Motion-art layer 1: sonar rings */}
478
+ <SonarRings />
479
+
480
+ {/* Motion-art layer 2: light beams */}
481
+ <LightBeam delay={0} angle={-18} />
482
+ <LightBeam delay={28} angle={22} />
483
+ <LightBeam delay={62} angle={-12} />
484
+
485
+ {/* Motion-art layer 3: floating glass glyphs */}
486
+ <FloatingGlyphs />
487
+
488
+ {/* Motion-art layer 4: particle burst */}
489
+ <ParticleBurst />
490
+
491
+ {/* Eyebrow */}
492
+ <div
493
+ style={{
494
+ position: "absolute",
495
+ top: SAFE_TOP + 24,
496
+ left: 0,
497
+ right: 0,
498
+ display: "flex",
499
+ justifyContent: "center",
500
+ opacity: interpolate(frame, [4, 24], [0, 1], { extrapolateRight: "clamp" }),
501
+ transform: `translateY(${interpolate(frame, [4, 24], [16, 0], {
502
+ extrapolateRight: "clamp",
503
+ easing: ease.power3Out,
504
+ })}px)`,
505
+ }}
506
+ >
507
+ <EyebrowPill>01 — meet your dock buddies</EyebrowPill>
508
+ </div>
509
+
510
+ {/* Lilagent-1 video card — anchored upper, glassy with iridescent ring */}
511
+ <div
512
+ style={{
513
+ position: "absolute",
514
+ left: "50%",
515
+ top: 460,
516
+ transform: `translateX(-50%) scale(${cardScale})`,
517
+ opacity: cardOp,
518
+ willChange: "transform, opacity",
519
+ }}
520
+ >
521
+ <div
522
+ style={{
523
+ position: "relative",
524
+ width: 720,
525
+ height: 720,
526
+ }}
527
+ >
528
+ {/* Conic iridescent halo */}
529
+ <div
530
+ style={{
531
+ position: "absolute",
532
+ inset: -80,
533
+ borderRadius: 60,
534
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
535
+ filter: "blur(50px)",
536
+ opacity: 0.55,
537
+ }}
538
+ />
539
+ {/* Outer ring pad */}
540
+ <div
541
+ style={{
542
+ position: "absolute",
543
+ inset: -6,
544
+ borderRadius: 46,
545
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
546
+ padding: 6,
547
+ }}
548
+ >
549
+ <div
550
+ style={{
551
+ width: "100%",
552
+ height: "100%",
553
+ borderRadius: 40,
554
+ background: C.bg,
555
+ }}
556
+ />
557
+ </div>
558
+ {/* Glass card frame */}
559
+ <div
560
+ style={{
561
+ ...glassBase,
562
+ position: "absolute",
563
+ inset: 0,
564
+ borderRadius: 40,
565
+ overflow: "hidden",
566
+ }}
567
+ >
568
+ {/* REFERENCE-STRIP: <OffthreadVideo> removed — bring your own clip */}
569
+ {/* Inner highlight */}
570
+ <div
571
+ style={{
572
+ position: "absolute",
573
+ inset: 0,
574
+ borderRadius: 40,
575
+ boxShadow: "inset 0 2px 0 rgba(255,255,255,0.7), inset 0 -1px 0 rgba(255,255,255,0.2)",
576
+ pointerEvents: "none",
577
+ }}
578
+ />
579
+ </div>
580
+ </div>
581
+ </div>
582
+
583
+ {/* Hero copy — bottom band, well below video card (video bottom ≈ 1180, text starts ≈ 1280) */}
584
+ <div
585
+ style={{
586
+ position: "absolute",
587
+ left: 0,
588
+ right: 0,
589
+ top: 1280,
590
+ padding: "0 56px",
591
+ }}
592
+ >
593
+ <StaggeredWords
594
+ text="tiny Claude agents"
595
+ startFrame={28}
596
+ perWordDelay={4}
597
+ fontSize={72}
598
+ fontWeight={500}
599
+ color={C.inkMuted}
600
+ align="center"
601
+ letterSpacing="-0.025em"
602
+ />
603
+ <div style={{ height: 6 }} />
604
+ <StaggeredWords
605
+ text="walk on your dock"
606
+ startFrame={50}
607
+ perWordDelay={3}
608
+ fontSize={92}
609
+ fontWeight={800}
610
+ color={C.ink}
611
+ align="center"
612
+ letterSpacing="-0.045em"
613
+ lineHeight={1}
614
+ highlight="walk"
615
+ highlightColor={C.iriViolet}
616
+ />
617
+ {/* Iridescent divider accent */}
618
+ <div
619
+ style={{
620
+ margin: "24px auto 0",
621
+ width: 200,
622
+ height: 4,
623
+ borderRadius: 999,
624
+ background: `linear-gradient(90deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose})`,
625
+ opacity: interpolate(frame, [80, 110], [0, 1], { extrapolateRight: "clamp" }),
626
+ transform: `scaleX(${interpolate(frame, [80, 120], [0, 1], {
627
+ extrapolateRight: "clamp",
628
+ easing: ease.expoOut,
629
+ })})`,
630
+ boxShadow: `0 0 24px ${C.iriViolet}66`,
631
+ }}
632
+ />
633
+ </div>
634
+ </AbsoluteFill>
635
+ );
636
+ };
637
+
638
+ // ═══════════════════════════════════════════════════════════════
639
+ // SCENE 2 — DOCK (164-268, 3.48s)
640
+ // "Like actual little animator guys just vibing up there all day."
641
+ // ═══════════════════════════════════════════════════════════════
642
+ const DockScene: React.FC = () => {
643
+ const frame = useCurrentFrame();
644
+ const local = frame - BEAT.dock;
645
+
646
+ const titleScale = spring({
647
+ frame: local - 4,
648
+ fps: 30,
649
+ config: { damping: 11, stiffness: 130 },
650
+ from: 0.7,
651
+ to: 1,
652
+ });
653
+
654
+ return (
655
+ <AbsoluteFill>
656
+ <FloatingGlyphs />
657
+
658
+ {/* Eyebrow */}
659
+ <div
660
+ style={{
661
+ position: "absolute",
662
+ top: SAFE_TOP + 24,
663
+ left: 0,
664
+ right: 0,
665
+ display: "flex",
666
+ justifyContent: "center",
667
+ opacity: interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" }),
668
+ }}
669
+ >
670
+ <EyebrowPill>02 — they just vibe</EyebrowPill>
671
+ </div>
672
+
673
+ {/* Big "VIBING" label */}
674
+ <div
675
+ style={{
676
+ position: "absolute",
677
+ left: 0,
678
+ right: 0,
679
+ top: SAFE_TOP + 130,
680
+ textAlign: "center",
681
+ opacity: interpolate(local, [4, 28], [0, 1], { extrapolateRight: "clamp" }),
682
+ transform: `scale(${titleScale})`,
683
+ willChange: "transform, opacity",
684
+ }}
685
+ >
686
+ <div
687
+ style={{
688
+ fontFamily: FONT,
689
+ fontSize: 56,
690
+ fontWeight: 500,
691
+ color: C.inkMuted,
692
+ letterSpacing: "-0.02em",
693
+ marginBottom: 8,
694
+ }}
695
+ >
696
+ they're just up there
697
+ </div>
698
+ <div
699
+ style={{
700
+ fontFamily: FONT,
701
+ fontSize: 184,
702
+ fontWeight: 800,
703
+ color: C.ink,
704
+ letterSpacing: "-0.06em",
705
+ lineHeight: 0.92,
706
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose})`,
707
+ WebkitBackgroundClip: "text",
708
+ WebkitTextFillColor: "transparent",
709
+ backgroundClip: "text",
710
+ }}
711
+ >
712
+ vibing.
713
+ </div>
714
+ </div>
715
+
716
+ {/* Mac dock with characters */}
717
+ <MacDock startFrame={BEAT.dock + 6} showCharacters />
718
+
719
+ {/* Ambient floating glyphs */}
720
+ <ThoughtBubble
721
+ x={140}
722
+ y={1180}
723
+ text="oh hi there"
724
+ startFrame={BEAT.dock + 30}
725
+ duration={70}
726
+ color={LA.bruce}
727
+ />
728
+ <ThoughtBubble
729
+ x={700}
730
+ y={1240}
731
+ text="just chillin'"
732
+ startFrame={BEAT.dock + 50}
733
+ duration={60}
734
+ color={LA.jazz}
735
+ />
736
+ </AbsoluteFill>
737
+ );
738
+ };
739
+
740
+ // ═══════════════════════════════════════════════════════════════
741
+ // SCENE 3 — NAME REVEAL (268-448, 6s)
742
+ // "It's a free app called Lil Agents, built by a developer named Ryan Stephen."
743
+ // ═══════════════════════════════════════════════════════════════
744
+ const NameScene: React.FC = () => {
745
+ const frame = useCurrentFrame();
746
+ const local = frame - BEAT.name;
747
+ const ringAngle = (frame * 0.7) % 360;
748
+
749
+ const titleScale = spring({
750
+ frame: local - 8,
751
+ fps: 30,
752
+ config: { damping: 14, stiffness: 110 },
753
+ from: 0.85,
754
+ to: 1,
755
+ });
756
+
757
+ const cardOp = interpolate(local, [60, 90], [0, 1], { extrapolateRight: "clamp" });
758
+ const cardY = interpolate(local, [60, 100], [40, 0], {
759
+ extrapolateRight: "clamp",
760
+ easing: ease.power3Out,
761
+ });
762
+
763
+ return (
764
+ <AbsoluteFill>
765
+ <FloatingGlyphs />
766
+
767
+ {/* Eyebrow */}
768
+ <div
769
+ style={{
770
+ position: "absolute",
771
+ top: SAFE_TOP + 24,
772
+ left: 0,
773
+ right: 0,
774
+ display: "flex",
775
+ justifyContent: "center",
776
+ opacity: interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" }),
777
+ }}
778
+ >
779
+ <EyebrowPill>03 — what it is</EyebrowPill>
780
+ </div>
781
+
782
+ {/* Hero title with iridescent halo */}
783
+ <AbsoluteFill style={{ alignItems: "center", justifyContent: "flex-start", paddingTop: 460 }}>
784
+ <div
785
+ style={{
786
+ position: "relative",
787
+ opacity: interpolate(local, [8, 30], [0, 1], { extrapolateRight: "clamp" }),
788
+ transform: `scale(${titleScale})`,
789
+ willChange: "transform, opacity",
790
+ textAlign: "center",
791
+ }}
792
+ >
793
+ {/* Conic halo */}
794
+ <div
795
+ style={{
796
+ position: "absolute",
797
+ left: "50%",
798
+ top: "50%",
799
+ width: 760,
800
+ height: 760,
801
+ transform: "translate(-50%, -50%)",
802
+ borderRadius: "50%",
803
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
804
+ filter: "blur(80px)",
805
+ opacity: 0.5,
806
+ }}
807
+ />
808
+ <div
809
+ style={{
810
+ position: "relative",
811
+ fontFamily: FONT,
812
+ fontSize: 56,
813
+ fontWeight: 500,
814
+ color: C.inkMuted,
815
+ letterSpacing: "-0.02em",
816
+ marginBottom: 10,
817
+ }}
818
+ >
819
+ it's called
820
+ </div>
821
+ <div
822
+ style={{
823
+ position: "relative",
824
+ fontFamily: FONT,
825
+ fontSize: 232,
826
+ fontWeight: 800,
827
+ color: C.ink,
828
+ letterSpacing: "-0.075em",
829
+ lineHeight: 0.88,
830
+ }}
831
+ >
832
+ lil
833
+ </div>
834
+ <div
835
+ style={{
836
+ position: "relative",
837
+ fontFamily: FONT,
838
+ fontSize: 232,
839
+ fontWeight: 800,
840
+ letterSpacing: "-0.075em",
841
+ lineHeight: 0.88,
842
+ background: `linear-gradient(135deg, ${C.iriCyan} 0%, ${C.iriViolet} 50%, ${C.iriRose} 100%)`,
843
+ WebkitBackgroundClip: "text",
844
+ WebkitTextFillColor: "transparent",
845
+ backgroundClip: "text",
846
+ }}
847
+ >
848
+ agents.
849
+ </div>
850
+ </div>
851
+
852
+ {/* Tagline */}
853
+ <div
854
+ style={{
855
+ marginTop: 28,
856
+ fontFamily: MONO,
857
+ fontSize: 22,
858
+ color: C.inkMuted,
859
+ letterSpacing: "0.18em",
860
+ textTransform: "uppercase",
861
+ opacity: interpolate(local, [40, 70], [0, 1], { extrapolateRight: "clamp" }),
862
+ }}
863
+ >
864
+ tiny ai companions for your dock
865
+ </div>
866
+ </AbsoluteFill>
867
+
868
+ {/* Maker card — Ryan Stephen */}
869
+ <div
870
+ style={{
871
+ position: "absolute",
872
+ left: 80,
873
+ right: 80,
874
+ bottom: 360,
875
+ opacity: cardOp,
876
+ transform: `translateY(${cardY}px)`,
877
+ willChange: "transform, opacity",
878
+ }}
879
+ >
880
+ <GlassCard radius={32} style={{ padding: 32 }}>
881
+ <div style={{ display: "flex", alignItems: "center", gap: 22 }}>
882
+ {/* Avatar disc */}
883
+ <div
884
+ style={{
885
+ width: 84,
886
+ height: 84,
887
+ borderRadius: 24,
888
+ background: `linear-gradient(145deg, ${LA.peach}, ${LA.peachDeep})`,
889
+ display: "flex",
890
+ alignItems: "center",
891
+ justifyContent: "center",
892
+ fontFamily: FONT,
893
+ fontSize: 38,
894
+ fontWeight: 800,
895
+ color: "white",
896
+ letterSpacing: "-0.04em",
897
+ boxShadow: [
898
+ `0 12px 24px -8px ${LA.peachDeep}88`,
899
+ "inset 0 1.5px 0 rgba(255,255,255,0.6)",
900
+ ].join(", "),
901
+ }}
902
+ >
903
+ R
904
+ </div>
905
+ <div style={{ display: "flex", flexDirection: "column", flex: 1 }}>
906
+ <div
907
+ style={{
908
+ fontFamily: MONO,
909
+ fontSize: 16,
910
+ color: C.inkDim,
911
+ letterSpacing: "0.18em",
912
+ textTransform: "uppercase",
913
+ }}
914
+ >
915
+ built by
916
+ </div>
917
+ <div
918
+ style={{
919
+ fontFamily: FONT,
920
+ fontSize: 52,
921
+ fontWeight: 700,
922
+ color: C.ink,
923
+ letterSpacing: "-0.035em",
924
+ lineHeight: 1,
925
+ marginTop: 4,
926
+ }}
927
+ >
928
+ Ryan Stephen
929
+ </div>
930
+ </div>
931
+ {/* GitHub mark */}
932
+ <div
933
+ style={{
934
+ width: 64,
935
+ height: 64,
936
+ borderRadius: 18,
937
+ background: "#0E0E12",
938
+ display: "flex",
939
+ alignItems: "center",
940
+ justifyContent: "center",
941
+ }}
942
+ >
943
+ <svg width="36" height="36" viewBox="0 0 24 24" fill="white">
944
+ <path d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1.1-.7.1-.7.1-.7 1.2.1 1.9 1.2 1.9 1.2 1.1 1.9 2.9 1.4 3.6 1 .1-.8.4-1.4.8-1.7-2.7-.3-5.5-1.3-5.5-6 0-1.3.5-2.4 1.2-3.2-.1-.3-.5-1.5.1-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0c2.3-1.5 3.3-1.2 3.3-1.2.7 1.7.2 2.9.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.4.4.8 1.1.8 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .3" />
945
+ </svg>
946
+ </div>
947
+ </div>
948
+ </GlassCard>
949
+ </div>
950
+ </AbsoluteFill>
951
+ );
952
+ };
953
+
954
+ // ═══════════════════════════════════════════════════════════════
955
+ // SCENE 4 — OPEN SOURCE (448-541, 3.1s)
956
+ // "Open source MIT licensed the whole thing."
957
+ // ═══════════════════════════════════════════════════════════════
958
+ const OSSScene: React.FC = () => {
959
+ const frame = useCurrentFrame();
960
+ const local = frame - BEAT.oss;
961
+
962
+ const badges = [
963
+ { label: "OPEN SOURCE", color: C.iriCyan, accent: "MIT" },
964
+ { label: "MIT LICENSE", color: C.iriViolet, accent: "free" },
965
+ { label: "macOS NATIVE", color: C.iriRose, accent: "swift" },
966
+ ];
967
+
968
+ return (
969
+ <AbsoluteFill>
970
+ <FloatingGlyphs />
971
+
972
+ {/* Eyebrow */}
973
+ <div
974
+ style={{
975
+ position: "absolute",
976
+ top: SAFE_TOP + 24,
977
+ left: 0,
978
+ right: 0,
979
+ display: "flex",
980
+ justifyContent: "center",
981
+ opacity: interpolate(local, [0, 16], [0, 1], { extrapolateRight: "clamp" }),
982
+ }}
983
+ >
984
+ <EyebrowPill>04 — fully open</EyebrowPill>
985
+ </div>
986
+
987
+ {/* Big number — "$0" or "FREE" */}
988
+ <div
989
+ style={{
990
+ position: "absolute",
991
+ left: 0,
992
+ right: 0,
993
+ top: SAFE_TOP + 120,
994
+ textAlign: "center",
995
+ opacity: interpolate(local, [4, 24], [0, 1], { extrapolateRight: "clamp" }),
996
+ transform: `scale(${spring({
997
+ frame: local - 4,
998
+ fps: 30,
999
+ config: { damping: 11, stiffness: 130 },
1000
+ from: 0.8,
1001
+ to: 1,
1002
+ })})`,
1003
+ }}
1004
+ >
1005
+ <div
1006
+ style={{
1007
+ fontFamily: FONT,
1008
+ fontSize: 224,
1009
+ fontWeight: 800,
1010
+ color: C.ink,
1011
+ letterSpacing: "-0.07em",
1012
+ lineHeight: 1,
1013
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriGold})`,
1014
+ WebkitBackgroundClip: "text",
1015
+ WebkitTextFillColor: "transparent",
1016
+ backgroundClip: "text",
1017
+ }}
1018
+ >
1019
+ $0
1020
+ </div>
1021
+ <div
1022
+ style={{
1023
+ fontFamily: MONO,
1024
+ fontSize: 24,
1025
+ color: C.inkMuted,
1026
+ letterSpacing: "0.22em",
1027
+ textTransform: "uppercase",
1028
+ marginTop: 8,
1029
+ }}
1030
+ >
1031
+ forever, no catch
1032
+ </div>
1033
+ </div>
1034
+
1035
+ {/* Three badges */}
1036
+ <div
1037
+ style={{
1038
+ position: "absolute",
1039
+ left: 80,
1040
+ right: 80,
1041
+ top: 1180,
1042
+ display: "flex",
1043
+ flexDirection: "column",
1044
+ gap: 18,
1045
+ }}
1046
+ >
1047
+ {badges.map((b, i) => {
1048
+ const start = local - 32 - i * 8;
1049
+ const op = interpolate(start, [0, 18], [0, 1], {
1050
+ extrapolateLeft: "clamp",
1051
+ extrapolateRight: "clamp",
1052
+ });
1053
+ const x = interpolate(start, [0, 18], [-30, 0], {
1054
+ extrapolateLeft: "clamp",
1055
+ extrapolateRight: "clamp",
1056
+ easing: ease.power3Out,
1057
+ });
1058
+ return (
1059
+ <div
1060
+ key={i}
1061
+ style={{
1062
+ ...glassBase,
1063
+ borderRadius: 22,
1064
+ padding: "20px 28px",
1065
+ display: "flex",
1066
+ alignItems: "center",
1067
+ gap: 18,
1068
+ opacity: op,
1069
+ transform: `translateX(${x}px)`,
1070
+ willChange: "transform, opacity",
1071
+ }}
1072
+ >
1073
+ {/* Color dot */}
1074
+ <div
1075
+ style={{
1076
+ width: 14,
1077
+ height: 14,
1078
+ borderRadius: "50%",
1079
+ background: b.color,
1080
+ boxShadow: `0 0 16px ${b.color}`,
1081
+ }}
1082
+ />
1083
+ <div
1084
+ style={{
1085
+ fontFamily: FONT,
1086
+ fontSize: 32,
1087
+ fontWeight: 700,
1088
+ color: C.ink,
1089
+ letterSpacing: "-0.025em",
1090
+ flex: 1,
1091
+ }}
1092
+ >
1093
+ {b.label}
1094
+ </div>
1095
+ <div
1096
+ style={{
1097
+ fontFamily: MONO,
1098
+ fontSize: 16,
1099
+ color: C.inkDim,
1100
+ letterSpacing: "0.18em",
1101
+ textTransform: "uppercase",
1102
+ }}
1103
+ >
1104
+ {b.accent}
1105
+ </div>
1106
+ </div>
1107
+ );
1108
+ })}
1109
+ </div>
1110
+ </AbsoluteFill>
1111
+ );
1112
+ };
1113
+
1114
+ // ═══════════════════════════════════════════════════════════════
1115
+ // SCENE 5 — CHARACTERS (541-710, 5.6s)
1116
+ // "You get two characters, Bruce and Jazz. They stroll back and forth above your dock."
1117
+ // ═══════════════════════════════════════════════════════════════
1118
+ const CharactersScene: React.FC = () => {
1119
+ const frame = useCurrentFrame();
1120
+ const local = frame - BEAT.chars;
1121
+
1122
+ const headerOp = interpolate(local, [0, 22], [0, 1], { extrapolateRight: "clamp" });
1123
+
1124
+ const bruceCardScale = spring({
1125
+ frame: local - 18,
1126
+ fps: 30,
1127
+ config: { damping: 12, stiffness: 130 },
1128
+ from: 0.7,
1129
+ to: 1,
1130
+ });
1131
+ const jazzCardScale = spring({
1132
+ frame: local - 32,
1133
+ fps: 30,
1134
+ config: { damping: 12, stiffness: 130 },
1135
+ from: 0.7,
1136
+ to: 1,
1137
+ });
1138
+
1139
+ const videoCardOp = interpolate(local, [40, 70], [0, 1], { extrapolateRight: "clamp" });
1140
+ const videoCardY = interpolate(local, [40, 80], [40, 0], {
1141
+ extrapolateRight: "clamp",
1142
+ easing: ease.power3Out,
1143
+ });
1144
+
1145
+ return (
1146
+ <AbsoluteFill>
1147
+ <FloatingGlyphs />
1148
+
1149
+ {/* Eyebrow */}
1150
+ <div
1151
+ style={{
1152
+ position: "absolute",
1153
+ top: SAFE_TOP + 24,
1154
+ left: 0,
1155
+ right: 0,
1156
+ display: "flex",
1157
+ justifyContent: "center",
1158
+ opacity: headerOp,
1159
+ }}
1160
+ >
1161
+ <EyebrowPill>05 — the cast</EyebrowPill>
1162
+ </div>
1163
+
1164
+ {/* Two character pills side-by-side */}
1165
+ <div
1166
+ style={{
1167
+ position: "absolute",
1168
+ left: 60,
1169
+ right: 60,
1170
+ top: SAFE_TOP + 100,
1171
+ display: "flex",
1172
+ gap: 24,
1173
+ }}
1174
+ >
1175
+ {/* Bruce */}
1176
+ <div
1177
+ style={{
1178
+ flex: 1,
1179
+ transform: `scale(${bruceCardScale})`,
1180
+ opacity: interpolate(local, [18, 36], [0, 1], { extrapolateRight: "clamp" }),
1181
+ willChange: "transform, opacity",
1182
+ }}
1183
+ >
1184
+ <GlassCard radius={28} style={{ padding: 24, position: "relative", overflow: "hidden" }}>
1185
+ {/* Glow background */}
1186
+ <div
1187
+ style={{
1188
+ position: "absolute",
1189
+ inset: 0,
1190
+ background: `radial-gradient(circle at 50% 30%, ${LA.bruce}55 0%, transparent 60%)`,
1191
+ pointerEvents: "none",
1192
+ }}
1193
+ />
1194
+ <div style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center" }}>
1195
+ <div style={{ position: "relative", width: 140, height: 168, marginBottom: 16 }}>
1196
+ <div style={{ position: "absolute", left: "50%", top: 24, transform: "translateX(-50%)" }}>
1197
+ <WalkingGlyph color={LA.bruce} delay={BEAT.chars + 24} size={120} speed={0.7} trackWidth={40} />
1198
+ </div>
1199
+ </div>
1200
+ <div
1201
+ style={{
1202
+ fontFamily: MONO,
1203
+ fontSize: 14,
1204
+ color: C.inkDim,
1205
+ letterSpacing: "0.22em",
1206
+ textTransform: "uppercase",
1207
+ }}
1208
+ >
1209
+ 01
1210
+ </div>
1211
+ <div
1212
+ style={{
1213
+ fontFamily: FONT,
1214
+ fontSize: 56,
1215
+ fontWeight: 800,
1216
+ color: C.ink,
1217
+ letterSpacing: "-0.04em",
1218
+ marginTop: 4,
1219
+ lineHeight: 1,
1220
+ }}
1221
+ >
1222
+ Bruce
1223
+ </div>
1224
+ <div
1225
+ style={{
1226
+ marginTop: 10,
1227
+ ...glassBase,
1228
+ background: `${LA.bruce}33`,
1229
+ border: `1px solid ${LA.bruce}66`,
1230
+ borderRadius: 9999,
1231
+ padding: "5px 14px",
1232
+ fontFamily: MONO,
1233
+ fontSize: 13,
1234
+ fontWeight: 600,
1235
+ color: C.inkSoft,
1236
+ letterSpacing: "0.12em",
1237
+ textTransform: "uppercase",
1238
+ }}
1239
+ >
1240
+ pink hustler
1241
+ </div>
1242
+ </div>
1243
+ </GlassCard>
1244
+ </div>
1245
+
1246
+ {/* Jazz */}
1247
+ <div
1248
+ style={{
1249
+ flex: 1,
1250
+ transform: `scale(${jazzCardScale})`,
1251
+ opacity: interpolate(local, [32, 50], [0, 1], { extrapolateRight: "clamp" }),
1252
+ willChange: "transform, opacity",
1253
+ }}
1254
+ >
1255
+ <GlassCard radius={28} style={{ padding: 24, position: "relative", overflow: "hidden" }}>
1256
+ <div
1257
+ style={{
1258
+ position: "absolute",
1259
+ inset: 0,
1260
+ background: `radial-gradient(circle at 50% 30%, ${LA.jazz}55 0%, transparent 60%)`,
1261
+ pointerEvents: "none",
1262
+ }}
1263
+ />
1264
+ <div style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center" }}>
1265
+ <div style={{ position: "relative", width: 140, height: 168, marginBottom: 16 }}>
1266
+ <div style={{ position: "absolute", left: "50%", top: 24, transform: "translateX(-50%)" }}>
1267
+ <WalkingGlyph color={LA.jazz} delay={BEAT.chars + 38} size={120} speed={0.65} trackWidth={40} />
1268
+ </div>
1269
+ </div>
1270
+ <div
1271
+ style={{
1272
+ fontFamily: MONO,
1273
+ fontSize: 14,
1274
+ color: C.inkDim,
1275
+ letterSpacing: "0.22em",
1276
+ textTransform: "uppercase",
1277
+ }}
1278
+ >
1279
+ 02
1280
+ </div>
1281
+ <div
1282
+ style={{
1283
+ fontFamily: FONT,
1284
+ fontSize: 56,
1285
+ fontWeight: 800,
1286
+ color: C.ink,
1287
+ letterSpacing: "-0.04em",
1288
+ marginTop: 4,
1289
+ lineHeight: 1,
1290
+ }}
1291
+ >
1292
+ Jazz
1293
+ </div>
1294
+ <div
1295
+ style={{
1296
+ marginTop: 10,
1297
+ ...glassBase,
1298
+ background: `${LA.jazz}33`,
1299
+ border: `1px solid ${LA.jazz}66`,
1300
+ borderRadius: 9999,
1301
+ padding: "5px 14px",
1302
+ fontFamily: MONO,
1303
+ fontSize: 13,
1304
+ fontWeight: 600,
1305
+ color: C.inkSoft,
1306
+ letterSpacing: "0.12em",
1307
+ textTransform: "uppercase",
1308
+ }}
1309
+ >
1310
+ cyan dreamer
1311
+ </div>
1312
+ </div>
1313
+ </GlassCard>
1314
+ </div>
1315
+ </div>
1316
+
1317
+ {/* Lilagent-2 video card — bottom band, full width */}
1318
+ <div
1319
+ style={{
1320
+ position: "absolute",
1321
+ left: 60,
1322
+ right: 60,
1323
+ bottom: 360,
1324
+ opacity: videoCardOp,
1325
+ transform: `translateY(${videoCardY}px)`,
1326
+ }}
1327
+ >
1328
+ <div
1329
+ style={{
1330
+ ...glassBase,
1331
+ borderRadius: 36,
1332
+ overflow: "hidden",
1333
+ position: "relative",
1334
+ aspectRatio: "1 / 1",
1335
+ }}
1336
+ >
1337
+ {/* lilagent-2 starts at scene start - so wrap in Sequence */}
1338
+ <Sequence from={BEAT.chars}>
1339
+ {/* REFERENCE-STRIP: <OffthreadVideo> removed — bring your own clip */}
1340
+ </Sequence>
1341
+ {/* Stroll arrow overlay */}
1342
+ <div
1343
+ style={{
1344
+ position: "absolute",
1345
+ left: 0,
1346
+ right: 0,
1347
+ bottom: 24,
1348
+ display: "flex",
1349
+ justifyContent: "center",
1350
+ gap: 14,
1351
+ fontFamily: MONO,
1352
+ fontSize: 22,
1353
+ color: "white",
1354
+ letterSpacing: "0.2em",
1355
+ textTransform: "uppercase",
1356
+ textShadow: "0 2px 8px rgba(0,0,0,0.6)",
1357
+ opacity: interpolate(local, [70, 100], [0, 1], { extrapolateRight: "clamp" }),
1358
+ }}
1359
+ >
1360
+ <span>← stroll</span>
1361
+ <span style={{ color: C.iriGold }}>back &amp; forth</span>
1362
+ <span>stroll →</span>
1363
+ </div>
1364
+ {/* Inner highlight */}
1365
+ <div
1366
+ style={{
1367
+ position: "absolute",
1368
+ inset: 0,
1369
+ borderRadius: 36,
1370
+ boxShadow: "inset 0 2px 0 rgba(255,255,255,0.7), inset 0 -1px 0 rgba(255,255,255,0.2)",
1371
+ pointerEvents: "none",
1372
+ }}
1373
+ />
1374
+ </div>
1375
+ </div>
1376
+ </AbsoluteFill>
1377
+ );
1378
+ };
1379
+
1380
+ // ═══════════════════════════════════════════════════════════════
1381
+ // SCENE 6 — TRANSITION (710-836, 4.2s)
1382
+ // "Honestly, kinda peaceful to watch. But here's where it gets fun."
1383
+ // ═══════════════════════════════════════════════════════════════
1384
+ const TransScene: React.FC = () => {
1385
+ const frame = useCurrentFrame();
1386
+ const local = frame - BEAT.trans;
1387
+
1388
+ const peacefulOp = interpolate(local, [0, 16, 60, 75], [0, 1, 1, 0], {
1389
+ extrapolateLeft: "clamp",
1390
+ extrapolateRight: "clamp",
1391
+ });
1392
+ const peacefulScale = 1 + Math.sin(local * 0.05) * 0.025;
1393
+
1394
+ const flashOp = interpolate(local, [60, 70, 80], [0, 1, 0], {
1395
+ extrapolateLeft: "clamp",
1396
+ extrapolateRight: "clamp",
1397
+ });
1398
+
1399
+ const funOp = interpolate(local, [78, 100], [0, 1], { extrapolateRight: "clamp" });
1400
+ const funY = interpolate(local, [78, 110], [60, 0], {
1401
+ extrapolateRight: "clamp",
1402
+ easing: ease.expoOut,
1403
+ });
1404
+
1405
+ return (
1406
+ <AbsoluteFill>
1407
+ <FloatingGlyphs />
1408
+
1409
+ {/* PEACEFUL phase 0-60 */}
1410
+ <AbsoluteFill
1411
+ style={{
1412
+ alignItems: "center",
1413
+ justifyContent: "center",
1414
+ opacity: peacefulOp,
1415
+ transform: `scale(${peacefulScale})`,
1416
+ willChange: "transform, opacity",
1417
+ }}
1418
+ >
1419
+ <div
1420
+ style={{
1421
+ fontFamily: FONT,
1422
+ fontSize: 56,
1423
+ fontWeight: 500,
1424
+ color: C.inkMuted,
1425
+ letterSpacing: "-0.02em",
1426
+ marginBottom: 8,
1427
+ }}
1428
+ >
1429
+ honestly...
1430
+ </div>
1431
+ <div
1432
+ style={{
1433
+ fontFamily: FONT,
1434
+ fontSize: 196,
1435
+ fontWeight: 800,
1436
+ color: C.ink,
1437
+ letterSpacing: "-0.06em",
1438
+ lineHeight: 0.9,
1439
+ }}
1440
+ >
1441
+ peaceful.
1442
+ </div>
1443
+ {/* Breathing ring */}
1444
+ <div
1445
+ style={{
1446
+ marginTop: 36,
1447
+ width: 160 + Math.sin(local * 0.07) * 30,
1448
+ height: 160 + Math.sin(local * 0.07) * 30,
1449
+ borderRadius: "50%",
1450
+ border: `2px solid ${C.iriCyan}`,
1451
+ opacity: 0.6,
1452
+ }}
1453
+ />
1454
+ </AbsoluteFill>
1455
+
1456
+ {/* Flash transition */}
1457
+ <AbsoluteFill
1458
+ style={{
1459
+ background: `radial-gradient(circle at 50% 50%, ${C.iriViolet}cc 0%, ${C.iriCyan}88 30%, transparent 70%)`,
1460
+ opacity: flashOp,
1461
+ mixBlendMode: "screen",
1462
+ }}
1463
+ />
1464
+
1465
+ {/* "FUN" phase */}
1466
+ {local >= 70 && (
1467
+ <>
1468
+ <LightBeam delay={BEAT.trans + 70} angle={-15} />
1469
+ <LightBeam delay={BEAT.trans + 78} angle={20} />
1470
+ </>
1471
+ )}
1472
+ <AbsoluteFill
1473
+ style={{
1474
+ alignItems: "center",
1475
+ justifyContent: "center",
1476
+ opacity: funOp,
1477
+ transform: `translateY(${funY}px)`,
1478
+ willChange: "transform, opacity",
1479
+ }}
1480
+ >
1481
+ <div
1482
+ style={{
1483
+ fontFamily: FONT,
1484
+ fontSize: 52,
1485
+ fontWeight: 500,
1486
+ color: C.inkMuted,
1487
+ letterSpacing: "-0.02em",
1488
+ marginBottom: 6,
1489
+ }}
1490
+ >
1491
+ but here's where it gets
1492
+ </div>
1493
+ <div
1494
+ style={{
1495
+ fontFamily: FONT,
1496
+ fontSize: 264,
1497
+ fontWeight: 800,
1498
+ letterSpacing: "-0.075em",
1499
+ lineHeight: 0.88,
1500
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold})`,
1501
+ WebkitBackgroundClip: "text",
1502
+ WebkitTextFillColor: "transparent",
1503
+ backgroundClip: "text",
1504
+ }}
1505
+ >
1506
+ fun.
1507
+ </div>
1508
+ </AbsoluteFill>
1509
+ </AbsoluteFill>
1510
+ );
1511
+ };
1512
+
1513
+ // ═══════════════════════════════════════════════════════════════
1514
+ // SCENE 7 — CLICK → TERMINAL (836-1093, 8.6s)
1515
+ // "You click one, and boom, a live Claude terminal opens. No app switching."
1516
+ // ═══════════════════════════════════════════════════════════════
1517
+ const ClickScene: React.FC = () => {
1518
+ const frame = useCurrentFrame();
1519
+ const local = frame - BEAT.click;
1520
+
1521
+ const headerOp = interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" });
1522
+
1523
+ const cardScale = spring({
1524
+ frame: local - 4,
1525
+ fps: 30,
1526
+ config: { damping: 13, stiffness: 120 },
1527
+ from: 0.7,
1528
+ to: 1,
1529
+ });
1530
+ const cardOp = interpolate(local, [4, 28], [0, 1], { extrapolateRight: "clamp" });
1531
+
1532
+ const ringAngle = (frame * 1.4) % 360;
1533
+
1534
+ const noBadgeOp = interpolate(local, [180, 210], [0, 1], { extrapolateRight: "clamp" });
1535
+
1536
+ return (
1537
+ <AbsoluteFill>
1538
+ <FloatingGlyphs />
1539
+
1540
+ {/* Eyebrow */}
1541
+ <div
1542
+ style={{
1543
+ position: "absolute",
1544
+ top: SAFE_TOP + 24,
1545
+ left: 0,
1546
+ right: 0,
1547
+ display: "flex",
1548
+ justifyContent: "center",
1549
+ opacity: headerOp,
1550
+ }}
1551
+ >
1552
+ <EyebrowPill>06 — click → claude</EyebrowPill>
1553
+ </div>
1554
+
1555
+ {/* Full-frame lilagent-1 video card (matches HookScene) — plays from 6s onward */}
1556
+ <div
1557
+ style={{
1558
+ position: "absolute",
1559
+ left: "50%",
1560
+ top: 460,
1561
+ transform: `translateX(-50%) scale(${cardScale})`,
1562
+ opacity: cardOp,
1563
+ willChange: "transform, opacity",
1564
+ }}
1565
+ >
1566
+ <div style={{ position: "relative", width: 720, height: 720 }}>
1567
+ {/* Conic iridescent halo */}
1568
+ <div
1569
+ style={{
1570
+ position: "absolute",
1571
+ inset: -80,
1572
+ borderRadius: 60,
1573
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
1574
+ filter: "blur(50px)",
1575
+ opacity: 0.55,
1576
+ }}
1577
+ />
1578
+ {/* Iridescent ring frame */}
1579
+ <div
1580
+ style={{
1581
+ position: "absolute",
1582
+ inset: -6,
1583
+ borderRadius: 46,
1584
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
1585
+ padding: 6,
1586
+ }}
1587
+ >
1588
+ <div style={{ width: "100%", height: "100%", borderRadius: 40, background: C.bg }} />
1589
+ </div>
1590
+ {/* Glass card with lilagent-1 video starting at 6s, plays through end of scene */}
1591
+ <div
1592
+ style={{
1593
+ ...glassBase,
1594
+ position: "absolute",
1595
+ inset: 0,
1596
+ borderRadius: 40,
1597
+ overflow: "hidden",
1598
+ }}
1599
+ >
1600
+ <Sequence from={BEAT.click}>
1601
+ {/* REFERENCE-STRIP: <OffthreadVideo> removed — bring your own clip */}
1602
+ </Sequence>
1603
+ {/* Inner highlight */}
1604
+ <div
1605
+ style={{
1606
+ position: "absolute",
1607
+ inset: 0,
1608
+ borderRadius: 40,
1609
+ boxShadow:
1610
+ "inset 0 2px 0 rgba(255,255,255,0.7), inset 0 -1px 0 rgba(255,255,255,0.2)",
1611
+ pointerEvents: "none",
1612
+ }}
1613
+ />
1614
+ </div>
1615
+ </div>
1616
+ </div>
1617
+
1618
+ {/* "no app switching / no tab juggling" badge band — bottom band */}
1619
+ <div
1620
+ style={{
1621
+ position: "absolute",
1622
+ left: 0,
1623
+ right: 0,
1624
+ bottom: 360,
1625
+ display: "flex",
1626
+ justifyContent: "center",
1627
+ gap: 14,
1628
+ opacity: noBadgeOp,
1629
+ transform: `translateY(${interpolate(local, [180, 210], [20, 0], {
1630
+ extrapolateLeft: "clamp",
1631
+ extrapolateRight: "clamp",
1632
+ easing: ease.power3Out,
1633
+ })}px)`,
1634
+ }}
1635
+ >
1636
+ <div
1637
+ style={{
1638
+ ...glassBase,
1639
+ background: C.glassFillStrong,
1640
+ borderRadius: 9999,
1641
+ padding: "12px 22px",
1642
+ fontFamily: MONO,
1643
+ fontSize: 16,
1644
+ color: C.inkSoft,
1645
+ letterSpacing: "0.18em",
1646
+ textTransform: "uppercase",
1647
+ display: "flex",
1648
+ alignItems: "center",
1649
+ gap: 8,
1650
+ }}
1651
+ >
1652
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={C.iriRose} strokeWidth="2.5">
1653
+ <line x1="4" y1="4" x2="20" y2="20" />
1654
+ <line x1="20" y1="4" x2="4" y2="20" />
1655
+ </svg>
1656
+ no app switching
1657
+ </div>
1658
+ <div
1659
+ style={{
1660
+ ...glassBase,
1661
+ background: C.glassFillStrong,
1662
+ borderRadius: 9999,
1663
+ padding: "12px 22px",
1664
+ fontFamily: MONO,
1665
+ fontSize: 16,
1666
+ color: C.inkSoft,
1667
+ letterSpacing: "0.18em",
1668
+ textTransform: "uppercase",
1669
+ display: "flex",
1670
+ alignItems: "center",
1671
+ gap: 8,
1672
+ }}
1673
+ >
1674
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={C.iriRose} strokeWidth="2.5">
1675
+ <line x1="4" y1="4" x2="20" y2="20" />
1676
+ <line x1="20" y1="4" x2="4" y2="20" />
1677
+ </svg>
1678
+ no tab juggling
1679
+ </div>
1680
+ </div>
1681
+ </AbsoluteFill>
1682
+ );
1683
+ };
1684
+
1685
+ // ═══════════════════════════════════════════════════════════════
1686
+ // SCENE 8 — THOUGHT BUBBLES (1093-1391, 9.9s)
1687
+ // "Thought bubbles with playful phrases. Sound on finish. Adorable."
1688
+ // ═══════════════════════════════════════════════════════════════
1689
+ const ThinkScene: React.FC = () => {
1690
+ const frame = useCurrentFrame();
1691
+ const local = frame - BEAT.think;
1692
+
1693
+ const headerOp = interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" });
1694
+
1695
+ // Sound waves trigger near end of scene
1696
+ const soundStart = BEAT.think + 220;
1697
+
1698
+ return (
1699
+ <AbsoluteFill>
1700
+ <FloatingGlyphs />
1701
+
1702
+ {/* Eyebrow */}
1703
+ <div
1704
+ style={{
1705
+ position: "absolute",
1706
+ top: SAFE_TOP + 24,
1707
+ left: 0,
1708
+ right: 0,
1709
+ display: "flex",
1710
+ justifyContent: "center",
1711
+ opacity: headerOp,
1712
+ }}
1713
+ >
1714
+ <EyebrowPill>07 — playful UX</EyebrowPill>
1715
+ </div>
1716
+
1717
+ {/* Title */}
1718
+ <div
1719
+ style={{
1720
+ position: "absolute",
1721
+ left: 0,
1722
+ right: 0,
1723
+ top: SAFE_TOP + 100,
1724
+ textAlign: "center",
1725
+ opacity: interpolate(local, [4, 26], [0, 1], { extrapolateRight: "clamp" }),
1726
+ transform: `translateY(${interpolate(local, [4, 26], [16, 0], {
1727
+ extrapolateRight: "clamp",
1728
+ easing: ease.power3Out,
1729
+ })}px)`,
1730
+ }}
1731
+ >
1732
+ <div
1733
+ style={{
1734
+ fontFamily: FONT,
1735
+ fontSize: 64,
1736
+ fontWeight: 500,
1737
+ color: C.inkMuted,
1738
+ letterSpacing: "-0.02em",
1739
+ }}
1740
+ >
1741
+ while it thinks,
1742
+ </div>
1743
+ <div
1744
+ style={{
1745
+ fontFamily: FONT,
1746
+ fontSize: 124,
1747
+ fontWeight: 800,
1748
+ color: C.ink,
1749
+ letterSpacing: "-0.05em",
1750
+ lineHeight: 0.95,
1751
+ marginTop: 4,
1752
+ }}
1753
+ >
1754
+ it talks back.
1755
+ </div>
1756
+ </div>
1757
+
1758
+ {/* Bruce in middle, thinking */}
1759
+ <div
1760
+ style={{
1761
+ position: "absolute",
1762
+ left: "50%",
1763
+ top: 970,
1764
+ transform: "translate(-50%, -50%)",
1765
+ opacity: interpolate(local, [20, 40], [0, 1], { extrapolateRight: "clamp" }),
1766
+ }}
1767
+ >
1768
+ <div
1769
+ style={{
1770
+ position: "relative",
1771
+ width: 220,
1772
+ height: 220,
1773
+ borderRadius: 56,
1774
+ background: `linear-gradient(145deg, ${LA.peach}, ${LA.peachDeep})`,
1775
+ boxShadow: [
1776
+ `0 30px 60px -10px ${LA.peachDeep}cc`,
1777
+ "inset 0 2px 0 rgba(255,255,255,0.55)",
1778
+ ].join(", "),
1779
+ }}
1780
+ >
1781
+ <div style={{ position: "absolute", left: 40, top: 30 }}>
1782
+ <WalkingGlyph color={LA.bruce} delay={BEAT.think + 30} size={140} speed={0.3} trackWidth={20} />
1783
+ </div>
1784
+ {/* Spinning ring around character — "thinking" indicator */}
1785
+ <div
1786
+ style={{
1787
+ position: "absolute",
1788
+ inset: -16,
1789
+ borderRadius: 72,
1790
+ background: `conic-gradient(from ${frame * 4}deg, transparent 60%, ${C.iriViolet}, ${C.iriCyan}, transparent 100%)`,
1791
+ filter: "blur(8px)",
1792
+ opacity: 0.85,
1793
+ }}
1794
+ />
1795
+ </div>
1796
+ </div>
1797
+
1798
+ {/* Thought bubbles cycling */}
1799
+ <ThoughtBubble
1800
+ x={140}
1801
+ y={680}
1802
+ text="hmm..."
1803
+ startFrame={BEAT.think + 30}
1804
+ duration={70}
1805
+ color={LA.bruce}
1806
+ />
1807
+ <ThoughtBubble
1808
+ x={680}
1809
+ y={760}
1810
+ text="thinking..."
1811
+ startFrame={BEAT.think + 65}
1812
+ duration={80}
1813
+ color={C.iriCyan}
1814
+ />
1815
+ <ThoughtBubble
1816
+ x={120}
1817
+ y={1180}
1818
+ text="cooking up vibes"
1819
+ startFrame={BEAT.think + 110}
1820
+ duration={75}
1821
+ color={C.iriViolet}
1822
+ />
1823
+ <ThoughtBubble
1824
+ x={620}
1825
+ y={1240}
1826
+ text="almost there"
1827
+ startFrame={BEAT.think + 150}
1828
+ duration={70}
1829
+ color={LA.jazz}
1830
+ />
1831
+ <ThoughtBubble
1832
+ x={200}
1833
+ y={620}
1834
+ text="big brain time"
1835
+ startFrame={BEAT.think + 180}
1836
+ duration={70}
1837
+ color={C.iriRose}
1838
+ />
1839
+
1840
+ {/* Sound waves at end of scene */}
1841
+ {local >= 220 && <SoundWaves startFrame={soundStart} cx={540} cy={970} />}
1842
+
1843
+ {/* DING badge — appears with sound */}
1844
+ <div
1845
+ style={{
1846
+ position: "absolute",
1847
+ left: 0,
1848
+ right: 0,
1849
+ bottom: 360,
1850
+ display: "flex",
1851
+ justifyContent: "center",
1852
+ opacity: interpolate(local, [220, 250], [0, 1], { extrapolateRight: "clamp" }),
1853
+ transform: `scale(${spring({
1854
+ frame: local - 220,
1855
+ fps: 30,
1856
+ config: { damping: 9, stiffness: 140 },
1857
+ from: 0.6,
1858
+ to: 1,
1859
+ })})`,
1860
+ }}
1861
+ >
1862
+ <div
1863
+ style={{
1864
+ ...glassBase,
1865
+ background: C.glassFillStrong,
1866
+ borderRadius: 9999,
1867
+ padding: "16px 32px",
1868
+ display: "flex",
1869
+ alignItems: "center",
1870
+ gap: 14,
1871
+ boxShadow: [
1872
+ "0 14px 32px -8px rgba(120,100,180,0.4)",
1873
+ `0 0 32px ${C.iriGold}55`,
1874
+ "inset 0 1.5px 0 rgba(255,255,255,0.95)",
1875
+ ].join(", "),
1876
+ }}
1877
+ >
1878
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke={C.iriGold} strokeWidth="2">
1879
+ <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" />
1880
+ <path d="M10.3 21a2 2 0 0 0 3.4 0" />
1881
+ </svg>
1882
+ <div
1883
+ style={{
1884
+ fontFamily: FONT,
1885
+ fontSize: 30,
1886
+ fontWeight: 700,
1887
+ color: C.ink,
1888
+ letterSpacing: "-0.025em",
1889
+ }}
1890
+ >
1891
+ done!
1892
+ </div>
1893
+ <div
1894
+ style={{
1895
+ fontFamily: MONO,
1896
+ fontSize: 14,
1897
+ color: C.inkDim,
1898
+ letterSpacing: "0.18em",
1899
+ textTransform: "uppercase",
1900
+ }}
1901
+ >
1902
+ *plays a little sound*
1903
+ </div>
1904
+ </div>
1905
+ </div>
1906
+ </AbsoluteFill>
1907
+ );
1908
+ };
1909
+
1910
+ // ═══════════════════════════════════════════════════════════════
1911
+ // SCENE 9 — LOCAL / PRIVACY (1391-1681, 9.7s)
1912
+ // "And the best part — no signup, nothing leaves your mac. Everything runs locally."
1913
+ // ═══════════════════════════════════════════════════════════════
1914
+ const LocalScene: React.FC = () => {
1915
+ const frame = useCurrentFrame();
1916
+ const local = frame - BEAT.local;
1917
+
1918
+ const headerOp = interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" });
1919
+
1920
+ const shieldScale = spring({
1921
+ frame: local - 6,
1922
+ fps: 30,
1923
+ config: { damping: 12, stiffness: 130 },
1924
+ from: 0.5,
1925
+ to: 1,
1926
+ });
1927
+
1928
+ const ringAngle = (frame * 1.2) % 360;
1929
+
1930
+ const cards = [
1931
+ { label: "no signup", value: "0", unit: "accounts", color: C.iriCyan },
1932
+ { label: "no tracking", value: "0", unit: "events", color: C.iriViolet },
1933
+ { label: "no cloud", value: "0", unit: "bytes leave", color: C.iriRose },
1934
+ ];
1935
+
1936
+ return (
1937
+ <AbsoluteFill>
1938
+ <FloatingGlyphs />
1939
+
1940
+ {/* Eyebrow */}
1941
+ <div
1942
+ style={{
1943
+ position: "absolute",
1944
+ top: SAFE_TOP + 24,
1945
+ left: 0,
1946
+ right: 0,
1947
+ display: "flex",
1948
+ justifyContent: "center",
1949
+ opacity: headerOp,
1950
+ }}
1951
+ >
1952
+ <EyebrowPill>08 — privacy first</EyebrowPill>
1953
+ </div>
1954
+
1955
+ {/* Shield with halo */}
1956
+ <div
1957
+ style={{
1958
+ position: "absolute",
1959
+ left: "50%",
1960
+ top: 540,
1961
+ transform: `translate(-50%, -50%) scale(${shieldScale})`,
1962
+ opacity: interpolate(local, [4, 26], [0, 1], { extrapolateRight: "clamp" }),
1963
+ willChange: "transform, opacity",
1964
+ }}
1965
+ >
1966
+ {/* Conic halo */}
1967
+ <div
1968
+ style={{
1969
+ position: "absolute",
1970
+ left: "50%",
1971
+ top: "50%",
1972
+ width: 460,
1973
+ height: 460,
1974
+ transform: "translate(-50%, -50%)",
1975
+ borderRadius: "50%",
1976
+ background: `conic-gradient(from ${ringAngle}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
1977
+ filter: "blur(60px)",
1978
+ opacity: 0.5,
1979
+ }}
1980
+ />
1981
+ {/* Pulsing glow ring */}
1982
+ <div
1983
+ style={{
1984
+ position: "absolute",
1985
+ left: "50%",
1986
+ top: "50%",
1987
+ width: 280 + Math.sin(local * 0.08) * 16,
1988
+ height: 280 + Math.sin(local * 0.08) * 16,
1989
+ transform: "translate(-50%, -50%)",
1990
+ borderRadius: "50%",
1991
+ border: `2px solid ${C.iriViolet}`,
1992
+ opacity: 0.5,
1993
+ }}
1994
+ />
1995
+ {/* Glass shield */}
1996
+ <div
1997
+ style={{
1998
+ position: "relative",
1999
+ width: 240,
2000
+ height: 280,
2001
+ display: "flex",
2002
+ alignItems: "center",
2003
+ justifyContent: "center",
2004
+ }}
2005
+ >
2006
+ <svg width="240" height="280" viewBox="0 0 240 280">
2007
+ <defs>
2008
+ <linearGradient id="shield-grad" x1="0" y1="0" x2="1" y2="1">
2009
+ <stop offset="0" stopColor="rgba(255,255,255,0.95)" />
2010
+ <stop offset="1" stopColor="rgba(255,255,255,0.55)" />
2011
+ </linearGradient>
2012
+ </defs>
2013
+ <path
2014
+ d="M 120 12 L 220 56 L 220 144 Q 220 218 120 268 Q 20 218 20 144 L 20 56 Z"
2015
+ fill="url(#shield-grad)"
2016
+ stroke="rgba(255,255,255,0.95)"
2017
+ strokeWidth={3}
2018
+ filter="drop-shadow(0 12px 24px rgba(120,100,180,0.4))"
2019
+ />
2020
+ <path
2021
+ d="M 78 140 L 110 172 L 168 110"
2022
+ fill="none"
2023
+ stroke={C.iriViolet}
2024
+ strokeWidth={10}
2025
+ strokeLinecap="round"
2026
+ strokeLinejoin="round"
2027
+ />
2028
+ </svg>
2029
+ </div>
2030
+ </div>
2031
+
2032
+ {/* Big "100% LOCAL" */}
2033
+ <div
2034
+ style={{
2035
+ position: "absolute",
2036
+ left: 0,
2037
+ right: 0,
2038
+ top: 800,
2039
+ textAlign: "center",
2040
+ opacity: interpolate(local, [40, 70], [0, 1], { extrapolateRight: "clamp" }),
2041
+ transform: `translateY(${interpolate(local, [40, 70], [20, 0], {
2042
+ extrapolateRight: "clamp",
2043
+ easing: ease.power3Out,
2044
+ })}px)`,
2045
+ }}
2046
+ >
2047
+ <div
2048
+ style={{
2049
+ fontFamily: MONO,
2050
+ fontSize: 22,
2051
+ color: C.inkDim,
2052
+ letterSpacing: "0.22em",
2053
+ textTransform: "uppercase",
2054
+ marginBottom: 8,
2055
+ }}
2056
+ >
2057
+ your data stays
2058
+ </div>
2059
+ <div
2060
+ style={{
2061
+ fontFamily: FONT,
2062
+ fontSize: 196,
2063
+ fontWeight: 800,
2064
+ letterSpacing: "-0.07em",
2065
+ lineHeight: 0.92,
2066
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose})`,
2067
+ WebkitBackgroundClip: "text",
2068
+ WebkitTextFillColor: "transparent",
2069
+ backgroundClip: "text",
2070
+ }}
2071
+ >
2072
+ 100% local.
2073
+ </div>
2074
+ </div>
2075
+
2076
+ {/* Three privacy cards */}
2077
+ <div
2078
+ style={{
2079
+ position: "absolute",
2080
+ left: 60,
2081
+ right: 60,
2082
+ bottom: 360,
2083
+ display: "flex",
2084
+ gap: 14,
2085
+ }}
2086
+ >
2087
+ {cards.map((c, i) => {
2088
+ const startL = local - 110 - i * 10;
2089
+ const op = interpolate(startL, [0, 18], [0, 1], {
2090
+ extrapolateLeft: "clamp",
2091
+ extrapolateRight: "clamp",
2092
+ });
2093
+ const y = interpolate(startL, [0, 24], [30, 0], {
2094
+ extrapolateLeft: "clamp",
2095
+ extrapolateRight: "clamp",
2096
+ easing: ease.expoOut,
2097
+ });
2098
+ return (
2099
+ <div
2100
+ key={i}
2101
+ style={{
2102
+ flex: 1,
2103
+ opacity: op,
2104
+ transform: `translateY(${y}px)`,
2105
+ willChange: "transform, opacity",
2106
+ }}
2107
+ >
2108
+ <GlassCard radius={24} style={{ padding: 18, position: "relative", overflow: "hidden" }}>
2109
+ <div
2110
+ style={{
2111
+ position: "absolute",
2112
+ inset: 0,
2113
+ background: `radial-gradient(circle at 50% 0%, ${c.color}33 0%, transparent 60%)`,
2114
+ pointerEvents: "none",
2115
+ }}
2116
+ />
2117
+ <div style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center" }}>
2118
+ <div
2119
+ style={{
2120
+ fontFamily: MONO,
2121
+ fontSize: 12,
2122
+ color: C.inkDim,
2123
+ letterSpacing: "0.22em",
2124
+ textTransform: "uppercase",
2125
+ marginBottom: 6,
2126
+ }}
2127
+ >
2128
+ {c.label}
2129
+ </div>
2130
+ <div
2131
+ style={{
2132
+ fontFamily: MONO,
2133
+ fontSize: 80,
2134
+ fontWeight: 700,
2135
+ color: C.ink,
2136
+ letterSpacing: "-0.05em",
2137
+ lineHeight: 1,
2138
+ fontVariantNumeric: "tabular-nums",
2139
+ }}
2140
+ >
2141
+ {c.value}
2142
+ </div>
2143
+ <div
2144
+ style={{
2145
+ fontFamily: MONO,
2146
+ fontSize: 13,
2147
+ color: c.color,
2148
+ letterSpacing: "0.18em",
2149
+ textTransform: "uppercase",
2150
+ marginTop: 4,
2151
+ }}
2152
+ >
2153
+ {c.unit}
2154
+ </div>
2155
+ </div>
2156
+ </GlassCard>
2157
+ </div>
2158
+ );
2159
+ })}
2160
+ </div>
2161
+ </AbsoluteFill>
2162
+ );
2163
+ };
2164
+
2165
+ // ═══════════════════════════════════════════════════════════════
2166
+ // SCENE 10 — ALIVE (1681-2016, 11.2s)
2167
+ // "It's wild. We make AI more powerful, faster, smarter. But this guy made it feel alive."
2168
+ // ═══════════════════════════════════════════════════════════════
2169
+ const AliveScene: React.FC = () => {
2170
+ const frame = useCurrentFrame();
2171
+ const local = frame - BEAT.alive;
2172
+
2173
+ const headerOp = interpolate(local, [0, 18], [0, 1], { extrapolateRight: "clamp" });
2174
+
2175
+ // Phase A: 3 stat counters (0-150)
2176
+ const stats = [
2177
+ { label: "powerful", value: 200, unit: "B params", color: C.iriCyan, delay: 18 },
2178
+ { label: "faster", value: 1.6, unit: "tok / ms", color: C.iriViolet, delay: 32, decimals: 1 },
2179
+ { label: "smarter", value: 95, unit: "% on benchmark", color: C.iriRose, delay: 46 },
2180
+ ];
2181
+
2182
+ // Phase B: ALIVE reveal (150+)
2183
+ const aliveOp = interpolate(local, [150, 180], [0, 1], { extrapolateRight: "clamp" });
2184
+ const aliveScale = spring({
2185
+ frame: local - 150,
2186
+ fps: 30,
2187
+ config: { damping: 12, stiffness: 110 },
2188
+ from: 0.7,
2189
+ to: 1,
2190
+ });
2191
+ const heartPulse = 1 + Math.sin(local * 0.18) * 0.04;
2192
+
2193
+ return (
2194
+ <AbsoluteFill>
2195
+ <FloatingGlyphs />
2196
+
2197
+ {/* Eyebrow */}
2198
+ <div
2199
+ style={{
2200
+ position: "absolute",
2201
+ top: SAFE_TOP + 24,
2202
+ left: 0,
2203
+ right: 0,
2204
+ display: "flex",
2205
+ justifyContent: "center",
2206
+ opacity: headerOp,
2207
+ }}
2208
+ >
2209
+ <EyebrowPill>09 — but this</EyebrowPill>
2210
+ </div>
2211
+
2212
+ {/* Phase A: stat counters fade out as ALIVE comes in */}
2213
+ <div
2214
+ style={{
2215
+ position: "absolute",
2216
+ left: 60,
2217
+ right: 60,
2218
+ top: SAFE_TOP + 130,
2219
+ opacity: interpolate(local, [4, 24, 130, 160], [0, 1, 1, 0], {
2220
+ extrapolateLeft: "clamp",
2221
+ extrapolateRight: "clamp",
2222
+ }),
2223
+ }}
2224
+ >
2225
+ <div
2226
+ style={{
2227
+ fontFamily: FONT,
2228
+ fontSize: 56,
2229
+ fontWeight: 500,
2230
+ color: C.inkMuted,
2231
+ letterSpacing: "-0.02em",
2232
+ marginBottom: 24,
2233
+ }}
2234
+ >
2235
+ we keep making AI...
2236
+ </div>
2237
+ <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
2238
+ {stats.map((s, i) => {
2239
+ const startL = local - s.delay;
2240
+ const op = interpolate(startL, [0, 22], [0, 1], {
2241
+ extrapolateLeft: "clamp",
2242
+ extrapolateRight: "clamp",
2243
+ });
2244
+ const x = interpolate(startL, [0, 22], [-30, 0], {
2245
+ extrapolateLeft: "clamp",
2246
+ extrapolateRight: "clamp",
2247
+ easing: ease.power3Out,
2248
+ });
2249
+ return (
2250
+ <div
2251
+ key={i}
2252
+ style={{
2253
+ ...glassBase,
2254
+ borderRadius: 22,
2255
+ padding: "18px 24px",
2256
+ display: "flex",
2257
+ alignItems: "baseline",
2258
+ gap: 18,
2259
+ opacity: op,
2260
+ transform: `translateX(${x}px)`,
2261
+ }}
2262
+ >
2263
+ <div
2264
+ style={{
2265
+ width: 12,
2266
+ height: 12,
2267
+ borderRadius: "50%",
2268
+ background: s.color,
2269
+ boxShadow: `0 0 14px ${s.color}`,
2270
+ alignSelf: "center",
2271
+ }}
2272
+ />
2273
+ <div
2274
+ style={{
2275
+ fontFamily: FONT,
2276
+ fontSize: 40,
2277
+ fontWeight: 700,
2278
+ color: C.ink,
2279
+ letterSpacing: "-0.03em",
2280
+ flex: 1,
2281
+ }}
2282
+ >
2283
+ {s.label}
2284
+ </div>
2285
+ <div
2286
+ style={{
2287
+ fontFamily: MONO,
2288
+ fontSize: 56,
2289
+ fontWeight: 700,
2290
+ color: C.ink,
2291
+ fontVariantNumeric: "tabular-nums",
2292
+ letterSpacing: "-0.04em",
2293
+ }}
2294
+ >
2295
+ <Counter
2296
+ from={0}
2297
+ to={s.value}
2298
+ startFrame={BEAT.alive + s.delay + 4}
2299
+ duration={50}
2300
+ format={(n) =>
2301
+ s.decimals
2302
+ ? n.toFixed(s.decimals)
2303
+ : Math.round(n).toLocaleString()
2304
+ }
2305
+ />
2306
+ </div>
2307
+ <div
2308
+ style={{
2309
+ fontFamily: MONO,
2310
+ fontSize: 14,
2311
+ color: C.inkDim,
2312
+ letterSpacing: "0.18em",
2313
+ textTransform: "uppercase",
2314
+ }}
2315
+ >
2316
+ {s.unit}
2317
+ </div>
2318
+ </div>
2319
+ );
2320
+ })}
2321
+ </div>
2322
+ </div>
2323
+
2324
+ {/* Phase B: ALIVE reveal */}
2325
+ <AbsoluteFill
2326
+ style={{
2327
+ alignItems: "center",
2328
+ justifyContent: "center",
2329
+ opacity: aliveOp,
2330
+ transform: `scale(${aliveScale})`,
2331
+ willChange: "transform, opacity",
2332
+ }}
2333
+ >
2334
+ {/* Pulsing heart */}
2335
+ <div style={{ marginBottom: 20, transform: `scale(${heartPulse})` }}>
2336
+ <svg width="100" height="100" viewBox="0 0 24 24" fill={C.iriRose}>
2337
+ <path d="M12 21s-7-4.5-9.5-9C1 8.5 3 5 6 5c2 0 3.5 1 6 4 2.5-3 4-4 6-4 3 0 5 3.5 3.5 7-2.5 4.5-9.5 9-9.5 9z" />
2338
+ </svg>
2339
+ </div>
2340
+ <div
2341
+ style={{
2342
+ fontFamily: FONT,
2343
+ fontSize: 56,
2344
+ fontWeight: 500,
2345
+ color: C.inkMuted,
2346
+ letterSpacing: "-0.02em",
2347
+ marginBottom: 8,
2348
+ }}
2349
+ >
2350
+ but this guy made it
2351
+ </div>
2352
+ <div
2353
+ style={{
2354
+ fontFamily: FONT,
2355
+ fontSize: 296,
2356
+ fontWeight: 800,
2357
+ letterSpacing: "-0.075em",
2358
+ lineHeight: 0.88,
2359
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold})`,
2360
+ WebkitBackgroundClip: "text",
2361
+ WebkitTextFillColor: "transparent",
2362
+ backgroundClip: "text",
2363
+ }}
2364
+ >
2365
+ alive.
2366
+ </div>
2367
+ <div
2368
+ style={{
2369
+ marginTop: 20,
2370
+ fontFamily: MONO,
2371
+ fontSize: 22,
2372
+ color: C.inkMuted,
2373
+ letterSpacing: "0.18em",
2374
+ textTransform: "uppercase",
2375
+ opacity: interpolate(local, [200, 230], [0, 1], { extrapolateRight: "clamp" }),
2376
+ }}
2377
+ >
2378
+ a little buddy on your screen
2379
+ </div>
2380
+ </AbsoluteFill>
2381
+ </AbsoluteFill>
2382
+ );
2383
+ };
2384
+
2385
+ // ═══════════════════════════════════════════════════════════════
2386
+ // SCENE 11 — CTA (2016-2160, 4.8s)
2387
+ // "If you want the link, like and subscribe and comment 'friend'."
2388
+ // ═══════════════════════════════════════════════════════════════
2389
+ const CTAScene: React.FC = () => {
2390
+ const frame = useCurrentFrame();
2391
+ const local = frame - BEAT.cta;
2392
+
2393
+ const headlineOp = interpolate(local, [0, 22], [0, 1], { extrapolateRight: "clamp" });
2394
+ const headlineY = interpolate(local, [0, 24], [22, 0], {
2395
+ extrapolateRight: "clamp",
2396
+ easing: ease.expoOut,
2397
+ });
2398
+
2399
+ const pillOp = interpolate(local, [30, 60], [0, 1], { extrapolateRight: "clamp" });
2400
+ const pillScale = spring({
2401
+ frame: local - 30,
2402
+ fps: 30,
2403
+ config: { damping: 13, stiffness: 130 },
2404
+ from: 0.8,
2405
+ to: 1,
2406
+ });
2407
+
2408
+ const triOp = interpolate(local, [70, 100], [0, 1], { extrapolateRight: "clamp" });
2409
+
2410
+ return (
2411
+ <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}>
2412
+ {/* Light beams */}
2413
+ <LightBeam delay={BEAT.cta + 4} angle={-12} />
2414
+ <LightBeam delay={BEAT.cta + 30} angle={18} />
2415
+ <FloatingGlyphs />
2416
+
2417
+ <div
2418
+ style={{
2419
+ opacity: headlineOp,
2420
+ transform: `translateY(${headlineY}px)`,
2421
+ textAlign: "center",
2422
+ marginBottom: 28,
2423
+ willChange: "transform, opacity",
2424
+ }}
2425
+ >
2426
+ <div
2427
+ style={{
2428
+ fontFamily: FONT,
2429
+ fontSize: 56,
2430
+ fontWeight: 500,
2431
+ color: C.inkMuted,
2432
+ letterSpacing: "-0.02em",
2433
+ }}
2434
+ >
2435
+ comment
2436
+ </div>
2437
+ <div
2438
+ style={{
2439
+ fontFamily: FONT,
2440
+ fontSize: 248,
2441
+ fontWeight: 800,
2442
+ letterSpacing: "-0.075em",
2443
+ lineHeight: 0.88,
2444
+ background: `linear-gradient(135deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose})`,
2445
+ WebkitBackgroundClip: "text",
2446
+ WebkitTextFillColor: "transparent",
2447
+ backgroundClip: "text",
2448
+ }}
2449
+ >
2450
+ "friend"
2451
+ </div>
2452
+ <div
2453
+ style={{
2454
+ fontFamily: FONT,
2455
+ fontSize: 56,
2456
+ fontWeight: 500,
2457
+ color: C.inkMuted,
2458
+ letterSpacing: "-0.02em",
2459
+ marginTop: -10,
2460
+ }}
2461
+ >
2462
+ and I'll send you the link.
2463
+ </div>
2464
+ </div>
2465
+
2466
+ {/* Iridescent subscribe pill */}
2467
+ <div
2468
+ style={{
2469
+ position: "relative",
2470
+ opacity: pillOp,
2471
+ transform: `scale(${pillScale})`,
2472
+ marginTop: 12,
2473
+ }}
2474
+ >
2475
+ <div
2476
+ style={{
2477
+ position: "absolute",
2478
+ inset: -3,
2479
+ borderRadius: 9999,
2480
+ background: `conic-gradient(from ${frame * 1.6}deg, ${C.iriCyan}, ${C.iriViolet}, ${C.iriRose}, ${C.iriGold}, ${C.iriCyan})`,
2481
+ filter: "blur(2px)",
2482
+ opacity: 0.85,
2483
+ }}
2484
+ />
2485
+ <div
2486
+ style={{
2487
+ ...glassBase,
2488
+ background: C.glassFillStrong,
2489
+ borderRadius: 9999,
2490
+ padding: "22px 44px",
2491
+ display: "inline-flex",
2492
+ alignItems: "center",
2493
+ gap: 16,
2494
+ position: "relative",
2495
+ }}
2496
+ >
2497
+ {/* YouTube glyph */}
2498
+ <svg width="44" height="44" viewBox="0 0 24 24" fill="#FF0000">
2499
+ <path d="M21.6 7.2a2.4 2.4 0 0 0-1.7-1.7C18.4 5 12 5 12 5s-6.4 0-7.9.5A2.4 2.4 0 0 0 2.4 7.2C2 8.7 2 12 2 12s0 3.3.4 4.8a2.4 2.4 0 0 0 1.7 1.7C5.6 19 12 19 12 19s6.4 0 7.9-.5a2.4 2.4 0 0 0 1.7-1.7c.4-1.5.4-4.8.4-4.8s0-3.3-.4-4.8zM10 15V9l5 3-5 3z" />
2500
+ </svg>
2501
+ <div
2502
+ style={{
2503
+ fontFamily: FONT,
2504
+ fontSize: 38,
2505
+ fontWeight: 700,
2506
+ color: C.ink,
2507
+ letterSpacing: "-0.02em",
2508
+ }}
2509
+ >
2510
+ like &amp; subscribe
2511
+ </div>
2512
+ </div>
2513
+ </div>
2514
+
2515
+ {/* Floating "friend" comment chips */}
2516
+ <div
2517
+ style={{
2518
+ position: "absolute",
2519
+ left: 0,
2520
+ right: 0,
2521
+ top: 1320,
2522
+ display: "flex",
2523
+ justifyContent: "center",
2524
+ gap: 12,
2525
+ opacity: triOp,
2526
+ }}
2527
+ >
2528
+ {["friend", "friend", "friend"].map((w, i) => {
2529
+ const float = Math.sin((frame + i * 30) * 0.06) * 8;
2530
+ return (
2531
+ <div
2532
+ key={i}
2533
+ style={{
2534
+ ...glassBase,
2535
+ background: i === 1 ? C.glassFillStrong : C.glassFill,
2536
+ borderRadius: 9999,
2537
+ padding: "10px 22px",
2538
+ fontFamily: MONO,
2539
+ fontSize: 18,
2540
+ color: C.inkSoft,
2541
+ letterSpacing: "0.12em",
2542
+ textTransform: "uppercase",
2543
+ transform: `translateY(${float}px) rotate(${(i - 1) * 3}deg)`,
2544
+ willChange: "transform",
2545
+ }}
2546
+ >
2547
+ "{w}"
2548
+ </div>
2549
+ );
2550
+ })}
2551
+ </div>
2552
+ </AbsoluteFill>
2553
+ );
2554
+ };
2555
+
2556
+ // ═══════════════════════════════════════════════════════════════
2557
+ // MAIN — orchestrate sequences with audio
2558
+ // ═══════════════════════════════════════════════════════════════
2559
+ export const LilAgentsReel: React.FC = () => {
2560
+ const { width, height } = useVideoConfig();
2561
+ const frame = useCurrentFrame();
2562
+
2563
+ return (
2564
+ <AbsoluteFill
2565
+ style={{
2566
+ background: `radial-gradient(ellipse at 30% 20%, ${C.bgWarm} 0%, ${C.bg} 50%, ${C.bgCool} 100%)`,
2567
+ width,
2568
+ height,
2569
+ overflow: "hidden",
2570
+ }}
2571
+ >
2572
+ {/* Perpetual caustic blobs — drift across entire reel */}
2573
+ <CausticBlobs />
2574
+
2575
+ {/* Subtle hairline grid */}
2576
+ <HairlineGrid opacity={0.04} />
2577
+
2578
+ {/* Film-grain noise (fixed, pointer-events none) */}
2579
+ <AbsoluteFill
2580
+ style={{
2581
+ backgroundImage:
2582
+ "url(\"data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E\")",
2583
+ opacity: 0.06,
2584
+ pointerEvents: "none",
2585
+ mixBlendMode: "multiply",
2586
+ }}
2587
+ />
2588
+
2589
+ {/* Scenes — conditional render so useCurrentFrame() returns GLOBAL frame */}
2590
+ {frame >= BEAT.hook && frame < BEAT.dock && <HookScene />}
2591
+ {frame >= BEAT.dock && frame < BEAT.name && <DockScene />}
2592
+ {frame >= BEAT.name && frame < BEAT.oss && <NameScene />}
2593
+ {frame >= BEAT.oss && frame < BEAT.chars && <OSSScene />}
2594
+ {frame >= BEAT.chars && frame < BEAT.trans && <CharactersScene />}
2595
+ {frame >= BEAT.trans && frame < BEAT.click && <TransScene />}
2596
+ {frame >= BEAT.click && frame < BEAT.think && <ClickScene />}
2597
+ {frame >= BEAT.think && frame < BEAT.local && <ThinkScene />}
2598
+ {frame >= BEAT.local && frame < BEAT.alive && <LocalScene />}
2599
+ {frame >= BEAT.alive && frame < BEAT.cta && <AliveScene />}
2600
+ {frame >= BEAT.cta && frame < BEAT.end && <CTAScene />}
2601
+
2602
+ {/* Bottom safe-zone footer (visible from scene 2 onward) */}
2603
+ <div
2604
+ style={{
2605
+ position: "absolute",
2606
+ bottom: 60,
2607
+ left: 0,
2608
+ right: 0,
2609
+ display: "flex",
2610
+ justifyContent: "center",
2611
+ opacity: interpolate(frame, [180, 220], [0, 1], {
2612
+ extrapolateLeft: "clamp",
2613
+ extrapolateRight: "clamp",
2614
+ }),
2615
+ }}
2616
+ >
2617
+ <div
2618
+ style={{
2619
+ ...glassBase,
2620
+ borderRadius: 9999,
2621
+ padding: "10px 22px",
2622
+ fontFamily: MONO,
2623
+ fontSize: 16,
2624
+ color: C.inkSoft,
2625
+ letterSpacing: "0.2em",
2626
+ textTransform: "uppercase",
2627
+ display: "flex",
2628
+ alignItems: "center",
2629
+ gap: 10,
2630
+ }}
2631
+ >
2632
+ <div
2633
+ style={{
2634
+ width: 6,
2635
+ height: 6,
2636
+ borderRadius: 3,
2637
+ background: C.iriViolet,
2638
+ boxShadow: `0 0 10px ${C.iriViolet}`,
2639
+ }}
2640
+ />
2641
+ @abhishek.devini
2642
+ </div>
2643
+ </div>
2644
+
2645
+ {/* Audio */}
2646
+ {/* REFERENCE-STRIP: voiceover tag removed — bring your own voiceover */}
2647
+ </AbsoluteFill>
2648
+ );
2649
+ };