'use client'; import { AnimatePresence, motion } from 'framer-motion'; import { ArrowRight, Dices, Wand2 } from 'lucide-react'; import { useEffect, useState } from 'react'; // ─── Modes ────────────────────────────────────────────────────────────────── type Mode = { id: 'compose' | 'rewrite'; label: string; icon: typeof Dices; outputLabel: string; output: string; } & ( | { inputLabel: string; input: string } | { inputLabel?: undefined; input?: undefined } ); const MODES: Mode[] = [ { id: 'rewrite', label: 'Rewrite', icon: Wand2, inputLabel: 'Your text', outputLabel: "Marlowe, in character", input: 'the build is done and we shipped to production', output: "Build's wrapped, ship's left the dock. Another stack of code makes its way into prod, another row of green checks lining the wall.", }, { id: 'compose', label: 'Compose', icon: Dices, outputLabel: "Marlowe, in character", output: "She came through clean. Not a single test casting a shadow. In this town, that's usually when you start worrying.", }, ]; const PERSONA_DESCRIPTION = "1940s noir detective. World-weary, cynical, every situation a metaphor for the city's underbelly. Talks like he's seen one stack trace too many."; // ─── Persona card ─────────────────────────────────────────────────────────── function PersonaCard() { return (
Marlowe
Voice profile · cloned from a 12s sample
Personality

“{PERSONA_DESCRIPTION}”

); } // ─── Mode demo ────────────────────────────────────────────────────────────── function ModeDemo({ mode, cycleKey }: { mode: Mode; cycleKey: number }) { return (
{/* Mode tabs */}
{MODES.map((m) => { const Icon = m.icon; const active = m.id === mode.id; return (
{m.label}
); })}
{/* Input → Output */}
{/* Input */} {mode.input ? (
{mode.inputLabel}
{mode.input}
) : (
No input
Click Compose — the character improvises a fresh line.
)} {/* Arrow */}
In character
{/* Output */}
{mode.outputLabel}
“{mode.output}”
); } // ─── Bullets ──────────────────────────────────────────────────────────────── const BULLETS = [ { icon: Wand2, title: 'Rewrite', description: 'Restate your text in their voice while preserving every idea. Same content, their delivery — for scripts, dubs, and consistent character voice across long-form work.', }, { icon: Dices, title: 'Compose', description: 'No input needed — hit the button and the character improvises a fresh line of their own. Roll again for another take. Useful for game dialogue, narration cues, or character barks.', }, ]; // ─── Section ──────────────────────────────────────────────────────────────── export function Personalities() { const [idx, setIdx] = useState(0); useEffect(() => { const iv = window.setInterval(() => { setIdx((i) => (i + 1) % MODES.length); }, 4500); return () => window.clearInterval(iv); }, []); const mode = MODES[idx]; return (
{/* Header */}
Personalities

Voices with a personality.

Give any voice profile a free-form personality. Then{' '} Rewrite your text in their voice, or let them{' '} Compose a fresh line of their own — your cloned voice, in full character.

{/* Mockup: persona card (left) + mode demo (right) */}
{/* Bullets */}
{BULLETS.map((bullet) => { const Icon = bullet.icon; return (

{bullet.title}

{bullet.description}

); })}
); }