import React from "react"; import { useCurrentFrame, useVideoConfig, interpolate, spring, Sequence, Easing, } from "remotion"; import { palette } from "./contract"; const bg = palette.background; const fg = palette.foreground; const accent = palette.accent; const secondary = palette.secondary; const muted = palette.muted; const SAFE = 80; function IntroSection() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const titleSpring = spring({ frame, fps, config: { damping: 12, stiffness: 80 } }); const titleY = interpolate(titleSpring, [0, 1], [60, 0]); const titleOpacity = interpolate(titleSpring, [0, 1], [0, 1]); const taglineDelay = 20; const taglineSpring = spring({ frame: frame - taglineDelay, fps, config: { damping: 14, stiffness: 60 } }); const taglineOpacity = interpolate(taglineSpring, [0, 1], [0, 1]); const taglineY = interpolate(taglineSpring, [0, 1], [30, 0]); const lineWidth = interpolate(frame, [10, 50], [0, 320], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const fadeOut = interpolate(frame, [70, 89], [1, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); return (
Relay
Make room for focused work
); } function FeatureCard({ label, icon, delay, color, }: { label: string; icon: React.ReactNode; delay: number; color: string; }) { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const cardSpring = spring({ frame: frame - delay, fps, config: { damping: 13, stiffness: 70 } }); const cardY = interpolate(cardSpring, [0, 1], [80, 0]); const cardOpacity = interpolate(cardSpring, [0, 1], [0, 1]); return (
{icon}
{label}
); } function PlanTogetherUI() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const cards = [0, 1, 2, 3, 4]; const baseDelay = 10; return (
{cards.map((i) => { const s = spring({ frame: frame - baseDelay - i * 6, fps, config: { damping: 12, stiffness: 90 } }); const h = interpolate(s, [0, 1], [0, 40 + i * 20]); return (
); })}
); } function FocusTimeUI() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const shieldScale = spring({ frame: frame - 5, fps, config: { damping: 10, stiffness: 60 } }); const ringProgress = interpolate(frame, [10, 50], [0, 270], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const circumference = 2 * Math.PI * 44; const dashOffset = circumference - (ringProgress / 360) * circumference; return (
◈
); } function ProgressUI() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const bars = [0.85, 0.6, 0.95, 0.4]; const colors = [accent, secondary, accent, secondary]; return (
{bars.map((target, i) => { const progress = interpolate(frame, [10 + i * 8, 50 + i * 8], [0, target], { extrapolateLeft: "clamp", extrapolateRight: "clamp", }); return (
); })}
); } function FeaturesSection() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const fadeIn = interpolate(frame, [0, 15], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const fadeOut = interpolate(frame, [165, 179], [1, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const feature1Spring = spring({ frame: frame - 5, fps, config: { damping: 13, stiffness: 70 } }); const feature2Spring = spring({ frame: frame - 15, fps, config: { damping: 13, stiffness: 70 } }); const feature3Spring = spring({ frame: frame - 25, fps, config: { damping: 13, stiffness: 70 } }); const f1y = interpolate(feature1Spring, [0, 1], [60, 0]); const f1o = interpolate(feature1Spring, [0, 1], [0, 1]); const f2y = interpolate(feature2Spring, [0, 1], [60, 0]); const f2o = interpolate(feature2Spring, [0, 1], [0, 1]); const f3y = interpolate(feature3Spring, [0, 1], [60, 0]); const f3o = interpolate(feature3Spring, [0, 1], [0, 1]); const headingSpring = spring({ frame: frame - 2, fps, config: { damping: 14, stiffness: 80 } }); const headingOpacity = interpolate(headingSpring, [0, 1], [0, 1]); return (
Built for your team
Plan together
Align on priorities in one shared space
Protect focus time
Guard deep-work blocks automatically
See progress
Track momentum without micromanaging
); } function OutroSection() { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const titleSpring = spring({ frame, fps, config: { damping: 12, stiffness: 70 } }); const titleY = interpolate(titleSpring, [0, 1], [40, 0]); const titleOpacity = interpolate(titleSpring, [0, 1], [0, 1]); const subDelay = 15; const subSpring = spring({ frame: frame - subDelay, fps, config: { damping: 14, stiffness: 60 } }); const subOpacity = interpolate(subSpring, [0, 1], [0, 1]); const subY = interpolate(subSpring, [0, 1], [20, 0]); const accentWidth = interpolate(frame, [5, 40], [0, 200], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const glowPulse = interpolate(frame, [30, 60, 90], [0, 1, 0.7], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); return (
Start your next week
with{" "} Relay
relay.app
); } export function BenchmarkVideo() { const frame = useCurrentFrame(); const { fps, durationInFrames } = useVideoConfig(); const bgOpacity = interpolate(frame, [0, 10], [0, 1], { extrapolateRight: "clamp" }); const gridOpacity = interpolate(frame, [0, 30], [0, 0.04], { extrapolateRight: "clamp" }); return (
{/* Subtle grid background */}
{/* Ambient glow */}
); }