/* ========================================================== YAPPY. — Homepage ========================================================== */ /* ---------- Hero: brand line only ---------- */ function Hero() { const ref = React.useRef(null); // gentle parallax on the packs (desktop pointer only) const onMove = (e) => { const el = ref.current; if (!el || window.matchMedia('(pointer:coarse)').matches) return; const r = el.getBoundingClientRect(); el.style.setProperty('--mx', ((e.clientX - r.left) / r.width - .5).toFixed(3)); el.style.setProperty('--my', ((e.clientY - r.top) / r.height - .5).toFixed(3)); }; return (
{/* noise, fading out toward the quiet */}

The world is loud. Find your quiet.

Everything is asking for your attention. This is the bit that doesn't.

Shop Yappy Free consultation
); } /* ---------- Noise → quiet (scroll-driven) ---------- */ function NoiseToQuiet() { const ref = React.useRef(null); const words = React.useMemo(() => { const rows = []; let seed = 7; const rnd = () => (seed = (seed * 9301 + 49297) % 233280) / 233280; for (let r = 0; r < 22; r++) { const row = []; for (let c = 0; c < 12; c++) { const dx = (c - 5.5) / 6, dy = (r - 10.5) / 11; row.push({ w: NOISE_WORDS[(r * 5 + c * 3) % NOISE_WORDS.length], t: Math.min(.95, .12 + Math.sqrt(dx * dx + dy * dy) * .62 + rnd() * .18) }); } rows.push(row); } return rows; }, []); React.useEffect(() => { const el = ref.current; if (!el) return; let raf = 0; const update = () => { raf = 0; const r = el.getBoundingClientRect(); const p = Math.max(0, Math.min(1, -r.top / Math.max(1, r.height - window.innerHeight))); el.style.setProperty('--p', p.toFixed(3)); }; const on = () => { if (!raf) raf = requestAnimationFrame(update); }; update(); window.addEventListener('scroll', on, { passive: true }); window.addEventListener('resize', on); return () => { window.removeEventListener('scroll', on); window.removeEventListener('resize', on); }; }, []); return (
The full stop

A deliberate pause between you and the noise.

Meet the statuses
); } /* ---------- Product card (simple e-com) ---------- */ function ProductCard({ p }) { const { add, setCartOpen } = useStore(); const adm = useAdmin(); const oos = adm.stock[p.id] === false; const [added, setAdded] = React.useState(false); const quickAdd = (e) => { e.preventDefault(); add(p.id); setAdded(true); setTimeout(() => setAdded(false), 1400); setCartOpen(true); }; return (
{p.status} {PACK.count}
{p.blurb}
); } function Discovery() { return (

Three statuses.
One Yappy.

{PACK.descriptor} · {PACK.count} per pouch.

{VARIANT_NOTE}

{SKU_ORDER.map((k) => )}
); } /* ---------- Simple how-it-works ---------- */ function SimpleSteps() { const steps = [ ['bag', 'Shop', 'Pick your status and check out.'], ['doc', 'Upload prescription', 'Add your prescription after you order.'], ['box', 'Delivered', 'Once verified, we pack and ship.'], ]; return (

Simple as
that.

    {steps.map(([ic, h, d], i) => (
  1. 0{i + 1}
    {h}.

    {d}

  2. ))}
); } /* ---------- No prescription? Free consult ---------- */ function FreeConsultBand() { return (
Don’t have a prescription?

Consult our
doctor.
For free.

Book a short call with a qualified doctor at no cost. They’ll decide whether Yappy is right for you.

    {['No charge for the consultation', 'Phone or video, at a time that suits you', 'No obligation to buy'].map((t) => (
  • {t}
  • ))}
Book free consultation

A prescription is issued only if the doctor decides it is appropriate.

); } /* ---------- Trust ---------- */ function TrustSection() { const items = [ ['doc', 'Product information', 'Pack contents and declarations, written plainly.', 'Final label pending sign-off'], ['leaf', 'Ingredients', 'Full ingredient list for every status.', 'To be supplied'], ['factory', 'Quality', 'Where and how Yappy is made.', 'Certifications to be verified'], ['lock', 'Privacy & support', 'Your prescription is seen only by our verification team.', 'Privacy policy to be finalised'], ]; return (

No noise.
Just clarity.

Our standards
{items.map(([ic, h, d, flag]) => (
{h}

{d}

{flag}
))}
); } function Expression() { return (
Less scroll.
More pause.
Shop Yappy
); } function Home() { useReveal(); return (
); } Object.assign(window, { Home, ProductCard, Discovery, FreeConsultBand, SimpleSteps });