/* global React, Star4, StarBurst, StarRays, Squiggle, BlobTop, BlobCorner, TildeRow, MarqueeSign, RoadShield, RibbonBanner, useMagnetic */
const { useRef, useEffect, useLayoutEffect, useState } = React;

// ============================================================
//  HERO — yellow stage w/ cyan blob + arched photo + stars
// ============================================================
function Hero() {
  const rootRef = useRef(null);
  const ctaRef = useMagnetic(0.15, 70);
  const cta2Ref = useMagnetic(0.15, 70);
  const skyParRef = useRef(null);

  // size the strip tiles to the sky image's true aspect ratio, so a wide
  // panorama scrolls through in full instead of being center-cropped
  useEffect(() => {
    const img = new Image();
    img.onload = () => {
      const el = rootRef.current && rootRef.current.querySelector(".hero-sky");
      if (el && img.naturalHeight) {
        el.style.setProperty("--sky-ar", (img.naturalWidth / img.naturalHeight).toFixed(4));
      }
    };
    img.src = "assets/sky.jpg";
  }, []);

  // chainzoku-style pointer parallax: the sky eases toward the cursor.
  // Skipped for touch and reduced-motion visitors.
  useEffect(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    if (window.matchMedia("(hover: none)").matches) return;
    let raf = 0, tx = 0, ty = 0, x = 0, y = 0;
    const onMove = (e) => {
      tx = e.clientX / window.innerWidth - 0.5;
      ty = e.clientY / window.innerHeight - 0.5;
    };
    const tick = () => {
      x += (tx - x) * 0.05;
      y += (ty - y) * 0.05;
      const el = skyParRef.current;
      if (el) el.style.transform = `translate(${(-x * 44).toFixed(2)}px, ${(-y * 24).toFixed(2)}px)`;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    window.addEventListener("mousemove", onMove);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("mousemove", onMove);
    };
  }, []);

  useLayoutEffect(() => {
    const gsap = window.gsap;
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const ctx = gsap.context(() => {
      const tl = gsap.timeline({ defaults: { ease: "power3.out" } });

      tl.set(".entry-swipe", { x: "-100%" }).
      to(".entry-swipe", { x: "100%", duration: 0.85, ease: "power3.inOut" }, 0).
      to(".nav-wrap", { autoAlpha: 1, y: 0, duration: 0.45 }, 0.4)
      // photo arch
      .fromTo(".hero-photo", { autoAlpha: 0, x: -60, scale: 0.92 }, { autoAlpha: 1, x: 0, scale: 1, duration: 0.9, ease: "back.out(1.2)" }, 0.65)
      // bursts on photo corners
      .fromTo(".photo-burst-bl", { autoAlpha: 0, scale: 0.3, rotation: -45 }, { autoAlpha: 1, scale: 1, rotation: 0, duration: 0.6, ease: "back.out(1.7)" }, 0.95)
      // content
      .fromTo(".hero-content > *", { autoAlpha: 0, y: 24 }, { autoAlpha: 1, y: 0, duration: 0.55, stagger: 0.08 }, 0.85)
      // sparkles + squiggles
      .fromTo(".hero-stars > *", { autoAlpha: 0, scale: 0.3 }, { autoAlpha: 1, scale: 1, duration: 0.5, stagger: 0.05, ease: "back.out(2)" }, 1.0).
      fromTo(".shape-squiggle", { autoAlpha: 0, x: -20 }, { autoAlpha: 1, x: 0, duration: 0.5, stagger: 0.06 }, 1.05);

      if (!reduced) {
        // idle — slow rotation on stars
        gsap.utils.toArray(".hero-stars > *").forEach((el, i) => {
          gsap.to(el, { rotation: 360, duration: 16 + i * 2, repeat: -1, ease: "none", transformOrigin: "50% 50%" });
        });
        // idle — photo bursts spin slowly opposite directions
        gsap.to(".photo-burst-bl", { rotation: -360, duration: 28, ease: "none", repeat: -1, transformOrigin: "50% 50%" });

        // parallax: photo drifts up on scroll
        gsap.to(".hero-photo", {
          yPercent: -10, ease: "none",
          scrollTrigger: { trigger: rootRef.current, start: "top top", end: "bottom top", scrub: true }
        });
      }
    });
    return () => ctx.revert();
  }, []);

  return (
    <section ref={rootRef} className="hero" id="top">
      {/* living sky — the photo scrolls right→left on a seamless mirrored
          loop and eases toward the cursor; if assets/sky.jpg is absent the
          yellow shows through */}
      <div className="hero-sky" aria-hidden="true">
        <div className="sky-par" ref={skyParRef}>
          <div className="sky-strip">
            <div className="sky-tile" style={{ backgroundImage: "url(assets/sky.jpg)" }} />
            <div className="sky-tile is-flip" style={{ backgroundImage: "url(assets/sky.jpg)" }} />
          </div>
        </div>
        <div className="sky-fade" />
      </div>

      {/* one squiggle, placed with intent near the headline */}
      <div className="hero-shapes" aria-hidden="true">
        <div className="hero-shape shape-squiggle shape-squiggle-mr">
          <Squiggle color="var(--red)" thick={6} />
        </div>
      </div>

      {/* a small constellation around the headline — not confetti */}
      <div className="hero-stars" aria-hidden="true">
        <Star4 className="star-1" color="var(--cyan)" outlined outline="var(--ink)" />
        <Star4 className="star-2" color="var(--green)" outlined outline="var(--ink)" />
        <Star4 className="star-5" color="var(--cyan)" outlined outline="var(--ink)" />
      </div>

      {/* photo arch */}
      <div className="hero-photo">
        <div className="ring-outer" />
        <div className="ring-mid" />
        <div className="ring-inner">
          <img src="assets/hero-girl-full.webp" alt="Pin-up model sipping from a Wonderful Choice diner coffee cup" decoding="async" fetchpriority="high" />
        </div>
        <div className="photo-burst-bl">
          <StarBurst color="var(--cream)" outline="var(--ink)" />
        </div>
      </div>

      {/* content */}
      <div className="hero-content">
        <div className="hero-eyebrow hero-neon-script" aria-hidden="true">
          Come <span className="neon-dud">o</span>n in!
        </div>
        <h1 className="hero-h1">
          <span className="l1">Food Service</span>
          <span className="l2" style={{ color: "rgb(214, 41, 41)" }}>Packaging Expert<span className="dot">.</span></span>
        </h1>
        <p className="hero-sub">



        </p>
        <div className="hero-actions">
          <a ref={ctaRef} href="#lineup" className="btn-pill" data-magnetic>
            More Info
          </a>
          <a ref={cta2Ref} href="#contact" className="btn-pill btn-red" data-magnetic>
            Get a Quote
          </a>
        </div>
      </div>
    </section>);} // ============================================================
//  ABOUT
// ============================================================
function About() {const rootRef = useRef(null);
  useLayoutEffect(() => {
    const gsap = window.gsap;
    const ctx = gsap.context(() => {
      gsap.fromTo(".about-text > *", { autoAlpha: 0, y: 30 },
      { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.08,
        scrollTrigger: { trigger: ".about-text", start: "top 78%" } });
      gsap.fromTo(".stat", { autoAlpha: 0, y: 30 },
      { autoAlpha: 1, y: 0, duration: 0.6, stagger: 0.08, ease: "back.out(1.4)",
        scrollTrigger: { trigger: ".about-stats", start: "top 80%" } });
      gsap.fromTo(".about-postcard, .about-card", { autoAlpha: 0, scale: 0.85 },
      { autoAlpha: 1, scale: 1, rotation: (i, el) => el.dataset.rot,
        duration: 0.7, stagger: 0.1, ease: "back.out(1.4)",
        scrollTrigger: { trigger: ".about-side", start: "top 78%" } });
      gsap.fromTo(".stop", { autoAlpha: 0, y: 44 },
      { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.14, ease: "back.out(1.2)",
        scrollTrigger: { trigger: ".placemat", start: "top 78%" } });
    }, rootRef);
    return () => ctx.revert();
  }, []);

  return (
    <section ref={rootRef} className="about" id="about">
      <div className="about-deco" aria-hidden="true">
        <Squiggle className="squig s1" color="var(--red)" thick={6} />
        <Squiggle className="squig s2" color="var(--red)" thick={6} />
        <Star4 className="star-1" color="var(--cream)" outlined outline="var(--ink)" />
        <Star4 className="star-2" color="var(--cream)" outlined outline="var(--ink)" />
      </div>

      <div className="section">
        <div className="about-text">
          <h1 className="h2">
            Good food deserves<br />
            <span className="alt">better packaging.</span>
          </h1>
          <p className="sub">
            We think take-away should feel like part of the meal, not an
            afterthought. Wonderful Choice makes food-service packaging with
            personality — cups, boxes, bags, and everything between, printed
            with your brand and built for the daily rush.
          </p>
          <p className="sub">
            One lineup, eighty-plus products: hot and cold cups, lids, straws,
            to-go boxes, bakery boxes, carrier bags, wraps, and labels. Bring
            a logo or a napkin sketch — we Pantone-match up to four colors
            and send a mock-up with every quote. Approve it, and we get
            printing.
          </p>
          <div className="about-stats">
            <div className="stat s2"><div className="num">80+</div><div className="lbl">Products in the lineup</div></div>
            <div className="stat s3"><div className="num">100%</div><div className="lbl">Food-safe materials</div></div>
          </div>
        </div>

        <div className="about-side">
          {/* the anchor — a snapshot from the shop wall */}
          <figure className="about-postcard" data-rot="2">
            <img src="assets/about-ramen.jpg" alt="Smiling model in 50s dress eating noodles from a custom-printed Wonderful Ramen cup" loading="lazy" decoding="async" />
            <figcaption>Our ink, somebody&rsquo;s lunch.</figcaption>
            <div className="about-postcard-banner" aria-hidden="true">
              <RibbonBanner label="Quality Guaranteed" tone="red" />
            </div>
          </figure>
          <div className="about-tickets">
            <div className="about-card c1" data-rot="-1.5">
              <div className="ttl">★ Design Help</div>
              Bring a logo or a napkin sketch — print-ready art and a mock-up
              come with every quote.
            </div>
            <div className="about-card c2" data-rot="1.2">
              <div className="ttl">★ Materials First</div>
              Food-safe inks and boards, with recycled and compostable options
              across the lineup.
            </div>
            <div className="about-card c3" data-rot="-1">
              <div className="ttl">★ Any Run Size</div>
              From a food truck&rsquo;s first hundred cups to a chain-wide
              rollout — quotes sized to your order.
            </div>
          </div>
        </div>

        {/* the old Process page, distilled — an order's road trip through the shop,
            laid out like a diner placemat map */}
        <div className="about-how">
          <p className="how-sub">One order, four stops — the road every job takes through the shop.</p>
          <div className="placemat">
            {/* dotted travel route winding behind the photo arches */}
            <svg className="route" viewBox="0 0 1160 220" preserveAspectRatio="none" aria-hidden="true">
              <path d="M-10,150 C120,60 240,60 350,120 S560,190 690,120 940,50 1170,110" fill="none" />
            </svg>
            <div className="stops">
              {[
                { n: "01", name: "Design", desc: "We sit down with you and sketch on diner napkins. Then a clean mock-up for your sign-off.", img: "assets/step-design.webp" },
                { n: "02", name: "Print & Form", desc: "Pantone-matched inks, offset or in-mold. Rolled, seamed, or molded into shape — listen for the click.", img: "assets/step-print.webp" },
                { n: "03", name: "Ship", desc: "Boxed by the case, wrapped on a pallet. Straight to your counter.", img: "assets/step-ship.webp" },
                { n: "04", name: "Enjoy", desc: "Your menu, your logo, your customers' hands. The part everyone showed up for.", img: "assets/step-enjoy.webp" },
              ].map((s, i) => (
                <div key={i} className={`stop p${i + 1}`}>
                  <div className="stop-arch">
                    <img src={s.img} alt="" loading="lazy" decoding="async" />
                    <span className="stop-badge" aria-hidden="true">{s.n}</span>
                  </div>
                  <h3 className="stop-name">{s.name}</h3>
                  <p className="stop-desc">{s.desc}</p>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>);

}

// ============================================================
//  LINEUP — diner menu card
// ============================================================
function Lineup() {
  const rootRef = useRef(null);
  const peekRef = useRef(null);

  // desktop delight: hovering a text menu item floats that product's photo
  // beside the cursor — every item already has a shot in assets/products/
  useEffect(() => {
    if (window.matchMedia("(hover: none)").matches) return;
    const root = rootRef.current, peek = peekRef.current;
    if (!root || !peek) return;
    const img = peek.querySelector("img");
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    let raf = 0, tx = 0, ty = 0, x = 0, y = 0;
    const place = () => {
      peek.style.transform = `translate(${x.toFixed(1)}px, ${y.toFixed(1)}px)`;
    };
    const move = (e) => {
      tx = Math.min(e.clientX + 26, window.innerWidth - 210);
      ty = Math.min(Math.max(e.clientY - 120, 12), window.innerHeight - 250);
      if (reduced) { x = tx; y = ty; place(); }
    };
    const over = (e) => {
      const a = e.target.closest("[data-peek]");
      if (!a) return;
      img.src = a.dataset.peek;
      peek.classList.add("is-on");
      // snap to the cursor on first show so it doesn't glide across the page
      if (x === 0 && y === 0) { x = tx; y = ty; place(); }
    };
    const out = (e) => {
      const a = e.target.closest("[data-peek]");
      if (a && !(e.relatedTarget && a.contains(e.relatedTarget))) peek.classList.remove("is-on");
    };
    const tick = () => {
      x += (tx - x) * 0.22;
      y += (ty - y) * 0.22;
      place();
      raf = requestAnimationFrame(tick);
    };
    if (!reduced) raf = requestAnimationFrame(tick);
    root.addEventListener("mousemove", move);
    root.addEventListener("mouseover", over);
    root.addEventListener("mouseout", out);
    return () => {
      cancelAnimationFrame(raf);
      root.removeEventListener("mousemove", move);
      root.removeEventListener("mouseover", over);
      root.removeEventListener("mouseout", out);
    };
  }, []);

  useLayoutEffect(() => {
    const gsap = window.gsap;
    const ctx = gsap.context(() => {
      gsap.fromTo(".menu-frame",
      { autoAlpha: 0, y: 60, rotation: -1.5 },
      { autoAlpha: 1, y: 0, rotation: 0, duration: 0.9, ease: "power3.out",
        scrollTrigger: { trigger: ".menu-frame", start: "top 80%" } });
      gsap.fromTo(".menu-row",
      { autoAlpha: 0, x: -20 },
      { autoAlpha: 1, x: 0, duration: 0.5, stagger: 0.08,
        scrollTrigger: { trigger: ".menu-list", start: "top 85%" } });
      gsap.fromTo(".menu-section-head",
      { autoAlpha: 0, scale: 0.9 },
      { autoAlpha: 1, scale: 1, duration: 0.6, stagger: 0.1, ease: "back.out(1.4)",
        scrollTrigger: { trigger: ".menu-card", start: "top 80%" } });
      gsap.fromTo(".menu-stamp",
      { autoAlpha: 0, scale: 0.4, rotation: -25 },
      { autoAlpha: 1, scale: 1, rotation: -8, duration: 0.7, ease: "back.out(1.7)",
        scrollTrigger: { trigger: ".menu-card", start: "top 70%" } });
      gsap.fromTo(".craft-tile",
      { autoAlpha: 0, y: 26 },
      { autoAlpha: 1, y: 0, duration: 0.5, stagger: 0.05, ease: "back.out(1.3)",
        scrollTrigger: { trigger: ".craft-grid", start: "top 84%" } });
    }, rootRef);
    return () => ctx.revert();
  }, []);

  // The house specialty — decorative finishing techniques for cups.
  // Single source of truth lives in components.jsx (shared with the PDPs).
  const crafts = window.WC_CRAFTS || [];

  const specials = [
  { n: "01", name: "Double-Wall Ripple", tag: "10oz · 12oz · 16oz · 22oz", desc: "Insulated hollow hot cup. No sleeve needed. Up to 4 inks, Pantone-matched.", photo: "assets/products/double-wall-ripple-1.jpg" },
  { n: "02", name: "PET Cold Cup", tag: "16oz · 22oz · clear", desc: "Crystal-clear cold cup with snap lid and straw. Frosted on request.", photo: "assets/products/pet-cold-cup-1.jpg" },
  { n: "03", name: "Square-Bottom To-Go", tag: "lunch box · lid in", desc: "Grease-proof board box. Stacks tight, travels flat, holds the heat.", photo: "assets/products/square-bottom-to-go-1.jpg" }];

  const catalog = [
  { no: "01", name: "Drinkware — Cups & Bottles", curl: "~ from the fountain ~", items: [
    { name: "Hot Cups", note: "single · double · ripple" },
    { name: "Insulated Hollow Cups", note: "10oz · 12oz · 16oz · 22oz" },
    { name: "Corrugated Cups", note: "extra-grip kraft" },
    { name: "Brushed Gold & Silver Cups", note: "metallic finish" },
    { name: "Cup-Within-a-Cup", note: "built-in sleeve" },
    { name: "Diagonal-Mouth Cups", note: "the slant rim" },
    { name: "Double-Wall Hollow Cups", note: "cool to the touch" },
    { name: "PET Cold Cups", note: "crystal clear" },
    { name: "Injection / Frosted Cups", note: "molded matte" },
    { name: "Square Cups", note: "clear or frosted" },
    { name: "U-Shape Cups", note: "clear or frosted" },
    { name: "In-Mold-Label Cups", note: "art baked in" },
    { name: "Bottles", note: "custom printed" },
    { name: "Custom Printed Cups", note: "your run, your art" }] },
  { no: "02", name: "Lids & Toppers", curl: "~ caps off ~", items: [
    { name: "Flat Lids", note: "" },
    { name: "High-Dome Lids", note: "room for foam" },
    { name: "Semi-Circular Lids", note: "" },
    { name: "90° Rotating Lids", note: "twist to sip" },
    { name: "Swivel Lids", note: "" },
    { name: "Lift-to-Drink Lids", note: "" },
    { name: "Split Hot-Drink Lids", note: "" },
    { name: "Panda Lids", note: "the cult favorite" },
    { name: "Flip Leak-Proof Lids", note: "spill-stop" },
    { name: "Clamshell Lids", note: "" },
    { name: "Injection / Siamese Lids", note: "" },
    { name: "PET Snap Drink Lids", note: "" },
    { name: "PET Double-Hole Lids", note: "" },
    { name: "Paper Lids", note: "plastic-free" }] },
  { no: "03", name: "Sleeves, Carriers & Holders", curl: "~ hold it steady ~", items: [
    { name: "Snap / Card-Buckle Sleeves", note: "" },
    { name: "Double-Layer Sleeves", note: "extra insulation" },
    { name: "Special-Shaped Sleeves", note: "cut to your art" },
    { name: "Corrugated Cup Carriers", note: "" },
    { name: "Handheld Carriers / Trays", note: "2 & 4 cup" },
    { name: "Cup Holders", note: "" }] },
  { no: "04", name: "Straws & Stir Sticks", curl: "~ sip & stir ~", items: [
    { name: "Paper Straws", note: "" },
    { name: "PLA Straws", note: "plant-based" },
    { name: "Paper-Wrapped PP Straws", note: "" },
    { name: "Plastic-Wrapped PP Straws", note: "" },
    { name: "Bamboo-Fiber Straws", note: "" }] },
  { no: "05", name: "To-Go Boxes & Entrée Containers", curl: "~ for the road ~", items: [
    { name: "Square-Bottom Lunch Boxes", note: "" },
    { name: "Octagonal Lunch Boxes", note: "" },
    { name: "Boat Boxes", note: "" },
    { name: "Box-With-Lid", note: "" },
    { name: "All-in-One Boxes", note: "hinged" },
    { name: "Burger Boxes", note: "" },
    { name: "Hot-Dog Boxes", note: "" },
    { name: "French-Fry Boxes", note: "" },
    { name: "Sushi Boxes", note: "" },
    { name: "Salad Bowls", note: "" },
    { name: "Soup Buckets", note: "" },
    { name: "Noodle Buckets", note: "" },
    { name: "Paper Food Covers / Lids", note: "" }] },
  { no: "06", name: "Bakery & Dessert Boxes", curl: "~ sweet tooth ~", items: [
    { name: "Pizza Boxes", note: "" },
    { name: "Toast / Bread Boxes", note: "" },
    { name: "Cake Boxes", note: "" },
    { name: "Mousse Cake Boxes", note: "" },
    { name: "Cupcake & Dessert Boxes", note: "" },
    { name: "Portable Egg-Tart Boxes", note: "" },
    { name: "Square Egg-Tart Boxes", note: "" },
    { name: "Gift Boxes", note: "ribbon-ready" }] },
  { no: "07", name: "Bags & Carryout", curl: "~ bag it up ~", items: [
    { name: "Kraft Paper Bags", note: "" },
    { name: "Square-Bottom Kraft Bags", note: "" },
    { name: "Window Pointed-Bottom Bags", note: "" },
    { name: "Handle / Tote Bags", note: "" },
    { name: "Drink-Carrier Bags", note: "" },
    { name: "OPP Clear Plastic Bags", note: "" },
    { name: "Plastic Bags", note: "" },
    { name: "Greaseproof Paper Bags", note: "" },
    { name: "Insulated Delivery Bags", note: "keeps it hot" }] },
  { no: "08", name: "Wraps, Liners & Papers", curl: "~ wrap it tight ~", items: [
    { name: "Greaseproof / Deli Paper", note: "" },
    { name: "Food-Wrapping Paper", note: "" },
    { name: "Leak-Proof Paper", note: "" },
    { name: "Sealing / Lidding Film", note: "" },
    { name: "Napkins & Paper Towels", note: "" }] },
  { no: "09", name: "Labels & Stickers", curl: "~ seal of approval ~", items: [
    { name: "Label Paper", note: "" },
    { name: "Receipt / Thermal Paper", note: "" },
    { name: "“Sealed for Freshness” Stickers", note: "" },
    { name: "Lid Reminder Stickers", note: "" },
    { name: "Expiration-Date Stickers", note: "" },
    { name: "Custom Cup Stickers", note: "your art" }] }];


  return (
    <section ref={rootRef} className="lineup lineup-menu" id="lineup">
      {/* floating photo card for menu-item hovers */}
      <div className="menu-peek" ref={peekRef} aria-hidden="true">
        <img alt="" decoding="async" />
      </div>
      <div className="lineup-deco" aria-hidden="true">
        <div className="blob"><BlobCorner color="var(--cyan)" /></div>
        <Squiggle className="squig-1" color="var(--red)" thick={6} />
        <Squiggle className="squig-2" color="var(--red)" thick={6} />
        <Star4 className="star-1" color="var(--cream)" outlined outline="var(--ink)" />
        <Star4 className="star-2" color="var(--cream)" outlined outline="var(--ink)" />
      </div>

      <div className="menu-eat-sign" aria-hidden="true">
        <MarqueeSign tone="teal" vertical>EAT HERE</MarqueeSign>
      </div>

      <div className="section">
        <h2 className="h2">Pull up<br />a stool. <span className="alt">Order up.</span></h2>

        <div className="menu-frame">
        <div className="menu-card">
          {/* scalloped service awning */}
          <div className="awning" aria-hidden="true" />
          {/* MENU header banner */}
          <div className="menu-banner">
            <span className="dingbat">★</span>
            <span className="menu-banner-title">Menu</span>
            <span className="dingbat">★</span>
          </div>
          <div className="menu-sub">— Wonderful Choice · 66 Diner Row —</div>

          {/* "Daily Specials" stamp */}
          <div className="menu-stamp">
            <div className="menu-stamp-inner">
              <span className="t-label">★ Daily ★</span>
              <span className="big">Specials</span>
              <span className="t-label">Printed Fresh</span>
            </div>
          </div>

          {/* THE SPECIAL CRAFT — finishing techniques, the house specialty */}
          <div className="menu-section-head">
            <span className="rule" />
            <h3 className="menu-section-title">The Special Craft</h3>
            <span className="curl">~ the house specialty ~</span>
            <span className="rule" />
          </div>
          <p className="craft-lead">
            Ten ways to dress a cup — foil, velvet, relief, and shine. Every
            technique on this board quotes on any cup in the lineup.{" "}
            <a className="craft-lead-link" href="blog/premium-cup-finishes.html">Read the finishes guide →</a>
          </p>
          <div className="craft-grid">
            {crafts.map((c, i) => (
              <figure
                key={c.name}
                className="craft-tile"
                tabIndex={0}
                aria-describedby={`craft-pop-${i}`}
              >
                <img src={c.photo} alt={c.alt} loading="lazy" decoding="async" />
                <figcaption>
                  <span className="craft-name">{c.name}</span>
                  <span className="craft-note">{c.note}</span>
                </figcaption>
                {/* hover / focus tip — which cups this finish applies to */}
                <span className="craft-pop" id={`craft-pop-${i}`} role="tooltip">
                  <span className="craft-pop-label">★ Goes on</span>
                  <span className="craft-pop-text">{c.applies}</span>
                </span>
              </figure>
            ))}
          </div>

          {/* HOUSE SPECIALS — featured photo trio */}
          <div className="menu-section-head">
            <span className="rule" />
            <h3 className="menu-section-title">House Specials</h3>
            <span className="curl">~ printed fresh daily ~</span>
            <span className="rule" />
          </div>
          <div className="menu-list">
            {specials.map((it) => <MenuRow key={it.n} item={it} />)}
          </div>

          {/* FULL CATALOG — every product, by the section */}
          {catalog.map((cat) => <MenuCat key={cat.no} cat={cat} />)}

          {/* 10 — FINISHING & EXTRAS — runs across the whole line */}
          <div className="menu-finish">
            <div className="menu-finish-head">
              <span className="menu-cat-no">10 /</span>
              <h3 className="menu-section-title">Finishing &amp; Extras</h3>
              <span className="curl">~ the works ~</span>
            </div>
            <p className="menu-finish-lead">
              Fork-and-spoon sets on the menu, too. And every technique on the
              Special Craft board up top — foil to flocking — quotes on any
              product in the line.
            </p>
          </div>

          {/* footer of menu */}
          <div className="menu-foot">
            <span className="t-label">★ Custom print included ★ Pantone-matched inks ★ Free mock-up with every quote ★</span>
          </div>
        </div>
        </div>
      </div>
    </section>);

}

// Build a detail-page link for any menu product. Name (and optional tag/photo)
// ride along as query params so the shared detail page reflects the clicked item.
// Every catalog product has a static, crawlable page at products/<slug>.html
// (generated by scripts/build-seo.mjs). product.html?p=… still works as a
// fallback for anything not in the catalog.
function productHref(name) {
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  return `products/${slug}.html`;
}

function MenuRow({ item }) {
  return (
    <a className="menu-row" href={productHref(item.name, item.tag, item.photo)} data-magnetic aria-label={`${item.name} — view details`}>
      <div className="menu-thumb">
        <img src={item.photo} alt="" loading="lazy" decoding="async" />
      </div>
      <div className="menu-body">
        <div className="menu-row-head">
          <span className="menu-num">№ {item.n}</span>
          <span className="menu-name">{item.name}</span>
        </div>
        <div className="menu-tag">{item.tag}</div>
        <p className="menu-desc">{item.desc}</p>
      </div>
    </a>);

}

function MenuCat({ cat }) {
  return (
    <div className="menu-cat">
      <div className="menu-section-head">
        <span className="rule" />
        <span className="menu-cat-no">{cat.no} /</span>
        <h3 className="menu-section-title">{cat.name}</h3>
        <span className="curl">{cat.curl}</span>
        <span className="rule" />
      </div>
      <div className="menu-cat-list">
        {cat.items.map((it) =>
        <a className="menu-item" key={it.name} href={productHref(it.name, it.note)} aria-label={`${it.name} — view details`}
            data-peek={`assets/products/${it.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")}-1.jpg`}>
            <span className="mi-name">{it.name}</span>
            <span className="mi-dots" aria-hidden="true" />
            {it.note ? <span className="mi-note">{it.note}</span> : null}
          </a>
        )}
      </div>
    </div>);

}

// ============================================================
//  CONTACT — dedicated B2B inquiry page
// ============================================================
const CONTACT_PRODUCTS = [
  "Cups & Bottles", "Lids & Toppers", "Sleeves & Carriers", "Straws & Stir Sticks",
  "To-Go & Entrée Boxes", "Bakery & Dessert Boxes", "Bags & Carryout", "Wraps & Liners", "Labels & Stickers",
];
const CONTACT_BIZ = [
  "Café / Coffee shop", "Restaurant", "Bakery / Dessert", "Food truck / Cart",
  "Bubble tea / Juice bar", "Franchise / Multi-site", "Distributor / Wholesale", "Other",
];
const CONTACT_VOLUME = [
  "Under 1,000 / month", "1,000 – 5,000 / month", "5,000 – 20,000 / month",
  "20,000 – 50,000 / month", "50,000+ / month", "One-time run",
];
const CONTACT_TIMELINE = ["ASAP — this month", "2 – 4 weeks", "1 – 3 months", "Just exploring"];

function Contact() {
  const rootRef = useRef(null);
  const [form, setForm] = useState({
    firstName: "", lastName: "", email: "", phone: "",
    company: "", role: "", website: "",
    businessType: "", location: "",
    products: [], volume: "", printing: "", timeline: "", message: "",
  });
  const [errors, setErrors] = useState({});
  const [status, setStatus] = useState("idle"); // idle | submitting | success
  const [sendError, setSendError] = useState(false); // backend send failed
  const hpRef = useRef(null); // honeypot — catches bots

  useLayoutEffect(() => {
    const gsap = window.gsap;
    const ctx = gsap.context(() => {
      gsap.fromTo(".ct-head > *", { autoAlpha: 0, y: 30 },
        { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.08, scrollTrigger: { trigger: ".ct-head", start: "top 85%" } });
      gsap.fromTo(".ct-rail, .ct-formcard", { autoAlpha: 0, y: 40 },
        { autoAlpha: 1, y: 0, duration: 0.7, stagger: 0.1, ease: "power3.out",
          scrollTrigger: { trigger: ".ct-grid", start: "top 82%" } });
    }, rootRef);
    return () => ctx.revert();
  }, []);

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const toggleProduct = (p) => setForm((f) => ({
    ...f, products: f.products.includes(p) ? f.products.filter((x) => x !== p) : [...f.products, p],
  }));

  const validate = () => {
    const e = {};
    if (!form.firstName.trim()) e.firstName = "Tell us your first name.";
    if (!form.lastName.trim()) e.lastName = "Tell us your last name.";
    if (!form.email.trim()) e.email = "We need an email to reply.";
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) e.email = "That email looks off. Check it?";
    if (!form.phone.trim()) e.phone = "A number we can reach you at.";
    if (!form.company.trim()) e.company = "What's the shop called?";
    if (!form.role.trim()) e.role = "Your role at the shop?";
    if (!form.businessType) e.businessType = "Pick the closest fit.";
    if (!form.location.trim()) e.location = "Where are you based?";
    if (form.products.length === 0) e.products = "Choose at least one product.";
    if (!form.volume) e.volume = "Give us a ballpark.";
    if (!form.timeline) e.timeline = "When do you need it?";
    if (!form.printing) e.printing = "Let us know about artwork.";
    if (!form.message.trim()) e.message = "Give us a line or two about the job.";
    return e;
  };

  // Manual escape hatch: opens the visitor's email app pre-filled with their
  // answers. Only ever triggered by the visitor clicking the link in the
  // send-failure banner — never automatically.
  const openMailto = () => {
    const L = [
      `Name: ${form.firstName} ${form.lastName}`,
      `Email: ${form.email}`,
      form.phone && `Phone: ${form.phone}`,
      `Company: ${form.company}`,
      form.role && `Role: ${form.role}`,
      form.website && `Website: ${form.website}`,
      `Business type: ${form.businessType}`,
      form.location && `Location: ${form.location}`,
      `Products: ${form.products.join(", ")}`,
      form.volume && `Monthly volume: ${form.volume}`,
      form.printing && `Printing: ${form.printing}`,
      form.timeline && `Timeline: ${form.timeline}`,
      "",
      "About the job:",
      form.message,
    ].filter(Boolean);
    const subject = `Quote request — ${form.company}`;
    window.location.href = `mailto:info@wonderfulchoice.com?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(L.join("\n"))}`;
  };

  const onSubmit = async (ev) => {
    ev.preventDefault();
    const e = validate();
    setErrors(e);
    if (Object.keys(e).length) {
      const order = ["firstName", "lastName", "email", "phone", "company", "role",
        "businessType", "location", "products", "volume", "timeline", "printing", "message"];
      const idFor = { products: "ct-products", printing: "ct-printing" };
      const first = order.find((k) => e[k]);
      const el = document.getElementById(idFor[first] || first);
      if (el) el.focus();
      return;
    }
    setStatus("submitting");
    setSendError(false);
    // The form sends through /api/quote (Resend) — no email app involved.
    try {
      const r = await fetch("/api/quote", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ...form, _hp: hpRef.current ? hpRef.current.value : "" }),
      });
      if (r.ok) { setStatus("success"); return; }
      console.warn("quote send failed:", r.status); // 503 = RESEND_API_KEY missing, 502 = Resend rejected
    } catch (err) {
      console.warn("quote send failed:", err);
    }
    // Send failed — keep the visitor's answers, show an inline error with a
    // manual email option. Never auto-open the email app.
    setStatus("idle");
    setSendError(true);
  };

  const reset = () => {
    setForm({ firstName: "", lastName: "", email: "", phone: "", company: "", role: "", website: "",
      businessType: "", location: "", products: [], volume: "", printing: "", timeline: "", message: "" });
    if (hpRef.current) hpRef.current.value = "";
    setErrors({}); setStatus("idle"); setSendError(false);
  };

  // inline field renderer (returns JSX, not a component → no remount / focus loss)
  const text = (id, label, o = {}) => {
    const err = errors[id];
    return (
      <div className={`cf-field ${o.half ? "cf-half" : ""}`}>
        <label htmlFor={id}>{label}{o.req ? <span className="cf-req" aria-hidden="true"> *</span> : null}</label>
        <input
          id={id} name={id} type={o.type || "text"} value={form[id]}
          onChange={(e) => set(id, e.target.value)}
          placeholder={o.ph || ""} autoComplete={o.ac}
          inputMode={o.inputMode}
          aria-required={o.req || undefined}
          aria-invalid={err ? "true" : undefined}
          aria-describedby={err ? `${id}-err` : (o.help ? `${id}-help` : undefined)}
          className={err ? "is-error" : ""}
        />
        {o.help && !err ? <p className="cf-help" id={`${id}-help`}>{o.help}</p> : null}
        {err ? <p className="cf-err" id={`${id}-err`} role="alert">{err}</p> : null}
      </div>
    );
  };

  const errCount = Object.keys(errors).length;

  if (status === "success") {
    return (
      <section ref={rootRef} className="contact" id="contact">
        <div className="section">
          <div className="ct-success" role="status" aria-live="polite">
            <div className="ct-success-burst" aria-hidden="true"><StarBurst color="var(--yellow)" outline="var(--ink)" /></div>
            <div className="t-label">★ Message sent ★</div>
            <h1 className="h2">You&rsquo;re in<br /><span className="alt">the queue.</span></h1>
            <p className="sub">
              Thanks, {form.firstName || "friend"}. Your request just landed in the shop&rsquo;s
              inbox &mdash; a real human reads every word and replies to <strong>{form.email}</strong>{" "}
              with a mock-up and a quote.
            </p>
            <button type="button" className="btn-pill btn-cyan" onClick={reset} data-magnetic>
              Send another &rarr;
            </button>
          </div>
        </div>
      </section>
    );
  }

  return (
    <section ref={rootRef} className="contact" id="contact">
      <div className="ct-deco" aria-hidden="true">
        <div className="blob"><BlobCorner color="var(--cyan)" /></div>
        <Squiggle className="ct-squig-1" color="var(--red)" thick={6} />
        <Star4 className="ct-star-2" color="var(--cream)" outlined outline="var(--ink)" />
      </div>

      <div className="section">
        <div className="ct-head">
          <h1 className="h2">Let&rsquo;s talk<br /><span className="alt">shop.</span> <Star4 className="ct-star-inline" color="var(--cream)" outlined outline="var(--ink)" /></h1>
          <p className="sub">
            Custom cups, lids, boxes, the works &mdash; tell us what your café runs on and we&rsquo;ll
            mock it up. Wholesale and recurring orders welcome. The more you share, the faster we can quote.
          </p>
        </div>

        <div className="ct-grid">
          {/* LEFT — info rail */}
          <aside className="ct-rail">
            <a className="ct-method" href="mailto:info@wonderfulchoice.com" data-magnetic>
              <span className="ct-ico" aria-hidden="true">
                <svg viewBox="0 0 24 24" fill="none"><rect x="3" y="5" width="18" height="14" rx="2" stroke="currentColor" strokeWidth="2.2" /><path d="M4 7l8 6 8-6" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" /></svg>
              </span>
              <span className="ct-method-body"><span className="t-label">Email</span><span className="ct-method-val">info@wonderfulchoice.com</span></span>
            </a>
            <div className="ct-next">
              <div className="t-label">What happens next</div>
              <ol>
                <li><b>01</b> We read every word &mdash; no bots.</li>
                <li><b>02</b> A mock-up + quote from the team.</li>
                <li><b>03</b> Approve it and we get printing.</li>
              </ol>
            </div>

            {/* the human on the other end — snapshot from the order desk */}
            <figure className="ct-photo">
              <img src="assets/customer-service-girl.jpg" alt="Retro office scene — a smiling operator in sunglasses takes a call at her desk, typewriter and rolodex at the ready" loading="lazy" decoding="async" />
              <figcaption>The order desk, at your service.</figcaption>
            </figure>
          </aside>

          {/* RIGHT — the B2B form */}
          <form className="ct-formcard" onSubmit={onSubmit} noValidate>
            {/* honeypot — off-screen, no human fills it; bots that do get dropped */}
            <input
              ref={hpRef} type="text" name="company_website" tabIndex={-1}
              autoComplete="off" aria-hidden="true"
              style={{ position: "absolute", left: "-9999px", width: "1px", height: "1px", opacity: 0 }}
            />
            {errCount > 0 ? (
              <div className="ct-summary" role="alert">
                <strong>Hold on &mdash; {errCount} {errCount === 1 ? "field needs" : "fields need"} a look.</strong> Marked in red below.
              </div>
            ) : null}

            <fieldset className="cf-group">
              <legend>01 / About you</legend>
              <div className="cf-row">
                {text("firstName", "First name", { req: true, half: true, ac: "given-name" })}
                {text("lastName", "Last name", { req: true, half: true, ac: "family-name" })}
              </div>
              <div className="cf-row">
                {text("email", "Work email", { req: true, half: true, type: "email", ac: "email", ph: "you@yourcafe.com" })}
                {text("phone", "Phone", { req: true, half: true, type: "tel", ac: "tel", inputMode: "tel", ph: "Best number to reach you" })}
              </div>
              <div className="cf-row">
                {text("company", "Company / Café", { req: true, half: true, ac: "organization" })}
                {text("role", "Your role", { req: true, half: true, ac: "organization-title", ph: "Owner, buyer, manager…" })}
              </div>
            </fieldset>

            <fieldset className="cf-group">
              <legend>02 / Your business</legend>
              <div className="cf-row">
                <div className="cf-field cf-half">
                  <label htmlFor="businessType">Business type<span className="cf-req" aria-hidden="true"> *</span></label>
                  <select
                    id="businessType" name="businessType" value={form.businessType}
                    onChange={(e) => set("businessType", e.target.value)}
                    aria-required="true" aria-invalid={errors.businessType ? "true" : undefined}
                    aria-describedby={errors.businessType ? "businessType-err" : undefined}
                    className={errors.businessType ? "is-error" : ""}
                  >
                    <option value="" disabled>Choose one…</option>
                    {CONTACT_BIZ.map((b) => <option key={b} value={b}>{b}</option>)}
                  </select>
                  {errors.businessType ? <p className="cf-err" id="businessType-err" role="alert">{errors.businessType}</p> : null}
                </div>
                {text("location", "City / Region", { req: true, half: true, ac: "address-level2", ph: "Amarillo, TX" })}
              </div>
              {text("website", "Website / Social Media", { ac: "url", ph: "Optional — helps us match your style" })}
            </fieldset>

            <fieldset className="cf-group">
              <legend>03 / What you need</legend>

              <div className="cf-field">
                <span className="cf-grouplabel" id="ct-products-label">Products of interest<span className="cf-req" aria-hidden="true"> *</span></span>
                <div
                  className="cf-chips" id="ct-products" role="group" aria-labelledby="ct-products-label"
                  tabIndex={-1}
                  aria-invalid={errors.products ? "true" : undefined}
                  aria-describedby={errors.products ? "products-err" : undefined}
                >
                  {CONTACT_PRODUCTS.map((p) => {
                    const on = form.products.includes(p);
                    return (
                      <button type="button" key={p} className={`cf-chip ${on ? "is-on" : ""}`}
                        aria-pressed={on} onClick={() => toggleProduct(p)} data-magnetic>
                        {p}
                      </button>
                    );
                  })}
                </div>
                {errors.products ? <p className="cf-err" id="products-err" role="alert">{errors.products}</p> : null}
              </div>

              <div className="cf-row">
                <div className="cf-field cf-half">
                  <label htmlFor="volume">Estimated volume<span className="cf-req" aria-hidden="true"> *</span></label>
                  <select
                    id="volume" name="volume" value={form.volume} onChange={(e) => set("volume", e.target.value)}
                    aria-required="true" aria-invalid={errors.volume ? "true" : undefined}
                    aria-describedby={errors.volume ? "volume-err" : undefined}
                    className={errors.volume ? "is-error" : ""}
                  >
                    <option value="" disabled>Choose one…</option>
                    {CONTACT_VOLUME.map((v) => <option key={v} value={v}>{v}</option>)}
                  </select>
                  {errors.volume ? <p className="cf-err" id="volume-err" role="alert">{errors.volume}</p> : null}
                </div>
                <div className="cf-field cf-half">
                  <label htmlFor="timeline">Timeline<span className="cf-req" aria-hidden="true"> *</span></label>
                  <select
                    id="timeline" name="timeline" value={form.timeline} onChange={(e) => set("timeline", e.target.value)}
                    aria-required="true" aria-invalid={errors.timeline ? "true" : undefined}
                    aria-describedby={errors.timeline ? "timeline-err" : undefined}
                    className={errors.timeline ? "is-error" : ""}
                  >
                    <option value="" disabled>Choose one…</option>
                    {CONTACT_TIMELINE.map((t) => <option key={t} value={t}>{t}</option>)}
                  </select>
                  {errors.timeline ? <p className="cf-err" id="timeline-err" role="alert">{errors.timeline}</p> : null}
                </div>
              </div>

              <div className="cf-field">
                <span className="cf-grouplabel" id="ct-printing-label">Custom printing?<span className="cf-req" aria-hidden="true"> *</span></span>
                <div
                  className="cf-radios" id="ct-printing" role="radiogroup" aria-labelledby="ct-printing-label"
                  tabIndex={-1}
                  aria-required="true" aria-invalid={errors.printing ? "true" : undefined}
                  aria-describedby={errors.printing ? "printing-err" : undefined}
                >
                  {["Yes — my own art", "No — blank stock", "Not sure yet"].map((opt) => (
                    <label key={opt} className={`cf-radio ${form.printing === opt ? "is-on" : ""}`}>
                      <input type="radio" name="printing" value={opt} checked={form.printing === opt} onChange={(e) => set("printing", e.target.value)} />
                      <span>{opt}</span>
                    </label>
                  ))}
                </div>
                {errors.printing ? <p className="cf-err" id="printing-err" role="alert">{errors.printing}</p> : null}
              </div>

              <div className="cf-field">
                <label htmlFor="message">Project details<span className="cf-req" aria-hidden="true"> *</span></label>
                <textarea
                  id="message" name="message" rows={4} value={form.message}
                  onChange={(e) => set("message", e.target.value)}
                  placeholder="Sizes, colors, finishes (foil, emboss, spot UV), deadlines — anything that helps us quote."
                  aria-required="true" aria-invalid={errors.message ? "true" : undefined}
                  aria-describedby={errors.message ? "message-err" : undefined}
                  className={errors.message ? "is-error" : ""}
                />
                {errors.message ? <p className="cf-err" id="message-err" role="alert">{errors.message}</p> : null}
              </div>
            </fieldset>

            {sendError ? (
              <div className="cf-sendfail" role="alert">
                <strong>That didn&rsquo;t go through</strong> &mdash; nothing was sent, and your
                answers are still here. Try again in a moment, or{" "}
                <button type="button" className="cf-sendfail-link" onClick={openMailto}>
                  email us your request instead
                </button>{" "}
                (opens your email app, pre-filled).
              </div>
            ) : null}

            <div className="cf-actions">
              <button type="submit" className="btn-pill btn-red cf-submit" disabled={status === "submitting"} data-magnetic>
                {status === "submitting" ? "Sending…" : sendError ? "Try again →" : "Send it over →"}
              </button>
              <p className="cf-fineprint">★ No spam. We only use this to quote your order.</p>
            </div>
          </form>
        </div>
      </div>
    </section>
  );
}

// ============================================================
//  FOOTER CTA
// ============================================================
function FooterCTA() {
  const rootRef = useRef(null);
  const ctaRef = useMagnetic(0.15, 70);
  const [email, setEmail] = useState("");
  const [brochureOpen, setBrochureOpen] = useState(false);

  useLayoutEffect(() => {
    const gsap = window.gsap;
    const ctx = gsap.context(() => {
      gsap.fromTo(".foot-head > *", { autoAlpha: 0, y: 40 },
      { autoAlpha: 1, y: 0, duration: 0.8, stagger: 0.1,
        scrollTrigger: { trigger: ".foot-head", start: "top 80%" } });
      gsap.fromTo(".foot-form", { autoAlpha: 0, y: 30 },
      { autoAlpha: 1, y: 0, duration: 0.7,
        scrollTrigger: { trigger: ".foot-form", start: "top 85%" } });
      gsap.fromTo(".wave-girl", { autoAlpha: 0, y: 40 },
      { autoAlpha: 1, y: 0, duration: 0.9, ease: "back.out(1.2)",
        scrollTrigger: { trigger: ".footer-cta", start: "top 70%" } });
    }, rootRef);
    return () => ctx.revert();
  }, []);

  return (
    <footer ref={rootRef} className="footer-cta" id="contact">
      <div className="foot-deco" aria-hidden="true">
        <div className="blob"><BlobCorner color="var(--yellow)" /></div>
        <Squiggle className="squig-1" color="var(--cream)" thick={6} />
        <Squiggle className="squig-2" color="var(--cream)" thick={6} />
        <Star4 className="star-1" color="var(--cream)" outlined outline="var(--ink)" />
        <Star4 className="star-2" color="var(--cream)" outlined outline="var(--ink)" />
        <Star4 className="star-3" color="var(--cream)" outlined outline="var(--ink)" />
      </div>

      {/* the waving girl — static cutout, animated to sway/wave */}
      <div className="wave-girl" aria-hidden="true">
        <img src="assets/wave-girl.webp" alt="" loading="lazy" decoding="async" />
      </div>

      <div className="foot-inner">
        <div className="foot-head">
          <div className="foot-serving" aria-hidden="true">Serving up the classics</div>
          <h2 className="foot-headline">
            Take the whole<br />
            <em>menu — to go.</em>
          </h2>
          <p className="foot-sub">
            Drop your email and our full brochure slides across the counter —
            every cup, box, bag, and lid we print, specs included. Ready to
            talk numbers? <a href="contact.html">Pull up a stool</a>.
          </p>
        </div>

        {brochureOpen ? (
          <div className="foot-form foot-unlocked" role="status">
            <p className="foot-thanks">Order up! Your brochure&rsquo;s hot off the press.</p>
            <div className="foot-brochure">
              <a className="btn-pill btn-cyan" href="assets/pdf/wonderful-choice-brochure.pdf"
                target="_blank" rel="noopener" data-magnetic>
                View the brochure →
              </a>
              <a className="btn-pill btn-ghost" href="assets/pdf/wonderful-choice-brochure.pdf"
                download="wonderful-choice-brochure.pdf" data-magnetic>
                Download PDF
              </a>
            </div>
          </div>
        ) : (
          <form className="foot-form" onSubmit={(e) => {
            e.preventDefault();
            // the browser blocks submit until the email is valid (required+type)
            try {
              const leads = JSON.parse(localStorage.getItem("wc-brochure-leads") || "[]");
              leads.push({ email, at: new Date().toISOString() });
              localStorage.setItem("wc-brochure-leads", JSON.stringify(leads));
            } catch (err) { /* private mode — still show the brochure */ }
            setBrochureOpen(true);
          }}>
            <input type="email" placeholder="your@email.com" required
              aria-label="Your email — we’ll open our brochure for you"
              value={email} onChange={(e) => setEmail(e.target.value)} />
            <button ref={ctaRef} type="submit" className="btn-pill btn-cyan" data-magnetic>
              Get the brochure →
            </button>
          </form>
        )}

        <div className="foot-bottom">
          <span className="info">© Wonderful Choice Co.</span>
        </div>
      </div>
    </footer>);

}

// ============================================================
//  Roadster
// ============================================================
function Roadster() {
  const rootRef = useRef(null);

  useEffect(() => {
    if (window.matchMedia("(max-width: 900px)").matches) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const gsap = window.gsap;
    const ScrollTrigger = window.ScrollTrigger;
    if (!gsap || !ScrollTrigger) return;

    rootRef.current.classList.add("is-ready");
    const root = rootRef.current;

    gsap.set(root, { rotation: 90, scaleX: -1, transformOrigin: "50% 50%", y: 100 });

    const bobTw = gsap.to(root, {
      rotation: 90.7, duration: 0.55, ease: "sine.inOut",
      yoyo: true, repeat: -1
    });
    const st = ScrollTrigger.create({
      trigger: document.body,
      start: "top top",
      end: "bottom bottom",
      onUpdate: (self) => {
        const p = self.progress;
        const vh = window.innerHeight;
        const y = 80 + (vh - 320) * p;
        const wiggle = Math.sin(p * 20) * 3;
        gsap.set(root, { x: wiggle, y });
      }
    });
    return () => {bobTw.kill();st.kill();};
  }, []);

  return (
    <div ref={rootRef} className="roadster" aria-hidden="true">
      <img src="assets/corvette.png" alt="" loading="lazy" decoding="async" />
    </div>);

}

Object.assign(window, { Hero, About, Lineup, Contact, FooterCTA, Roadster });