// receptionist-portrait.jsx — AI Receptionist, portrait (1080×1920) edition // Relies on globals from scenes.jsx + animations.jsx: // TERRA, SANS, MONO, HUD, Sprite, clamp, Easing // ───────────────────────── Scene 1P: Ringing (portrait) ─────────────────────── function SceneRingingP({ start, end }) { return ( {({ localTime, duration }) => { const ringT = localTime % 1.0; const ringScale = 1 + Math.exp(-ringT * 4) * 0.3; const exitP = clamp((localTime - (duration - 0.5)) / 0.45, 0, 1); const op = 1 - exitP; return (
{/* Top: caller */}
INCOMING CALL
+1 (314) 555
0 1 8 4
ST. LOUIS · MO · 11:47 PM
{/* Middle: ring rings + phone */}
{[0, 0.3, 0.6].map((offset, i) => { const t = (localTime - offset) % 1.2; if (t < 0) return null; const s = 0.4 + t * 1.4; const o = Math.max(0, 1 - t * 0.9); return (
); })} {/* Phone icon */}
{/* Bottom: OLD WAY / VOICEMAIL */}
OLD WAY
VOICEMAIL
15 CALLS LOST/DAY → $0
); }} ); } // ───────────────────────── Scene 2P: Call In Progress (portrait) ────────────── function SceneCallInProgressP({ start, end }) { return ( {({ localTime, duration }) => { const transcript = [ { at: 0.3, who: 'AI', text: "Good evening, Prestige Home Services. How can I help?" }, { at: 2.0, who: 'HU', text: "Hey — my water heater just burst, I need someone tonight." }, { at: 4.0, who: 'AI', text: "Got it. I can book an emergency tech. What's the address?" }, { at: 5.8, who: 'HU', text: "4412 Maple Grove Ave, St. Louis." }, { at: 7.3, who: 'AI', text: "Logging that. Nearest available technician: Marcus — ETA 34 minutes." }, { at: 9.2, who: 'AI', text: "You'll get a text confirmation. Anything else?" }, ]; const headerP = clamp(localTime / 0.5, 0, 1); const exitP = clamp((localTime - (duration - 0.5)) / 0.45, 0, 1); const op = 1 - exitP; const barCount = 40; const talking = transcript.some(m => localTime > m.at && localTime < m.at + 1.5); return (
{/* Header row */}
LIVE — AI RECEPTIONIST
{Math.floor(localTime * 10) / 10}s
{/* Stacked: waveform block + transcript block */}
{/* Waveform */}
AUDIO STREAM · 16KHZ
{Array.from({ length: barCount }, (_, i) => { const seed = Math.sin(i * 12.9898) * 43758.5453; const base = (seed - Math.floor(seed)); const phase = localTime * 8 + i * 0.4; const amp = talking ? (0.3 + base * 0.7) : 0.08; const h = (0.3 + Math.abs(Math.sin(phase)) * 0.7) * amp * 150; return (
); })}
{/* Stats cards — 2 columns */}
{[ { l: 'RESPONSE TIME', v: '0.2s' }, { l: 'LANGUAGE', v: 'EN-US' }, { l: 'INTENT', v: 'BOOKING' }, { l: 'SENTIMENT', v: 'URGENT' }, ].map((s, i) => (
{s.l}
{s.v}
))}
{/* Transcript */}
LIVE TRANSCRIPT
{transcript.map((m, i) => { const p = clamp((localTime - m.at) / 0.4, 0, 1); if (p <= 0) return null; const isAI = m.who === 'AI'; return (
{isAI ? '● TERRA AI' : '○ CALLER'}
{m.text}
); })}
); }} ); } // ───────────────────────── Scene 3P: Booked (portrait) ──────────────────────── function SceneBookedP({ start, end }) { return ( {({ localTime, duration }) => { const p1 = clamp(localTime / 0.5, 0, 1); const p2 = clamp((localTime - 0.5) / 0.5, 0, 1); const p3 = clamp((localTime - 1.2) / 0.6, 0, 1); const p4 = clamp((localTime - 2.0) / 0.6, 0, 1); const p5 = clamp((localTime - 2.8) / 0.5, 0, 1); const p6 = clamp((localTime - 3.6) / 0.5, 0, 1); const exitP = clamp((localTime - (duration - 0.5)) / 0.45, 0, 1); const op = 1 - exitP; const checkDraw = Easing.easeOutExpo(p2); return (
{/* Header */}
CALL COMPLETE · 00:11 · BOOKED
{/* Check icon */}
{/* Headline */}
LEAD
CAPTURED.
{/* Subtitle */}
Booked, confirmed, routed to your tech — in 11 seconds.
{/* Ticket — full width */}
WORK ORDER
#WO-41829
{[ { k: 'CUSTOMER', v: 'J. Chen' }, { k: 'ISSUE', v: 'Water heater burst' }, { k: 'ADDRESS', v: '4412 Maple Grove Ave' }, { k: 'PRIORITY', v: 'EMERGENCY', accent: true }, { k: 'ASSIGNED', v: 'Marcus R. · Van 03' }, { k: 'ETA', v: '34 minutes' }, ].map((r, i) => (
{r.k}
{r.v}
))}
SMS SENT
✓ 11:47 PM
{/* Bottom tagline */}
YOUR FRONT DESK.
UPGRADED.
— 24/7 · ZERO MISSED CALLS
); }} ); } Object.assign(window, { SceneRingingP, SceneCallInProgressP, SceneBookedP });