// waiv-home-sections.jsx — homepage sections built on the Direction-B system. // Reuses WaivCard3D, WAIV_FINISHES, the .wv-phone mockup, buttons & eyebrows. const { useState, useEffect, useRef } = React; /* ── minimal stroked icon set ── */ const ICON_PATHS = { user: 'M5 20a7 7 0 0 1 14 0 M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8', share: 'M6 12a3 3 0 1 0 0-.01 M18 6a3 3 0 1 0 0-.01 M18 18a3 3 0 1 0 0-.01 M8.6 10.6l6.8-3.4 M8.6 13.4l6.8 3.4', card: 'M3 7h18v11H3z M3 10h18', grid: 'M4 4h7v7H4z M13 4h7v7h-7z M13 13h7v7h-7z M4 13h7v7H4z', calendar: 'M4 6h16v15H4z M4 10h16 M8 3v4 M16 3v4', wifi: 'M3 9a15 15 0 0 1 18 0 M6 12.5a10 10 0 0 1 12 0 M9 16a5 5 0 0 1 6 0 M12 19.5h.01', link: 'M9.5 14.5l5-5 M8 11l-2 2a3.5 3.5 0 0 0 5 5l2-2 M16 13l2-2a3.5 3.5 0 0 0-5-5l-2 2', chart: 'M4 20V4 M4 20h16 M8 16v-4 M12 16V8 M16 16v-7', edit: 'M4 20h4l10-10-4-4L4 16z M14 6l4 4', refresh: 'M4 11a8 8 0 0 1 14-5l2 2 M20 13a8 8 0 0 1-14 5l-2-2 M18 3v5h-5 M6 21v-5h5', users: 'M3 20a6 6 0 0 1 12 0 M9 11a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7 M16 7a3 3 0 0 1 1 5.8 M16.5 14a6 6 0 0 1 4.5 6', shield: 'M12 3l8 3v5c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V6z M9 12l2 2 4-4', building: 'M5 21V4h9v17 M14 9h5v12 M8 8h3 M8 12h3 M8 16h3 M17 13h0 M17 17h0', bolt: 'M13 3L5 13h6l-1 8 8-11h-6z', arrow: 'M5 12h14 M13 6l6 6-6 6', }; function Ico({ n }) { return ( ); } function Kicker({ children }) { return
{children}
; } /* ───────── marquee trust strip ───────── */ function TrustStrip() { const names = ['Founders', 'Realtors', 'Photographers', 'Consultants', 'Creators', 'Recruiters', 'Architects', 'Freelancers']; const loop = [...names, ...names]; return (
The handshake, upgraded — for the people who live on introductions
{loop.map((n, i) => {n})}
); } /* ───────── how it works ───────── */ function HowItWorks() { const [active, setActive] = useState(0); const steps = [ { t: 'Tap your waiv to any phone', d: 'Hold the card near the top of any modern smartphone. The NFC chip wakes instantly — no app, no QR scanner, no pairing.' }, { t: 'Your Onelynk profile opens', d: 'A beautiful full-screen profile appears in their browser within a second: your photo, links, socials and a one-tap save-contact button.' }, { t: 'They keep you — for good', d: 'One tap saves your details straight to their phone. Update your profile anytime; every card you ever handed out updates with it.' }, ]; useEffect(() => { const id = setInterval(() => setActive(a => (a + 1) % 3), 3800); return () => clearInterval(id); }, []); return (
HOW IT WORKS

Three seconds from stranger to saved.

{steps.map((s, i) => (
setActive(i)}>
0{i + 1}

{s.t}

{s.d}

))}
⚡ Received via waiv
Save contact
); } /* ───────── card / finishes deep-dive ───────── */ function FinishShowcase() { const [finish, setFinish] = useState('sapphire'); const tiltRef = useRef(null); useEffect(() => { const el = tiltRef.current; if (!el) return; const cur = { rx: 6, ry: -20 }, tgt = { rx: 6, ry: -20 }; let raf; const onMove = (e) => { const r = el.getBoundingClientRect(); const nx = (e.clientX - (r.left + r.width / 2)) / window.innerWidth; const ny = (e.clientY - (r.top + r.height / 2)) / window.innerHeight; tgt.ry = -18 + nx * 26; tgt.rx = 6 - ny * 16; }; const loop = () => { cur.rx += (tgt.rx - cur.rx) * 0.08; cur.ry += (tgt.ry - cur.ry) * 0.08; el.style.transform = `rotateX(${cur.rx.toFixed(2)}deg) rotateY(${cur.ry.toFixed(2)}deg) rotateZ(2deg)`; raf = requestAnimationFrame(loop); }; window.addEventListener('pointermove', onMove); raf = requestAnimationFrame(loop); return () => { window.removeEventListener('pointermove', onMove); cancelAnimationFrame(raf); }; }, []); const cfg = WAIV_FINISHES[finish]; return (
THE CARD

A first impression with real weight.

Each waiv is a precision-finished card with a secure NFC chip embedded inside. Pick a finish — then carry an object people actually want to hold.

FINISHES
{WAIV_FINISH_ORDER.map(id => (

{cfg.name}

0{WAIV_FINISH_ORDER.indexOf(finish) + 1} / 0{WAIV_FINISH_ORDER.length}

Chip

NTAG 424 DNAAES-encrypted, tamper-proof

Antenna

13.56 MHzcopper coil, full-card

Print

UV high-buildraised, scratch-resistant

Taps

Unlimitedno subscription to share

); } /* ───────── everything you can share — bento ───────── */ function ShareGrid() { const tiles = [ { ico: 'user', t: 'Contacts', d: 'Name, number, email and address saved in one tap — straight into their phone.', cls: 'span2', chips: ['vCard', 'Apple Wallet', 'Google'] }, { ico: 'share', t: 'Socials', d: 'Every handle, one place.', cls: '' }, { ico: 'card', t: 'Payments', d: 'Get paid on the spot.', cls: '', chips: ['Venmo', 'PayPal', 'Cash App'] }, { ico: 'grid', t: 'Portfolio & links', d: 'Showcase your work, menu, booking page or storefront — anything with a URL lives on your profile.', cls: 'span2 row2', big: true }, { ico: 'calendar', t: 'Booking', d: 'Drop a calendar link and let people book you right after they tap.', cls: '' }, { ico: 'wifi', t: 'Wi-Fi & more', d: 'Guest Wi-Fi, reviews, PDFs.', cls: '' }, ]; return (
ONE TAP, EVERYTHING

Share whatever matters most.

Your waiv isn't just a contact card. Mix and match what people see — and reorder it any time from your phone.

{tiles.map((t, i) => (

{t.t}

{t.d}

{t.chips &&
{t.chips.map(c => {c})}
}
))}
); } /* ───────── Onelynk digital profile ───────── */ function Onelynk() { const feats = [ { ico: 'edit', t: 'Edit once, update everywhere', p: 'Change a job, a number, a link — every card you handed out reflects it instantly. Paper business cards can’t.' }, { ico: 'chart', t: 'See who you’re connecting with', p: 'Live analytics on taps, profile views and saved contacts — know which rooms are working.' }, { ico: 'bolt', t: 'No app for anyone', p: 'Your profile is just a web link. The person tapping needs nothing installed, ever.' }, ]; return (
ONELYNK

One link that is you.

Every waiv points to your Onelynk — a living profile you control from your phone.

{feats.map((f, i) => (

{f.t}

{f.p}

))}
1.2k
profile
views
+318
contacts
saved

Maya Okafor

Product Designer · Studio North

⚡ via waiv
Portfoliomaya.design
Book a coffeecal.com/maya
Instagram@maya.makes
Save contact
); } /* ───────── for business ───────── */ function ForBusiness() { const cards = [ { ico: 'users', t: 'Equip the whole team', p: 'Order matching cards for everyone and manage their profiles from one dashboard.' }, { ico: 'building', t: 'On-brand, every tap', p: 'Lock logos, colors and layout so every profile looks unmistakably yours.' }, { ico: 'refresh', t: 'CRM in real time', p: 'Pipe captured leads straight into Salesforce, HubSpot or a webhook automatically.' }, ]; return (
FOR BUSINESS

Networking that scales with the team.

From two-person studios to thousand-seat sales floors — deploy, brand and measure every connection from one place.

{cards.map((c, i) => (

{c.t}

{c.p}

))}
7×more contacts kept
0apps to install
40k+professionals on waiv
1.4mtaps shared
); } /* ───────── final CTA — giant waving Tappy finale ───────── */ function FinalCTA() { const secRef = useRef(null); const pupL = useRef(null), pupR = useRef(null); const [happy, setHappy] = useState(false); const [bursts, setBursts] = useState([]); const keyRef = useRef(0); // eyes follow cursor useEffect(() => { const onMove = (e) => { [pupL, pupR].forEach(ref => { const el = ref.current; if (!el) return; const r = el.getBoundingClientRect(); const dx = e.clientX - (r.left + r.width / 2), dy = e.clientY - (r.top + r.height / 2); const a = Math.atan2(dy, dx), d = Math.min(6, Math.hypot(dx, dy) / 28); el.style.transform = `translate(calc(-50% + ${Math.cos(a) * d}px), calc(-50% + ${Math.sin(a) * d}px))`; }); const sec = secRef.current; if (sec) { const r = sec.getBoundingClientRect(); sec.style.setProperty('--mx', ((e.clientX - r.left) / r.width * 100).toFixed(1) + '%'); sec.style.setProperty('--my', ((e.clientY - r.top) / r.height * 100).toFixed(1) + '%'); } }; window.addEventListener('pointermove', onMove); return () => window.removeEventListener('pointermove', onMove); }, []); const CONFETTI = ['#ffd527', '#3f8bff', '#67b9a4', '#e0577f', '#cfe0ff', '#f2c200']; const celebrate = () => { setHappy(true); const k = ++keyRef.current; const pieces = Array.from({ length: 26 }, (_, i) => ({ id: k + '-' + i, x: (Math.random() * 2 - 1) * 280, y: -120 - Math.random() * 200, rot: Math.random() * 360, c: CONFETTI[i % CONFETTI.length], dl: Math.random() * 0.12, })); setBursts(b => [...b, { k, pieces }]); setTimeout(() => setBursts(b => b.filter(x => x.k !== k)), 1500); setTimeout(() => setHappy(false), 1800); }; return (
); } /* ───────── footer ───────── */ function Footer() { const cols = [ { h: 'Product', links: ['The card', 'Onelynk', 'Finishes', 'How it works', 'Pricing'] }, { h: 'Company', links: ['About', 'Careers', 'Press', 'Sustainability'] }, { h: 'Support', links: ['Help center', 'Activate a card', 'Contact', 'Privacy'] }, ]; return ( ); } Object.assign(window, { Ico, Kicker, TrustStrip, HowItWorks, FinishShowcase, ShareGrid, Onelynk, ForBusiness, FinalCTA, Footer });