- {/* Avatar stack */}
-
- {["#FF6B6B", "#4ECDC4", "#45B7D1"].map((color, i) => (
-
0 ? -15 : 0,
- zIndex: 3 - i,
- }}
- />
- ))}
-
-
-
- LA Trip Planning
-
-
- 3 people
-
-
-
-
- {/* Messages */}
-
- {messages.map((message, index) => {
- // Stagger each message
- const messageDelay = index * 6;
- const localFrame = frame - messageDelay;
-
- const entranceProgress = spring({
- frame: localFrame,
- fps,
- config: theme.animation.snappy,
- });
-
- const opacity = interpolate(
- localFrame,
- [0, 5],
- [0, 1],
- { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
- );
-
- const translateX = message.side === "left"
- ? interpolate(entranceProgress, [0, 1], [-50, 0])
- : interpolate(entranceProgress, [0, 1], [50, 0]);
-
- const scale = interpolate(entranceProgress, [0, 1], [0.8, 1]);
-
- return (
-
-
- {/* Sender name */}
-
- {message.sender}
-
-
- {/* Bubble */}
-
-
- {message.text}
-
-
-
-
- );
- })}
-
-
- );
-};
-
-// "Stop the chaos" text overlay
-export const StopTheChaos: React.FC = () => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- const progress = spring({
- frame,
- fps,
- config: theme.animation.smooth,
- });
-
- const opacity = interpolate(progress, [0, 1], [0, 1]);
- const translateY = interpolate(progress, [0, 1], [30, 0]);
-
- return (
-
-
- Stop the chaos.
-
-
- );
-};
diff --git a/marketing-videos/src/videos/TheSquad/PollAnimation.tsx b/marketing-videos/src/videos/TheSquad/PollAnimation.tsx
deleted file mode 100644
index 9266eb8..0000000
--- a/marketing-videos/src/videos/TheSquad/PollAnimation.tsx
+++ /dev/null
@@ -1,438 +0,0 @@
-import React from "react";
-import {
- AbsoluteFill,
- useCurrentFrame,
- useVideoConfig,
- spring,
- interpolate,
-} from "remotion";
-import { theme } from "../../components/shared/theme";
-
-type PollOption = {
- game: string;
- league: string;
- votes: { name: string; avatar: string }[];
- percentage: number;
- isWinner?: boolean;
-};
-
-const pollOptions: PollOption[] = [
- {
- game: "Lakers vs Celtics",
- league: "NBA",
- votes: [
- { name: "Mike", avatar: "#FF6B6B" },
- { name: "Sarah", avatar: "#4ECDC4" },
- { name: "Jake", avatar: "#45B7D1" },
- ],
- percentage: 100,
- isWinner: true,
- },
- {
- game: "Dodgers vs Giants",
- league: "MLB",
- votes: [
- { name: "Sarah", avatar: "#4ECDC4" },
- ],
- percentage: 33,
- },
-];
-
-export const PollCreation: React.FC = () => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- const entranceProgress = spring({
- frame,
- fps,
- config: theme.animation.smooth,
- });
-
- const scale = interpolate(entranceProgress, [0, 1], [0.95, 1]);
- const opacity = interpolate(entranceProgress, [0, 1], [0, 1]);
-
- return (
-
-
- {/* Poll card */}
-
- {/* Header */}
-
-
- LA Trip - Which games?
-
-
- Vote for your favorites
-
-
-
- {/* Options */}
-
- {pollOptions.map((option, index) => (
-
-
-
-
- {option.league}
-
-
- {option.game}
-
-
-
- {/* Vote checkbox */}
-
-
-
- ))}
-
-
- {/* Share button */}
-
-
- Share Poll
-
-
-
-
-
- );
-};
-
-export const PollVoting: React.FC = () => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- return (
-
-
- {/* Header */}
-
-
- LA Trip - Which games?
-
-
- 3 votes cast
-
-
-
- {/* Options with votes */}
-
- {pollOptions.map((option, index) => {
- // Animate votes appearing
- const voteDelay = index * fps * 0.3;
-
- return (
-
- {/* Game info */}
-
-
-
- {option.league}
-
-
- {option.game}
-
-
-
- {option.isWinner && (
-
- ✓ Winner
-
- )}
-
-
- {/* Progress bar */}
-
-
- {/* Voter avatars */}
-
-
- );
- })}
-
-
-
- );
-};
-
-type PollProgressBarProps = {
- percentage: number;
- delay: number;
- isWinner?: boolean;
-};
-
-const PollProgressBar: React.FC
= ({
- percentage,
- delay,
- isWinner,
-}) => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- const progress = spring({
- frame: frame - delay,
- fps,
- config: theme.animation.smooth,
- });
-
- const width = interpolate(progress, [0, 1], [0, percentage]);
-
- return (
-
- );
-};
-
-type VoterAvatarsProps = {
- votes: { name: string; avatar: string }[];
- startDelay: number;
-};
-
-const VoterAvatars: React.FC = ({ votes, startDelay }) => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- return (
-
-
- {votes.map((vote, i) => {
- const avatarProgress = spring({
- frame: frame - startDelay - i * 5,
- fps,
- config: theme.animation.snappy,
- });
-
- const scale = interpolate(avatarProgress, [0, 1], [0, 1]);
- const opacity = interpolate(avatarProgress, [0, 1], [0, 1]);
-
- return (
-
0 ? -10 : 0,
- transform: `scale(${scale})`,
- opacity,
- display: "flex",
- justifyContent: "center",
- alignItems: "center",
- }}
- >
-
- {vote.name[0]}
-
-
- );
- })}
-
-
- {votes.length} vote{votes.length > 1 ? "s" : ""}
-
-
- );
-};
diff --git a/marketing-videos/src/videos/TheSquad/ResultsReveal.tsx b/marketing-videos/src/videos/TheSquad/ResultsReveal.tsx
deleted file mode 100644
index a37c271..0000000
--- a/marketing-videos/src/videos/TheSquad/ResultsReveal.tsx
+++ /dev/null
@@ -1,258 +0,0 @@
-import React from "react";
-import {
- AbsoluteFill,
- useCurrentFrame,
- useVideoConfig,
- spring,
- interpolate,
-} from "remotion";
-import { theme } from "../../components/shared/theme";
-
-// Confetti particles
-const Confetti: React.FC = () => {
- const frame = useCurrentFrame();
- const { fps, width, height } = useVideoConfig();
-
- const particles = React.useMemo(() => {
- const colors = [theme.colors.accent, theme.colors.secondary, theme.colors.gold, "#9B59B6"];
- return Array.from({ length: 25 }, (_, i) => ({
- id: i,
- x: Math.random() * width,
- color: colors[Math.floor(Math.random() * colors.length)],
- size: 6 + Math.random() * 10,
- rotation: Math.random() * 360,
- speed: 0.4 + Math.random() * 0.4,
- delay: Math.random() * 8,
- }));
- }, [width]);
-
- return (
- <>
- {particles.map((particle) => {
- const localFrame = frame - particle.delay;
- if (localFrame < 0) return null;
-
- const y = interpolate(
- localFrame,
- [0, fps * 2],
- [-50, height + 100],
- { extrapolateRight: "clamp" }
- ) * particle.speed;
-
- const rotation = particle.rotation + localFrame * 4;
- const opacity = interpolate(
- localFrame,
- [0, fps * 0.3, fps * 1.5, fps * 2],
- [0, 1, 1, 0],
- { extrapolateRight: "clamp" }
- );
-
- return (
-
- );
- })}
- >
- );
-};
-
-export const ResultsReveal: React.FC = () => {
- const frame = useCurrentFrame();
- const { fps } = useVideoConfig();
-
- // Winner card entrance
- const cardProgress = spring({
- frame,
- fps,
- config: { damping: 15, stiffness: 120 },
- });
-
- const cardScale = interpolate(cardProgress, [0, 1], [0.8, 1]);
- const cardOpacity = interpolate(cardProgress, [0, 1], [0, 1]);
-
- // "Democracy wins" text entrance
- const textProgress = spring({
- frame: frame - fps * 0.6,
- fps,
- config: theme.animation.smooth,
- });
-
- const textOpacity = interpolate(textProgress, [0, 1], [0, 1]);
- const textY = interpolate(textProgress, [0, 1], [20, 0]);
-
- return (
-
- {/* Confetti */}
-
-
-
- {/* Winner card */}
-
-
- {/* Winner badge */}
-
-
- {/* Winning game */}
-
-
- NBA
-
-
-
-
- Lakers vs Celtics
-
-
- {/* Vote count */}
-
- {/* Voter avatars */}
-
- {["#FF6B6B", "#4ECDC4", "#45B7D1"].map((color, i) => (
-
0 ? -10 : 0,
- }}
- />
- ))}
-
-
- 3 votes • 100%
-
-
-
-
-
- {/* "Democracy wins" text */}
-
-
- Democracy wins.
-
-
-
-
- );
-};
diff --git a/marketing-videos/src/videos/TheSquad/index.tsx b/marketing-videos/src/videos/TheSquad/index.tsx
deleted file mode 100644
index 84d1d49..0000000
--- a/marketing-videos/src/videos/TheSquad/index.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import React from "react";
-import {
- AbsoluteFill,
- useVideoConfig,
-} from "remotion";
-import { TransitionSeries, linearTiming } from "@remotion/transitions";
-import { fade } from "@remotion/transitions/fade";
-import { slide } from "@remotion/transitions/slide";
-
-import { ChatBubbles, StopTheChaos } from "./ChatBubbles";
-import { PollCreation, PollVoting } from "./PollAnimation";
-import { ResultsReveal } from "./ResultsReveal";
-import {
- GradientBackground,
- LogoEndcard,
- TextReveal,
- theme,
-} from "../../components/shared";
-
-/**
- * Video 4: "The Squad"
- *
- * Goal: Promote group polling feature, position app for friend group planning
- * Length: 18 seconds (540 frames at 30fps)
- *
- * Scene breakdown:
- * - 0:00-0:02 (0-60): Chat bubbles chaos
- * - 0:02-0:05 (60-150): "Stop the chaos" + Poll creation
- * - 0:05-0:09 (150-270): Votes animating in
- * - 0:09-0:13 (270-390): Results reveal with confetti
- * - 0:13-0:16 (390-480): Trip planned text
- * - 0:16-0:18 (480-540): Logo endcard
- */
-export const TheSquad: React.FC = () => {
- const { fps } = useVideoConfig();
-
- const TRANSITION_DURATION = 12;
-
- const SCENE_DURATIONS = {
- chatBubbles: 2.5 * fps, // 75 frames
- stopChaos: 1 * fps, // 30 frames
- pollCreation: 2 * fps, // 60 frames
- pollVoting: 3 * fps, // 90 frames
- results: 3.5 * fps, // 105 frames
- tripPlanned: 2.5 * fps, // 75 frames
- logo: 3.5 * fps, // 105 frames
- };
-
- return (
-
-
-
-
- {/* Scene 1: Chat bubbles chaos */}
-
-
-
-
-
-
- {/* Scene 2: "Stop the chaos" */}
-
-
-
-
-
-
- {/* Scene 3: Poll creation UI */}
-
-
-
-
-
-
- {/* Scene 4: Votes animating in */}
-
-
-
-
-
-
- {/* Scene 5: Results reveal with confetti */}
-
-
-
-
-
-
- {/* Scene 6: Trip planned text */}
-
-
-
-
-
-
-
-
- {/* Scene 7: Logo endcard */}
-
-
-
-
-
- );
-};
diff --git a/marketing-videos/tsconfig.json b/marketing-videos/tsconfig.json
deleted file mode 100644
index ef73a5c..0000000
--- a/marketing-videos/tsconfig.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2022",
- "module": "ES2022",
- "moduleResolution": "bundler",
- "jsx": "react-jsx",
- "strict": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- "resolveJsonModule": true,
- "declaration": true,
- "declarationMap": true,
- "noEmit": true,
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
- "baseUrl": ".",
- "paths": {
- "@/*": ["src/*"]
- }
- },
- "include": ["src/**/*", "remotion.config.ts"],
- "exclude": ["node_modules", "out"]
-}