/* Vooice — Marketing landing page (expanded) */ function MarketingHero({ width = 1320, height = 880, onNavigate }) { const go = (k) => onNavigate && onNavigate(k); const NAV_ITEMS = [ { l: 'Memory', k: 'contacts-memory' }, { l: 'Pricing', k: 'pricing' }, { l: 'Live demo', k: 'home' }, ]; return (
); } // ── Top nav ─────────────────────────────────────────────────────────────── function TopNav({ nav, go }) { return (
go('about')} style={{ cursor:'pointer' }}>
{nav.map(it => ( go(it.k)} style={{ fontSize: 14, color: VC_TOKENS.ink2, cursor:'pointer' }}>{it.l} ))}
); } // ── Hero ────────────────────────────────────────────────────────────────── function Hero({ go }) { return (
PHONE‑FIRST · INVITE BETA · APR 2026

The assistant
you can call.

Dial Vooice from any phone. Ask her to call your dentist, your contractor, your mom. She picks up, makes the call, repeats the details back, gets it done.
STACK · CLAUDE · ELEVENLABS · DEEPGRAM · LIVEKIT · TWILIO
{/* Right — physical "call card" */}
OUTBOUND · LIVE 00:42
Bayview Hair Studio
Calling for Jordan Reyes · Hayes Valley
"Thursday at 2 with Marcus, 45 minutes — confirming with Jordan's calendar before I commit."
SLOT READ‑BACK CONFIRM ✓
HONEST ABOUT BEING AI
); } // ── Section header utility ──────────────────────────────────────────────── function SectionEyebrow({ kicker, title, italic }) { return (
{kicker}

{title}{italic && ( <> {italic} )}

); } // ── How it works (integrated from /how) ─────────────────────────────────── function HowItWorksSection({ go }) { const STEPS = [ { n:'01', title:'You call her, or text her.', body:'Phone, Telegram, WhatsApp. Voice or text. Whatever surface you\u2019re on.', art:'self' }, { n:'02', title:'She figures out what to do.', body:'Reads your calendar, your inbox, your contacts, what she remembers. Picks the right tools.', art:'memory' }, { n:'03', title:'She does the thing.', body:'Calls people. Sends emails. Books appointments. Repeats key details back to confirm.', art:'phone' }, { n:'04', title:'She tells you what happened.', body:'A voice note, a text, a card on the dashboard. Whichever channel suits the moment.', art:'card' }, ]; return (
{STEPS.map((s, i) => (
{s.n}
{s.title}
{s.body}
))}
); } function StepArt({ kind }) { if (kind === 'self') return (
); if (kind === 'memory') return (
{[0,1,2].map(i => (
{['contact: lina','calendar.read','tool.dial'][i]}
))}
); if (kind === 'phone') return (
"Hi Marcus, this is Vooice…"
); return (
BOOKED
Thu 2pm · Marcus Wu
Added to calendar
); } // ── Use cases ───────────────────────────────────────────────────────────── function UseCasesSection() { const CASES = [ { tag: 'THE BOOKER', who: 'For people who hate phone tag.', head: '"Book me a haircut Thursday after 1."', body: 'She finds your usual barber, dials, holds the line, negotiates the slot, repeats it back, drops it on your calendar. You never picked up the phone.', stamp: 'SAVES 14 MIN/WEEK', rotate: -1.2, }, { tag: 'THE TRIAGER', who: 'For people whose inbox is a fire.', head: '"What\u2019s urgent today?"', body: 'She reads everything. Surfaces 3 things that need you. Drafts the answers. You confirm or correct. The rest she handles or files.', stamp: 'INBOX ZERO BY 10AM', rotate: 1.4, }, { tag: 'THE FAMILY OPS', who: 'For people running a household.', head: '"Tell Mom dinner Sunday at 6."', body: 'She remembers Mom\u2019s number, her preferred channel (a call, not a text), the dynamic ("don\u2019t mention work stress"). She sends the note. She tells you it landed.', stamp: 'KEEPS YOU PRESENT', rotate: -0.8, }, { tag: 'THE GATEKEEPER', who: 'For people who answer too many calls.', head: '"Pick up for me. Decide if it matters."', body: 'Forward unknowns to your Vooice number. She answers, screens, takes a message, transcribes. If it\u2019s real, she pings you. If it\u2019s spam, she hangs up.', stamp: 'BLOCKS 41 SPAM/MO', rotate: 1.0, }, ]; return (
She’s the same assistant — she just shows up differently depending on what your day needs.
{CASES.map((c, i) => (
{c.tag}
{c.who}
{c.head}
{c.body}
{c.stamp}
))}
); } // ── Live transcript demo (animated) ─────────────────────────────────────── function LiveTranscriptDemo() { const SCRIPT = [ { t: 0, sp: 'callee', who: 'MARCUS', body: 'Bayview Hair, this is Marcus.' }, { t: 2.2, sp: 'vooice', who: 'VOOICE', body: 'Hi Marcus — this is Vooice, I\u2019m an AI calling on behalf of Jordan Reyes.' }, { t: 6.0, sp: 'vooice', who: 'VOOICE', body: 'Looking to book a cut, ideally Thursday after 1pm with you specifically.' }, { t: 10.0, sp: 'callee', who: 'MARCUS', body: 'I\u2019ve got 2pm Thursday, 45 minutes. Works?' }, { t: 13.0, sp: 'vooice', who: 'VOOICE', body: 'Reading back: Thursday 2pm, 45 minutes, with Marcus. Confirming with Jordan\u2019s calendar — one second.' }, { t: 18.0, sp: 'vooice', who: 'VOOICE', body: 'Confirmed. Booked. Should I have him bring anything?' }, { t: 22.0, sp: 'callee', who: 'MARCUS', body: 'Just himself. We\u2019re good.' }, { t: 24.0, sp: 'vooice', who: 'VOOICE', body: 'Thank you, Marcus. Have a good one.' }, ]; const TOTAL = 28; const [tSec, setTSec] = React.useState(0); React.useEffect(() => { const id = setInterval(() => { setTSec(t => (t + 0.1) % TOTAL); }, 100); return () => clearInterval(id); }, []); const visible = SCRIPT.filter(l => l.t <= tSec + 0.05); const current = visible[visible.length - 1]; return (
LIVE DEMO · NOT A RECORDING

What it sounds like when she calls.

{/* Transcript */}
● LIVE · {Math.floor(tSec).toString().padStart(2,'0')}:{Math.floor((tSec*10)%10)}{Math.floor((tSec*100)%10)} BAYVIEW HAIR · MARCUS WU
{[...visible].reverse().slice(0, 4).map((l, i) => { const isVooice = l.sp === 'vooice'; const isCurrent = i === 0; return (
{l.who}
{l.body}
); })}
{/* Side rail — what she's doing */}
RIGHT NOW SHE'S
{current?.sp === 'vooice' ? 'Speaking.' : 'Listening.'}
TOOL CALLS
{[ { t: 6, label: 'calendar.read · jordan' }, { t: 13, label: 'slot.readback · thu 2pm' }, { t: 18, label: 'calendar.write · 45min · marcus' }, ].map(tc => (
= tc.t ? '#2a2724' : 'transparent', border: `1px solid ${tSec >= tc.t ? '#3a3530' : '#2a2724'}`, color: tSec >= tc.t ? VC_TOKENS.paper : '#666', transition: 'all 200ms ease', }}> {tSec >= tc.t ? '✓ ' : '○ '}{tc.label}
))}
OUTCOME
{tSec >= 18 ? '"Booked Thu 2pm w/ Marcus."' : 'In progress…'}
); } // ── Memory section ──────────────────────────────────────────────────────── function MemorySection({ go }) { const MEMORIES = [ { who: 'MOM', body: 'Prefers a phone call to a text. Don\u2019t mention work stress. Birthday May 4.', tone: 'butter' }, { who: 'LINA', body: 'Wednesday afternoons only. Husband Pete. Daughter Eli, kindergarten 2026.', tone: 'sage' }, { who: 'DR. HAN\u2019S OFFICE', body: 'Front desk is Maria. They take calls 8\u201311 and 1\u20134, Pacific. Annual physical due April.', tone: 'paper' }, { who: 'BAYVIEW HAIR', body: 'Marcus is your barber. 45 minutes. Walk-ins only Tuesday.', tone: 'signalSoft' }, ]; return (
Vooice keeps a private memory of the people in your life — how they prefer to be reached, what they care about, what you’ve told her not to say. You can read every line of it. You can edit it. You can delete it.
{[ 'Yours alone. Not used to train models.', 'Source-traced. Every fact links to the call, message, or note it came from.', 'Forgettable. Tell her to forget something. She does.', ].map((p, i) => (
{p}
))}
{/* Memory cards collage */}
{MEMORIES.map((m, i) => { const tones = { butter: { bg: VC_TOKENS.butter, fg: VC_TOKENS.ink, sh: VC_TOKENS.ink }, sage: { bg: VC_TOKENS.sage, fg: VC_TOKENS.paper, sh: VC_TOKENS.ink }, paper: { bg: VC_TOKENS.paper, fg: VC_TOKENS.ink, sh: VC_TOKENS.signal }, signalSoft: { bg: VC_TOKENS.signalSoft, fg: VC_TOKENS.ink, sh: VC_TOKENS.ink }, }; const tone = tones[m.tone]; const rot = [(-1.5), (1.4), (1.0), (-1.2)][i]; return (
{m.who}
{m.body}
); })}
); } // ── Trust & safety ──────────────────────────────────────────────────────── function TrustSection() { const COMMITMENTS = [ { t: 'She will not impersonate you.', b: 'When she calls on your behalf she identifies herself as an AI and names you as the person she\u2019s calling for. Always. The first thing out of her mouth.', icon: 'identity', }, { t: 'She will not train on your data.', b: 'Your calls, your messages, your memory — yours. Not in any training set, not shared with model providers for improvement, not seen by us beyond what\u2019s needed to deliver the service.', icon: 'lock', }, { t: 'She will dial you in if asked.', b: 'Any party on a call can ask "can I talk to a human?" and she\u2019ll bridge you in or end the call and ping you. No chatbot loops. No "I\u2019m sorry, I can\u2019t do that."', icon: 'bridge', }, { t: 'She will read back before writing.', b: 'Before she books, sends, replies, or commits — she repeats the key details out loud, in plain language, and waits for confirmation. Slot read-back is a safety feature, not a flourish.', icon: 'readback', }, ]; return (
A voice that calls people on your behalf is a serious thing. We took the boundaries seriously and put them in writing. Pinned to the wall. Hard to move.
{COMMITMENTS.map((c, i) => (
{c.t}
{c.b}
))}
); } function PromiseIcon({ kind }) { const sz = 56; const stroke = VC_TOKENS.ink; const accent = VC_TOKENS.signal; if (kind === 'identity') return ( ); if (kind === 'lock') return ( ); if (kind === 'bridge') return ( ); return ( ); } // ── FAQ ─────────────────────────────────────────────────────────────────── function FAQSection() { const QS = [ { q: 'What does it cost?', a: 'Free for the first 200 minutes a month while we\u2019re in beta. Pricing tiers go live this summer; existing users keep beta pricing for a year.', }, { q: 'Whose voice does she use?', a: 'A neutral, warm voice we built with ElevenLabs. You\u2019ll be able to pick from a small set of voices later, but never one cloned from you. We won\u2019t do that even if you ask.', }, { q: 'What if she gets it wrong on a call?', a: 'She\u2019ll say so. Her instructions tell her to admit confusion, repeat back, and offer to bring you in. The slot read-back catches most errors before they commit. The audit log catches the rest.', }, { q: 'Does she record the calls?', a: 'Yes, with consent — she announces recording at the start and stores them encrypted, accessible only to you. Two-party-consent states get an explicit prompt; one-party states get a notification.', }, { q: 'Can I bring my own phone number?', a: 'Not yet. Today every user gets a Vooice number in their area code. Number porting is on the roadmap.', }, ]; return (
{QS.map((item, i) => )}
); } function FAQItem({ q, a, startOpen }) { const [open, setOpen] = React.useState(!!startOpen); return (
{open && (
{a}
)}
); } // ── CTA + Footer ────────────────────────────────────────────────────────── function CTAFooter({ go }) { return ( <>
READY TO TRY HER?

Get a phone number
that thinks.

Beta is invite-only and free for 200 minutes a month. Drop your number; we’ll text you when your line is provisioned.
WAITLIST · 90 SECONDS
We text once when your line is ready. Never sold, never spammed.
{/* Bottom commitments strip */}
{[ 'WILL NOT IMPERSONATE', 'WILL NOT TRAIN ON YOUR DATA', 'WILL DIAL YOU IN', 'WILL READ BACK', ].map((t, i, arr) => ( {t} {i < arr.length - 1 && } ))}
{/* Footer */} ); } function FooterCol({ title, links, go }) { return (
{title}
{links.map(l => ( l.k && go && go(l.k)} style={{ fontSize: 14, color: VC_TOKENS.ink, cursor: l.k ? 'pointer' : 'default' }} > {l.l} ))}
); } window.MarketingHero = MarketingHero;