/** * Slide — reusable single-slide renderer for Remotion compositions. * * Uses inline styles only (no Tailwind — Remotion bundles in isolation). * Style: dark gradient (#0f172a → #1e293b), white text, emerald accent (#10b981). */ import React from 'react'; import { AbsoluteFill, useCurrentFrame, interpolate } from 'remotion'; // ─── Types ────────────────────────────────────────────────────────────────── export interface SlideData { type: 'cover' | 'key_point' | 'steps' | 'statistic' | 'quote' | 'cta'; title: string; subtitle?: string; content?: string; items?: string[]; value?: string; label?: string; author?: string; cta_text?: string; background_style?: string; } // ─── Palette ──────────────────────────────────────────────────────────────── const ACCENT = '#10b981'; const TEXT = '#ffffff'; const MUTED = 'rgba(255,255,255,0.6)'; const FONT = '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; // ─── Slide ────────────────────────────────────────────────────────────────── /** * Renders a single slide with a fade-in + slide-up entrance animation. * Meant to be used inside a in ShipVideo/AdVideo. */ export const Slide: React.FC<{ slide: SlideData }> = ({ slide }) => { const frame = useCurrentFrame(); const opacity = interpolate(frame, [0, 15], [0, 1], { extrapolateRight: 'clamp' }); const y = interpolate(frame, [0, 15], [24, 0], { extrapolateRight: 'clamp' }); return ( ); }; // ─── Slide content by type ────────────────────────────────────────────────── function SlideContent({ slide }: { slide: SlideData }) { switch (slide.type) { case 'cover': return ( <>
{slide.subtitle || 'Just Shipped'}

{slide.title}

); case 'key_point': return ( <>
{slide.title}

{slide.content}

); case 'steps': return ( <>
{slide.title}
{(slide.items || []).map((item, i) => (
{i + 1}
{item}
))}
); case 'statistic': return ( <>
{slide.title}
{slide.value || '—'}
{slide.label}
); case 'quote': return ( <>

“{slide.content}”

{slide.author &&
— {slide.author}
} ); case 'cta': return ( <> {slide.subtitle && (
{slide.subtitle}
)}

{slide.title}

{slide.cta_text || 'Get Started'}
); default: return
{slide.title}
; } }