// landing-sections.jsx — page sections (Hero, Strategy, Logos, Glance, Dives, Outcomes, Testimonials, CTA, Footer)
// Note: useEffect/useRef/useState are already destructured from React in landing-mockups.jsx,
// which loads first. Re-declaring with `const` here would throw "Identifier already declared".

/* ------------------------------------------------------------------
   i18n bridge — read window.Wisbid.i18n; force re-render on change.
   t(key) returns the translation or falls back to EN, then the key.
   ------------------------------------------------------------------ */
const useT = () => {
  const i18n = typeof window !== "undefined" && window.Wisbid && window.Wisbid.i18n || null;
  const [, force] = useState(0);
  useEffect(() => {
    if (!i18n) return;
    const unsub = i18n.subscribe(() => force((v) => v + 1));
    return unsub;
  }, [i18n]);
  return (key, fallback) => i18n ? i18n.t(key, fallback) : (fallback || key);
};
const useLocale = () => {
  const i18n = typeof window !== "undefined" && window.Wisbid && window.Wisbid.i18n || null;
  const [code, setCode] = useState(i18n ? i18n.get() : "en");
  useEffect(() => {
    if (!i18n) return;
    const unsub = i18n.subscribe((c) => setCode(c));
    return unsub;
  }, [i18n]);
  const set = (c) => {if (i18n) i18n.set(c);};
  return [code, set];
};
window.useWisbidT = useT;

/* ------------------------------------------------------------------
   Hooks
   ------------------------------------------------------------------ */

// Scroll reveal — adds .is-in when entering viewport
function useReveal() {
  useEffect(() => {
    if (typeof window === "undefined") return;
    const els = document.querySelectorAll(".lp-reveal");
    if (!els.length) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("is-in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);
}

// Animated count-up triggered when element enters viewport
function useCountUp(ref, target, { duration = 1600, suffix = "", decimals = 0 } = {}) {
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    let raf = 0;let started = false;
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const render = (v) => {
      el.textContent = v.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ",") + suffix;
    };
    if (reduced) {render(target);return;}
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          const start = performance.now();
          const tick = (now) => {
            const t = Math.min(1, (now - start) / duration);
            const eased = 1 - Math.pow(1 - t, 3);
            render(target * eased);
            if (t < 1) raf = requestAnimationFrame(tick);
          };
          raf = requestAnimationFrame(tick);
          io.unobserve(el);
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => {cancelAnimationFrame(raf);io.disconnect();};
  }, [ref, target, duration, suffix, decimals]);
}

// Parallax — translate Y by scroll delta * factor when in view
function useParallax(ref, factor = 0.08) {
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduced) return;
    let ticking = false;
    const update = () => {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const center = r.top + r.height / 2;
      const delta = (vh / 2 - center) * factor;
      el.style.transform = `translate3d(0, ${delta.toFixed(1)}px, 0)`;
      ticking = false;
    };
    const onScroll = () => {
      if (!ticking) {ticking = true;requestAnimationFrame(update);}
    };
    update();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, [ref, factor]);
}

/* ------------------------------------------------------------------
   Navigation
   ------------------------------------------------------------------ */
/* ------------------------------------------------------------------
   Demo drawer — slides in from the right on "Book a demo"
   ------------------------------------------------------------------ */
const openDemo = () => window.dispatchEvent(new CustomEvent("wisbid:demo"));

const DemoDrawer = () => {
  const t = useT();
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const onOpen = () => setOpen(true);
    window.addEventListener("wisbid:demo", onOpen);
    return () => window.removeEventListener("wisbid:demo", onOpen);
  }, []);
  useEffect(() => {
    const onKey = (e) => {if (e.key === "Escape") setOpen(false);};
    if (open) {
      document.addEventListener("keydown", onKey);
      document.body.style.overflow = "hidden";
    }
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [open]);

  const channels = [
  { k: "email", icon: "inbox", label: t("demo.emailLabel"), value: "pohwp@wisbid.com", href: "mailto:pohwp@wisbid.com?subject=Wisbid%20demo%20request" },
  { k: "phone", icon: "users", label: t("demo.callLabel"), value: "+65 9475 5548", href: "tel:+6594755548" }];



  return (
    <div className={`dd-root ${open ? "is-open" : ""}`} aria-hidden={!open}>
      <div className="dd-scrim" onClick={() => setOpen(false)} />
      <aside className="dd-panel" role="dialog" aria-modal="true" aria-label={t("demo.eyebrow")}>
        <div className="dd-head">
          <div>
            <span className="dd-eyebrow"><span className="dot" />{t("demo.eyebrow")}</span>
            <h3>{t("demo.title")}</h3>
            <p>{t("demo.body")}</p>
          </div>
          <button className="dd-close" onClick={() => setOpen(false)} aria-label={t("aria.closeMenu", "Close")}>
            <Icon name="x" size={18} />
          </button>
        </div>

        <div className="dd-section-label">{t("demo.directLabel")}</div>
        <div className="dd-contacts">
          {channels.map((c) =>
          <a key={c.k} className="dd-contact" href={c.href}>
              <span className="dd-contact-ico"><Icon name={c.icon} size={18} /></span>
              <span className="dd-contact-body">
                <span className="lbl">{c.label}</span>
                <span className="val">{c.value}</span>
              </span>
              <Icon name="arrow-up-right" size={16} className="dd-contact-arr" />
            </a>
          )}
        </div>

        <div className="dd-section-label">{t("demo.textLabel")}</div>
        <div className="dd-widgets">
          <a className="dd-widget dd-widget--wa" href="https://wa.me/+6594755548" target="_blank" rel="noopener noreferrer">
            <span className="dd-widget-ico">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2a10 10 0 0 0-8.5 15.2L2 22l4.9-1.3A10 10 0 1 0 12 2zm5.4 14.2c-.2.6-1.3 1.2-1.8 1.3-.5.1-1 .1-1.7-.1-.4-.1-.9-.3-1.6-.6-2.8-1.2-4.6-4-4.8-4.2-.1-.2-1.1-1.4-1.1-2.7s.7-1.9 1-2.2c.2-.2.5-.3.7-.3h.5c.2 0 .4 0 .6.5l.8 2c.1.2.1.4 0 .6l-.4.5-.4.4c-.1.2-.3.3-.1.6.1.3.7 1.1 1.5 1.7 1 .9 1.8 1.1 2 1.2.3.1.4.1.6-.1l.7-.8c.2-.2.4-.2.6-.1l1.8.9c.3.1.5.2.6.4 0 .1 0 .8-.2 1.5z" /></svg>
            </span>
            <span className="dd-widget-body">
              <span className="lbl">{t("demo.whatsapp")}</span>
              <span className="val">{t("demo.whatsappSub")}</span>
            </span>
          </a>
        </div>

        <div className="dd-foot">
          <span className="dd-trust"><Icon name="shield" size={14} />{t("demo.trust")}</span>
        </div>
      </aside>
    </div>);

};

/* ------------------------------------------------------------------
   Navigation
   ------------------------------------------------------------------ */
const Navigation = () => {
  const t = useT();
  const [locale, setLocale] = useLocale();
  const [scrolled, setScrolled] = useState(false);
  const [mega, setMega] = useState(null);
  const [mobile, setMobile] = useState(false);
  const [langOpen, setLangOpen] = useState(false);
  const langRef = useRef(null);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 16);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    if (!langOpen) return;
    const onDoc = (e) => {
      if (langRef.current && !langRef.current.contains(e.target)) setLangOpen(false);
    };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [langOpen]);

  const LANGS = [
  { code: "en", short: "EN", label: "English", native: "English", flag: "assets/flags/en.png" },
  { code: "zh", short: "ZH", label: "Chinese", native: "中文", flag: "assets/flags/zh.png" },
  { code: "ta", short: "TA", label: "Tamil", native: "தமிழ்", flag: "assets/flags/ta.png" },
  { code: "tl", short: "TL", label: "Tagalog", native: "Tagalog", flag: "assets/flags/tl.svg" },
  { code: "th", short: "TH", label: "Thai", native: "ไทย", flag: "assets/flags/th.png" },
  { code: "ms", short: "MS", label: "Melayu", native: "Melayu", flag: "assets/flags/ms.webp" }];


  const current = LANGS.find((l) => l.code === locale) || LANGS[0];

  const navItems = [
  { key: "product", label: t("nav.product"), mega: true },
  { key: "strategy", label: t("nav.theLoop") },
  { key: "integrations", label: t("nav.integrations") },
  { key: "features", label: t("nav.features") },
  { key: "compare", label: t("nav.compare") },
  { key: "pricing", label: t("nav.pricing") }];



  const [activeNav, setActiveNav] = useState("strategy");
  useEffect(() => {
    const ids = navItems.filter((n) => !n.mega).map((n) => n.key);
    const els = ids.map((id) => document.getElementById(id)).filter(Boolean);
    if (!els.length) return;
    const io = new IntersectionObserver(
      (entries) => {
        const visible = entries.
        filter((e) => e.isIntersecting).
        sort((a, b) => b.intersectionRatio - a.intersectionRatio);
        if (visible.length) setActiveNav(visible[0].target.id);
      },
      { rootMargin: "-30% 0px -50% 0px", threshold: [0, 0.1, 0.25, 0.5] }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  const handleNavClick = (e, key) => {
    e.preventDefault();
    const el = document.getElementById(key);
    if (!el) return;
    const navHeight = 68;
    const rect = el.getBoundingClientRect();
    const sectionTop = rect.top + window.scrollY;
    let top;
    if (key === "integrations") {
      // Integrations is a 220vh scroll-pinned section: the logos only become
      // visible mid-progress. Aim for ~55% through so the row is centred.
      const vh = window.innerHeight;
      const total = Math.max(0, rect.height - vh);
      top = sectionTop + total * 0.55 - navHeight - 8;
    } else {
      top = sectionTop - navHeight - 8;
    }
    window.scrollTo({ top, behavior: "smooth" });
    setMega(null);
    setMobile(false);
  };


  return (
    <nav className={`lp-nav ${scrolled ? "is-scrolled" : ""}`}>
      <div className="lp-shell lp-nav-inner" onMouseLeave={() => setMega(null)}>
        <a href="#top" className="lp-logo">
          <img src="assets/wisbid-icon.png" alt="" />
          Wisbid
        </a>
        <div className="lp-nav-links">
          {navItems.map((n) =>
          n.mega ?
          <a
            key={n.key}
            href="#strategy"
            className={`lp-nav-link ${mega === n.key ? "is-active" : ""}`}
            onMouseEnter={() => setMega(n.key)}
            onClick={(e) => handleNavClick(e, "strategy")}>
            
              {n.label}
              <Icon name="chevron-down" size={14} />
            </a> :

          <a
            key={n.key}
            href={`#${n.key}`}
            className={`lp-nav-link ${activeNav === n.key ? "is-active" : ""}`}
            onMouseEnter={() => setMega(null)}
            onClick={(e) => handleNavClick(e, n.key)}>
            
              {n.label}
            </a>
          )}
        </div>
        <div className="lp-nav-right">
          <div className="lp-lang-wrap" ref={langRef}>
            <button
              className={`lp-lang ${langOpen ? "is-open" : ""}`}
              onClick={() => setLangOpen((v) => !v)}
              aria-haspopup="listbox"
              aria-label={t("aria.languageMenu", "Language menu")}
              aria-expanded={langOpen}>
              
              <span className="lp-lang-cur">
                <span className="code">{current.short}</span>
                <span className="native">{current.native}</span>
              </span>
              <img className="lp-lang-flag" src={current.flag} alt="" />
              <Icon name="chevron-down" size={12} />
            </button>
            {langOpen &&
            <div className="lp-lang-menu" role="listbox">
                {LANGS.map((l) =>
              <button
                key={l.code}
                type="button"
                role="option"
                aria-selected={locale === l.code}
                className={`lp-lang-item ${locale === l.code ? "is-selected" : ""}`}
                onClick={() => {setLocale(l.code);setLangOpen(false);}}>
                
                    <span className="lp-lang-meta">
                      <span className="lp-lang-code">{l.short}</span>
                      <span className="lp-lang-native">{l.native}</span>
                    </span>
                    <img className="lp-lang-flag" src={l.flag} alt="" />
                  </button>
              )}
              </div>
            }
          </div>
          <a href="#cta" className="lp-cta-sm" onClick={(e) => {e.preventDefault();openDemo();}}>{t("nav.bookDemo")}<Icon name="arrow-right" size={14} /></a>
          <button className="lp-burger" onClick={() => setMobile(true)} aria-label={t("nav.openMenu")}>
            <Icon name="menu" size={18} />
          </button>
        </div>
        {/* Mega menu */}
        <div className={`lp-mega ${mega === "product" ? "is-open" : ""}`}>
          <div className="lp-shell lp-mega-grid">
            <div className="lp-mega-col">
              <h4>{t("mega.products")}</h4>
              <a className="lp-mega-item" href="cmms.html">
                <div className="lp-mega-item-title"><Icon name="wrench" size={16} />{t("mega.fmMaintenance")}</div>
                <div className="lp-mega-item-desc">{t("mega.fmDesc")}</div>
              </a>
            </div>
            <div className="lp-mega-col">
              <h4>{t("mega.features")}</h4>
              {[
              [t("mega.copilot"), t("mega.copilotDesc"), "features"],
              [t("mega.intake"), t("mega.intakeDesc"), "features"],
              [t("mega.crossPlatform"), t("mega.crossPlatformDesc"), "features"],
              [t("mega.agentTask"), "", "features"]].
              map(([title, d, target]) =>
              <a key={title} className="lp-mega-item" href={`#${target}`} onClick={(e) => handleNavClick(e, target)}>
                  <div className="lp-mega-item-title">{title}</div>
                  {d && <div className="lp-mega-item-desc">{d}</div>}
                </a>
              )}
            </div>
            <div className="lp-mega-col">
              <h4>{t("mega.whyWisbid")}</h4>
              {[
              [t("nav.compare"), "compare"],
              [t("nav.pricing"), "pricing"],
              [t("nav.theLoop"), "strategy"],
              [t("nav.integrations"), "integrations"]].
              map(([title, target]) =>
              <a key={title} className="lp-mega-item" href={`#${target}`} onClick={(e) => handleNavClick(e, target)}>
                  <div className="lp-mega-item-title">{title}</div>
                </a>
              )}
            </div>
            <div className="lp-mega-col">
              <h4>{t("mega.builtInSg")}</h4>
              <a className="lp-mega-item" href="#compare" onClick={(e) => handleNavClick(e, "compare")}>
                <div className="lp-mega-item-title">{t("mega.dataResidency")}</div>
                <div className="lp-mega-item-desc">{t("mega.dataResidencyDesc")}</div>
              </a>
              <a className="lp-mega-item" href="#strategy" onClick={(e) => handleNavClick(e, "strategy")}>
                <div className="lp-mega-item-title">{t("mega.wisaiGov")}</div>
                <div className="lp-mega-item-desc">{t("mega.wisaiGovDesc")}</div>
              </a>
            </div>
          </div>
        </div>
      </div>
      {/* Mobile menu */}
      {mobile &&
      <div className="lp-mobile-menu is-open">
          <button className="lp-burger" onClick={() => setMobile(false)} aria-label={t("nav.close")} style={{ marginBottom: 24 }}>
            <Icon name="x" size={18} />
          </button>
          {navItems.filter((n) => !n.mega).map((n) =>
        <a
          key={n.key}
          href={`#${n.key}`}
          onClick={(e) => handleNavClick(e, n.key)}
          style={{ display: 'block', padding: '14px 0', borderBottom: '1px solid var(--wb-border)', fontSize: 18, fontWeight: 500, color: 'var(--wb-navy-900)', textDecoration: 'none' }}>
          {n.label}</a>
        )}
          <a href="#cta" className="lp-cta-sm" style={{ marginTop: 24, width: '100%', justifyContent: 'center', height: 48 }} onClick={(e) => {e.preventDefault();setMobile(false);openDemo();}}>{t("nav.bookDemo")}</a>
        </div>
      }
    </nav>);

};

/* ------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------ */
const Hero = () => {
  const t = useT();
  const mockRef = useRef(null);
  useParallax(mockRef, 0.04);
  return (
    <section className="lp-hero" id="top">
      <div className="lp-hero-bg" />
      <div className="lp-hero-grid" />
      <div className="lp-shell lp-hero-inner">
        <div className="lp-hero-eyebrow lp-reveal">
          <span className="dot"><Icon name="sparkles" size={10} /></span>
          {t("hero.eyebrow")}
        </div>
        <h1 className="lp-reveal" data-stagger="1">
          {t("hero.headline1")} <em>{t("hero.headlineEm")}</em>{t("hero.headlineEnd")}
        </h1>
        <h2 className="lp-hero-lede lp-reveal" data-stagger="2">
          {t("hero.lede")}
        </h2>
        <div className="lp-hero-cta lp-reveal" data-stagger="3">
          <a href="#cta" className="lp-btn-primary" onClick={(e) => {e.preventDefault();openDemo();}}>
            {t("btn.bookDemo")}<Icon name="arrow-right" size={16} className="arrow" />
          </a>
          <a href="#product" className="lp-btn-ghost">
            <Icon name="play" size={14} /> {t("hero.ctaSee")}
          </a>
        </div>
        <a href="#strategy" className="lp-scroll-cue lp-reveal" data-stagger="4" style={{ textDecoration: 'none' }}>
          {t("hero.scrollCue")}<span className="line" />
        </a>
        <div ref={mockRef} className="lp-reveal" data-stagger="4" style={{ width: '100%' }}>
          <PlatformPreview />
        </div>
      </div>
    </section>);

};

/* ------------------------------------------------------------------
   Strategy + AI execution — 4 intelligence cards
   ------------------------------------------------------------------ */
const Strategy = () => {
  const t = useT();
  const cards = [
  { kind: "intake", label: t("strategy.card1.label", "Intake & Triage"), title: t("strategy.card1.title", "Every channel becomes a real work item"), desc: t("strategy.card1.desc", "Email, WhatsApp, voice, walk-in — Wisbid turns messy intake into a tracked request with the right asset, vendor and SLA already attached.") },
  { kind: "dispatch", label: t("strategy.card2.label", "Dispatch"), title: t("strategy.card2.title", "Right team, right context, first time"), desc: t("strategy.card2.desc", "WisAI matches each request to the technician, vendor or DLP partner who has handled it before. Routes, ETAs and prior work travel with the dispatch.") },
  { kind: "evidence", label: t("strategy.card3.label", "Evidence"), title: t("strategy.card3.title", "Close with proof, not promises"), desc: t("strategy.card3.desc", "Geo-tagged photos, checklist steps, meter readings and vendor signatures attach as you work — every closure carries its audit trail.") },
  { kind: "audit", label: t("strategy.card4.label", "Audit"), title: t("strategy.card4.title", "Audit-ready, every quarter"), desc: t("strategy.card4.desc", "Inspection packs assemble themselves: SOPs, evidence, vendor sign-off, approver notes. Export to PDF when BCA, MCST chair or insurer asks.") }];

  return (
    <section className="lp-section" id="strategy">
      <div className="lp-shell">
        <div className="lp-reveal" style={{ maxWidth: 720 }}>
          <span className="lp-eyebrow"><span className="num">01</span>{t("loop.kicker", "The Wisbid loop")}</span>
          <h2 className="is-large">{t("loop.lead", "One platform from request to closure — with WisAI doing the work in between.")}</h2>
          <p className="lede">{t("loop.sub", "Four intelligence layers, one operational loop. Wisbid replaces the spreadsheets, group chats and PDF email chains FM teams use today.")}</p>
        </div>
        <div className="lp-strategy-grid">
          {cards.map((c, i) =>
          <article key={c.kind} className="lp-strategy-card lp-reveal" data-stagger={i + 1}>
              <span className="label"><span className="dot" />{c.label} {t("strategy.intelligence", "Intelligence")}</span>
              <h3>{c.title}</h3>
              <p>{c.desc}</p>
              <StrategyVisual kind={c.kind} />
              <a href="#dive" className="lp-link-arrow" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, marginTop: 18, color: 'var(--wb-navy-700)', fontWeight: 500, fontSize: 14, textDecoration: 'none' }}>
                {t("strategy.readMore", "Read more")}<Icon name="arrow-right" size={14} />
              </a>
            </article>
          )}
        </div>
      </div>
    </section>);

};

/* ------------------------------------------------------------------
   Customer logo strip
   ------------------------------------------------------------------ */
const Logos = () => {
  const t = useT();
  // Fictional but plausible Singapore facilities customer placeholders.
  const customers = ["Marina One MCST", "Northbridge Estates", "Sentosa Quay", "Pacific Estate", "Keppel Bay MCST", "Orchard Towers", "Robinson 88", "Bedok Reservoir TC", "Punggol Coast", "Kent Ridge FM", "Bukit Batok MCST", "Tampines Edge"];
  return (
    <section className="lp-logos lp-reveal" id="customers">
      <div className="lp-shell">
        <div className="heading">{t("logos.heading", "The best facilities teams in Singapore run on Wisbid")}</div>
        <div className="lp-logo-grid">
          {customers.map((c) =>
          <div key={c} className="lp-logo-cell" title={c}>
              {c.split(" ").slice(0, 2).join(" ")}
            </div>
          )}
        </div>
      </div>
    </section>);

};

/* ------------------------------------------------------------------
   WisAiScenarioShowcase — WisAI Copilot scenario animation
   ------------------------------------------------------------------ */
const useWisAiMotionInView = typeof window !== "undefined" && window.Motion && window.Motion.useInView ? window.Motion.useInView : null;
const useWisAiMotionReduced = typeof window !== "undefined" && window.Motion && window.Motion.useReducedMotion ? window.Motion.useReducedMotion : null;
const WISAI_EASE = typeof _EASE !== "undefined" ? _EASE : [0.22, 1, 0.36, 1];

const panelVariants = {
  hidden: { opacity: 0, y: 14, scale: 0.99 },
  show: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.42, ease: WISAI_EASE } },
  exit: { opacity: 0, y: -10, scale: 0.99, transition: { duration: 0.24, ease: WISAI_EASE } }
};
const staggerContainer = {
  hidden: {},
  show: { transition: { staggerChildren: 0.1, delayChildren: 0.08 } }
};
const staggerItem = {
  hidden: { opacity: 0, y: 10 },
  show: { opacity: 1, y: 0, transition: { duration: 0.34, ease: WISAI_EASE } }
};
const cardReveal = {
  hidden: { opacity: 0, y: 16, scale: 0.98 },
  show: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.42, ease: WISAI_EASE } }
};
const sourceScan = {
  hidden: { opacity: 0, y: 12, scale: 0.98 },
  show: (i = 0) => ({
    opacity: 1,
    y: 0,
    scale: 1,
    transition: { delay: i * 0.15, duration: 0.38, ease: WISAI_EASE }
  })
};

const SCENARIOS = [
  {
    key: "blocked",
    tabLabel: "Why is this blocked?",
    tabSubcopy: "Email + work log + WO chat",
    prompt: "Why has WO-2026-SM-0148 been blocked for so long? Check the Gmail vendor email thread, the work order timeline, technician work logs, and internal work-order chat. Tell me the blocker and draft the next update.",
    headline: "Blocked on site access confirmation — not technician availability.",
    body: "The vendor is ready to attend, and the technician has noted that parts are available. The work order remains on hold because the Level 2 service-corridor night access slot and isolation permit have not been confirmed.",
    actions: ["Copy requester update", "Draft vendor reply", "Add internal note draft", "Open work order"],
    progress: [
      "Reading recent Gmail messages",
      "Retrieving work order timeline",
      "Checking technician work logs",
      "Checking internal work-order chat"
    ],
    checked: [
      "Gmail",
      "Work orders",
      "Technician work logs",
      "Internal work-order chat"
    ],
    sources: [
      ["Gmail vendor thread", "Vendor requested night access + isolation permit", "gmail"],
      ["Work order timeline", "On Hold · Waiting for Site Access", "clock"],
      ["Technician work log", "Parts ready · awaiting mall access", "file"],
      ["Internal WO chat", "Site team asked to confirm Level 2 access", "users"]
    ],
    artifactTitle: "Blocker summary",
    draft: {
      title: "Draft requester update",
      text: "Hi, the repair is currently waiting for the confirmed night access slot for the Level 2 service corridor. The vendor has confirmed readiness to attend once access is approved. We will update you once the access window is confirmed."
    }
  },
  {
    key: "breaking",
    tabLabel: "What keeps breaking?",
    tabSubcopy: "Site trends + hotspots",
    prompt: "What are the most common issues across Sunshine Mall in the past 3 months? Show the top issue types, affected locations, recurring assets, and which ones are driving repeat work orders.",
    headline: "Air-conditioning comfort complaints are the top recurring issue at Sunshine Mall.",
    body: "The highest volume comes from aircon not cold / comfort complaints, followed by water leaks and toilet plumbing issues. Level 2 East Atrium and B1 Food Court are the main hotspots, with FCU-L2-17 showing repeated work-order activity.",
    actions: ["Open in Reports & Analytics", "Show underlying work orders", "Download CSV", "Create ops brief draft"],
    progress: [
      "Reading Sunshine Mall requests",
      "Retrieving work orders from the past 3 months",
      "Grouping problem codes",
      "Checking recurring assets"
    ],
    checked: [
      "Service requests",
      "Work orders",
      "Problem codes",
      "Assets & locations"
    ],
    bars: [
      ["Aircon not cold", 42],
      ["Water leak", 31],
      ["Toilet blockage", 24],
      ["Lighting fault", 18],
      ["Escalator/lift area defect", 11]
    ],
    hotspots: ["Level 2 East Atrium", "B1 Food Court", "Level 3 Toilets"],
    repeatAssets: ["FCU-L2-17", "AHU-B1-03", "Sump Pump-B1-02"]
  },
  {
    key: "dlp",
    tabLabel: "DLP / warranty check",
    tabSubcopy: "Asset documents + citations",
    prompt: "For WO-2026-SM-0148 on FCU-L2-17, check the O&M manual and DLP/warranty documents. Is this likely DLP/warranty relevant, what does the manual say to check, and what evidence should the technician capture before closure?",
    headline: "This appears DLP/warranty-relevant, but should be reviewed before formal claim submission.",
    body: "The DLP schedule indicates FCU-L2-17 is still within the defects liability period. The O&M manual points first to condensate tray condition, drain blockage, float switch operation, and chilled-water line insulation checks. Before closure, the technician should capture clear evidence so the FM team can decide whether to raise a DLP/warranty claim.",
    actions: ["Create checklist draft", "Open asset documents", "Attach citation pack", "Open work order"],
    progress: [
      "Retrieving permitted asset documents",
      "Reading O&M manual",
      "Checking DLP / warranty schedule",
      "Reviewing commissioning report"
    ],
    checked: [
      "Work orders",
      "O&M manual",
      "DLP / warranty schedule",
      "Commissioning report"
    ],
    docs: [
      ["O&M Manual", "FCU Series O&M Manual", "Condensate drainage inspection", "Page 42", "p.42"],
      ["DLP / Warranty Schedule", "Sunshine Mall Handover Pack", "Mechanical equipment DLP", "Page 7", "p.7"],
      ["Commissioning Report", "FCU-L2-17 commissioning checklist", "Page 3", "Page 3", "p.3"]
    ],
    checklist: [
      "Affected ceiling / stain area",
      "FCU-L2-17 nameplate",
      "Condensate tray condition",
      "Drain-line test result",
      "Float switch test result",
      "Before / after photos",
      "Completion note with likely cause"
    ]
  }
];

function useWisAiReducedMotionFallback() {
  const [reduced, setReduced] = useState(false);
  useEffect(() => {
    const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
    const update = () => setReduced(mq.matches);
    update();
    mq.addEventListener("change", update);
    return () => mq.removeEventListener("change", update);
  }, []);
  return reduced;
}

function useWisAiInViewFallback(ref) {
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), {
      threshold: 0.28,
      rootMargin: "0px 0px -10% 0px"
    });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [ref]);
  return inView;
}

const WisAiMotionNode = (props) => {
  const as = props.as || "div";
  const enabled = props.enabled !== false;
  const className = props.className;
  const children = props.children;
  const style = props.style;
  const variants = props.variants;
  const initial = props.initial;
  const animate = props.animate;
  const exit = props.exit;
  const transition = props.transition;
  const custom = props.custom;
  const domProps = {};
  const localKeys = [
    "as",
    "enabled",
    "className",
    "children",
    "style",
    "variants",
    "initial",
    "animate",
    "exit",
    "transition",
    "custom"
  ];
  Object.keys(props).forEach((key) => {
    if (!localKeys.includes(key)) domProps[key] = props[key];
  });
  if (enabled && _motion) {
    const MotionTag = _motion[as] || _motion.div;
    return React.createElement(
      MotionTag,
      Object.assign({}, domProps, {
        className,
        style,
        variants,
        initial,
        animate,
        exit,
        transition,
        custom
      }),
      children
    );
  }
  const Tag = as;
  return React.createElement(Tag, Object.assign({}, domProps, { className, style }), children);
};

const ScenarioTabs = ({ scenarios, activeKey, onSelect, tabRefs }) => {
  const onKeyDown = (event, index) => {
    const last = scenarios.length - 1;
    let nextIndex = index;
    if (event.key === "ArrowRight") nextIndex = index === last ? 0 : index + 1;
    if (event.key === "ArrowLeft") nextIndex = index === 0 ? last : index - 1;
    if (event.key === "Home") nextIndex = 0;
    if (event.key === "End") nextIndex = last;
    if (nextIndex !== index) {
      event.preventDefault();
      onSelect(nextIndex, true);
      window.requestAnimationFrame(() => tabRefs.current[nextIndex] && tabRefs.current[nextIndex].focus());
    }
  };

  return (
    <div className="wai-scenario-tabs" role="tablist" aria-label="WisAI scenario examples">
      {scenarios.map((scenario, index) =>
      <button
        key={scenario.key}
        ref={(node) => {tabRefs.current[index] = node;}}
        type="button"
        role="tab"
        id={`wai2-tab-${scenario.key}`}
        aria-controls={`wai2-panel-${scenario.key}`}
        aria-selected={activeKey === scenario.key}
        tabIndex={activeKey === scenario.key ? 0 : -1}
        className={`wai-scenario-tab ${activeKey === scenario.key ? "is-active" : ""}`}
        onClick={() => onSelect(index, true)}
        onKeyDown={(event) => onKeyDown(event, index)}>
          <span className="wai-scenario-tab-label">{scenario.tabLabel}</span>
          <span className="wai-scenario-tab-sub">{scenario.tabSubcopy}</span>
        </button>
      )}
    </div>
  );
};

const AnimatedSourceCard = ({ source, index, motionEnabled }) => (
  <WisAiMotionNode
    enabled={motionEnabled}
    className="wai-source-card"
    custom={index}
    variants={sourceScan}
    initial="hidden"
    animate="show">
    <div className={`wai-source-icon ${source[2] === "gmail" ? "is-gmail" : ""}`}>
      {source[2] === "gmail" ? <img src="assets/gmail-icon.svg" alt="" /> : <Icon name={source[2]} size={14} />}
    </div>
    <div className="wai-source-body">
      <span>{source[0]}</span>
      <strong>{source[1]}</strong>
    </div>
    <span className="wai-source-check"><Icon name="check" size={12} /></span>
  </WisAiMotionNode>
);

const MarkdownRule = () => <div className="wai-md-rule" aria-hidden="true" />;

const MarkdownTable = ({ columns, rows }) => (
  <div className="wai-md-table-wrap">
    <table className="wai-md-table">
      <thead>
        <tr>
          {columns.map((column) => <th key={column}>{column}</th>)}
        </tr>
      </thead>
      <tbody>
        {rows.map((row, index) =>
        <tr key={`${row.join("-")}-${index}`}>
          {row.map((cell, cellIndex) => <td key={`${cell}-${cellIndex}`}>{cell}</td>)}
        </tr>
        )}
      </tbody>
    </table>
  </div>
);

const WhyBlockedArtifact = ({ scenario, motionEnabled }) => (
  <div className="wai-markdown wai-fade-in">
    <MarkdownRule />
    <h4>{scenario.artifactTitle}</h4>
    <MarkdownTable
      columns={["Source", "Finding"]}
      rows={scenario.sources.map((source) => [source[0], source[1]])} />

    <MarkdownRule />
    <h4>{scenario.draft.title}</h4>
    <p>{scenario.draft.text}</p>
  </div>
);

// Categorical palette (ECharts-style), matched to Wisbid tokens.
const WAI_BAR_COLORS = [
  "var(--wb-navy-600)",
  "var(--wb-info-500)",
  "var(--wb-success-500)",
  "var(--wb-warning-500)",
  "var(--wb-error-500)"
];
const MiniBarChart = ({ bars, motionEnabled }) => {
  const max = Math.max(...bars.map(([, value]) => value));
  return (
    <div className="wai-bars" aria-label="Top issue types in the past 3 months">
      {bars.map(([label, value], index) => {
        const pct = `${Math.round(value / max * 100)}%`;
        const color = WAI_BAR_COLORS[index % WAI_BAR_COLORS.length];
        return (
          <div className="wai-bar-row" key={label}>
            <span className="wai-bar-label">{label}</span>
            <div className="wai-bar-track">
              <WisAiMotionNode
                as="span"
                enabled={motionEnabled}
                className="wai-bar-fill"
                initial={{ width: 0 }}
                animate={{ width: pct }}
                transition={{ delay: 0.18 + index * 0.09, duration: 0.64, ease: WISAI_EASE }}
                style={motionEnabled ? { background: color } : { width: pct, background: color }} />
            </div>
            <strong>{value}</strong>
          </div>
        );
      })}
    </div>
  );
};

const WhatKeepsBreakingArtifact = ({ scenario, motionEnabled }) => (
  <div className="wai-markdown wai-fade-in">
    <MarkdownRule />
    <h4>Most common issues (last 3 months)</h4>
    <MiniBarChart bars={scenario.bars} motionEnabled={motionEnabled} />

    <MarkdownRule />
    <h4>Hotspot locations</h4>
    <ul>
      {scenario.hotspots.map((item) => <li key={item}>{item}</li>)}
    </ul>

    <h4>Repeat assets</h4>
    <ul>
      {scenario.repeatAssets.map((item) => <li key={item}>{item}</li>)}
    </ul>
  </div>
);

const DlpWarrantyArtifact = ({ scenario, motionEnabled }) => (
  <div className="wai-markdown wai-fade-in">
    <MarkdownRule />
    <h4>Documents reviewed</h4>
    <MarkdownTable
      columns={["Document", "Finding", "Citation"]}
      rows={scenario.docs.map((doc) => [doc[1], doc[2], doc[4]])} />

    <MarkdownRule />
    <h4>Evidence to capture</h4>
    <ul>
      {scenario.checklist.map((item) => <li key={item}>{item}</li>)}
    </ul>
  </div>
);

const ScenarioArtifact = ({ scenario, motionEnabled }) => {
  if (scenario.key === "blocked") return <WhyBlockedArtifact scenario={scenario} motionEnabled={motionEnabled} />;
  if (scenario.key === "breaking") return <WhatKeepsBreakingArtifact scenario={scenario} motionEnabled={motionEnabled} />;
  return <DlpWarrantyArtifact scenario={scenario} motionEnabled={motionEnabled} />;
};

const WhatIChecked = ({ items }) => (
  <div className="wai-ai-checked wai-fade-in">
    <button type="button" className="wai-checked-row">
      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="m9 18 6-6-6-6" />
      </svg>
      <strong>What I checked</strong>
      <span>{items.length} checks, 0 references</span>
    </button>
    <div className="wai-checked-list">
      {items.map((item) => <span key={item}>{item}</span>)}
    </div>
  </div>
);

const ActionButtonRow = ({ actions, motionEnabled }) => (
  <WisAiMotionNode
    enabled={motionEnabled}
    className="wai-actions wai-fade-in"
    variants={staggerContainer}
    initial="hidden"
    animate="show">
    {actions.map((action) =>
    <WisAiMotionNode
      enabled={motionEnabled}
      as="button"
      key={action}
      className="wai-action"
      type="button"
      variants={staggerItem}>
      {action}
    </WisAiMotionNode>
    )}
  </WisAiMotionNode>
);

const WisAiProgressList = ({ scenario }) => (
  <div className="wai-progress-list wai-fade-in" aria-label="WisAI source checks in progress">
    {scenario.progress.map((item, index) =>
    <div
      key={item}
      className={`wai-progress-row ${index < scenario.progress.length - 1 ? "is-done" : "is-active"}`}
      style={{ "--progress-delay": `${index * 260}ms` }}>
      <span className="wai-progress-status" aria-hidden="true">
        {index < scenario.progress.length - 1 ? "✓" : ""}
      </span>
      {item.includes("Gmail") &&
      <span className="wai-progress-gmail" aria-hidden="true">
        <img src="assets/gmail-icon.svg" alt="" />
      </span>
      }
      <span>{index < scenario.progress.length - 1 ? item : "Thinking..."}</span>
    </div>
    )}
  </div>
);

const ScenarioConversation = ({ scenario, replayKey, motionEnabled, inView }) => {
  const completePhase = 6;
  const shouldAnimate = motionEnabled && inView;
  const [phase, setPhase] = useState(shouldAnimate ? 0 : completePhase);
  const [headlineIdx, setHeadlineIdx] = useState(shouldAnimate ? 0 : scenario.headline.length);

  useEffect(() => {
    setPhase(shouldAnimate ? 0 : completePhase);
    setHeadlineIdx(shouldAnimate ? 0 : scenario.headline.length);
  }, [scenario.key, replayKey, shouldAnimate, scenario.headline.length]);

  useEffect(() => {
    if (!shouldAnimate) return;
    if (phase === 0) {const id = setTimeout(() => setPhase(1), 260);return () => clearTimeout(id);}
    if (phase === 1) {const id = setTimeout(() => setPhase(2), 820);return () => clearTimeout(id);}
    if (phase === 2) {const id = setTimeout(() => setPhase(3), 2400);return () => clearTimeout(id);}
    if (phase === 4) {const id = setTimeout(() => setPhase(5), 1750);return () => clearTimeout(id);}
    if (phase === 5) {const id = setTimeout(() => setPhase(6), 560);return () => clearTimeout(id);}
  }, [phase, shouldAnimate]);

  useEffect(() => {
    if (!shouldAnimate || phase !== 3) return;
    if (headlineIdx >= scenario.headline.length) {
      const id = setTimeout(() => setPhase(4), 260);
      return () => clearTimeout(id);
    }
    const id = setTimeout(() => setHeadlineIdx((value) => value + 1), 22);
    return () => clearTimeout(id);
  }, [phase, headlineIdx, shouldAnimate, scenario.headline.length]);

  const showUser = phase >= 1;
  const showThinking = phase === 2;
  const showAnswer = phase >= 3;
  const showBody = phase >= 4;
  const showChecked = phase >= 5;
  const showActions = phase >= 6;
  const headline = phase >= 4 ? scenario.headline : scenario.headline.slice(0, headlineIdx);

  return (
    <div
      key={`${scenario.key}-${replayKey}`}
      className="wai-conversation-stage"
      id={`wai2-panel-${scenario.key}`}
      role="tabpanel"
      aria-labelledby={`wai2-tab-${scenario.key}`}>
      {showUser &&
      <div className="wai-row wai-row--user wai-fade-in">
        <div className="wai-bubble">
          <div className="wai-bubble-meta">
            <strong>You</strong>
            <span>2026-05-27 16:07 UTC</span>
          </div>
          <div className="wai-bubble-text">{scenario.prompt}</div>
        </div>
        <div className="wai-avatar wai-avatar--user">Y</div>
      </div>
      }

      {(showThinking || showAnswer) &&
      <div className="wai-row wai-row--ai wai-fade-in">
        <div className="wai-avatar wai-avatar--ai">
          <img src="assets/wisbid-icon.png" alt="" />
        </div>
        <div className="wai-ai">
          <div className="wai-bubble-meta">
            <strong>WisAI</strong>
            <span>2026-05-27 16:07 UTC</span>
          </div>

          {showThinking &&
          <WisAiProgressList scenario={scenario} />
          }

          {showAnswer &&
          <p className="wai-ai-lead wai-fade-in">
            <strong>{headline}</strong>{phase === 3 && <span className="wai-caret" />}
          </p>
          }

          {showBody &&
          <p className="wai-ai-foot wai-fade-in">{scenario.body}</p>
          }

          {showBody && <ScenarioArtifact scenario={scenario} motionEnabled={motionEnabled} />}
          {showChecked && <WhatIChecked items={scenario.checked} />}
          {showActions && <ActionButtonRow actions={scenario.actions} motionEnabled={motionEnabled} />}
        </div>
      </div>
      }
    </div>
  );
};

const AssistantPanel = ({
  scenario,
  replayKey,
  motionEnabled,
  setHoverPaused,
  inView
}) => {
  const AP = _AnimatePresence;
  const content = <ScenarioConversation scenario={scenario} replayKey={replayKey} motionEnabled={motionEnabled} inView={inView} />;

  return (
    <div
      className="wai"
      onMouseEnter={() => setHoverPaused(true)}
      onMouseLeave={() => setHoverPaused(false)}
      onFocus={() => setHoverPaused(true)}
      onBlur={(event) => {
        if (!event.currentTarget.contains(event.relatedTarget)) setHoverPaused(false);
      }}>
      <div className="wai-head">
        <div className="wai-mark">
          <img src="assets/wisbid-icon.png" alt="" />
        </div>
        <span className="wai-title">WisAI Assistant</span>
        <div className="wai-head-actions">
          <button className="wai-iconbtn" type="button" aria-label="Expand" aria-disabled="true">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <path d="M4 4h6M4 4v6M20 20h-6M20 20v-6M20 4l-7 7M4 20l7-7" />
            </svg>
          </button>
          <button className="wai-iconbtn" type="button" aria-label="Close" aria-disabled="true">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <path d="M6 6l12 12M6 18 18 6" />
            </svg>
          </button>
        </div>
      </div>

      <div className="wai-conv">
        <button className="wai-conv-pill" type="button">
          {scenario.tabLabel}
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="m6 9 6 6 6-6" />
          </svg>
        </button>
        <span className="wai-tag">Sunshine Mall</span>
        <div className="wai-conv-actions">
          <button className="wai-iconbtn" type="button" aria-label="Settings" aria-disabled="true">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="3" />
              <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.65 1.65 0 0 0 15 19.4a1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51A1.65 1.65 0 0 0 7.18 19.73l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09A1.65 1.65 0 0 0 15 4.6a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9c.15.53.55.95 1.06 1H21a2 2 0 0 1 0 4h-.54c-.51.05-.91.47-1.06 1z" />
            </svg>
          </button>
          <button className="wai-iconbtn" type="button" aria-label="Edit" aria-disabled="true">
            <Icon name="file" size={15} />
          </button>
        </div>
      </div>

      <div className="wai-panel-body" aria-live="polite">
        {AP ? <AP mode="wait">{content}</AP> : content}
      </div>

      <div className="wai-composer" aria-label="WisAI prompt input preview">
        <button type="button" aria-label="Add context">
          <span>+</span>
        </button>
        <span className="wai-composer-placeholder">Ask, search, or explain...</span>
        <button type="button" className="wai-send" aria-label="Send prompt">
          <Icon name="send" size={17} />
        </button>
      </div>
    </div>
  );
};

const WisAiScenarioCopy = ({ scenario, selectScenario, tabRefs }) => (
  <div className="wai-scenario-copy">
    <span className="wai-scenario-eyebrow">WisAI Copilot for FM Operations</span>
    <h3>Stop digging across emails, logs, charts, and manuals.</h3>
    <p>
      Ask about a blocked job, a recurring site issue, or a DLP claim. WisAI checks permitted Wisbid records and connected context, explains what matters, and prepares the next step for review.
    </p>
    <ScenarioTabs
      scenarios={SCENARIOS}
      activeKey={scenario.key}
      onSelect={selectScenario}
      tabRefs={tabRefs} />
  </div>
);

const WisAiScenarioShowcase = () => {
  const rootRef = useRef(null);
  const tabRefs = useRef([]);
  const fallbackInView = useWisAiInViewFallback(rootRef);
  const fallbackReducedMotion = useWisAiReducedMotionFallback();
  const inView = useWisAiMotionInView ? useWisAiMotionInView(rootRef, { amount: 0.28 }) : fallbackInView;
  const reducedMotion = useWisAiMotionReduced ? useWisAiMotionReduced() : fallbackReducedMotion;
  const motionEnabled = Boolean(_motion && !reducedMotion);
  const [activeIndex, setActiveIndex] = useState(0);
  const [replayKey, setReplayKey] = useState(0);
  const [hoverPaused, setHoverPaused] = useState(false);
  const scenario = SCENARIOS[activeIndex];
  const paused = hoverPaused;

  const selectScenario = (nextIndex, pause = false) => {
    setActiveIndex(nextIndex);
    setReplayKey((value) => value + 1);
  };

  useEffect(() => {
    if (!inView || paused || reducedMotion) return;
    const id = window.setInterval(() => {
      setActiveIndex((index) => (index + 1) % SCENARIOS.length);
      setReplayKey((value) => value + 1);
    }, 11000);
    return () => window.clearInterval(id);
  }, [inView, paused, reducedMotion]);

  return (
    <div ref={rootRef} className="wai-scenario-shell">
      <WisAiScenarioCopy
        scenario={scenario}
        selectScenario={selectScenario}
        tabRefs={tabRefs} />
      <div className="lp-glance-glass wai-hero-glass lp-reveal" data-stagger="2">
        <div className="lp-glance-glass-inner">
          <AssistantPanel
            scenario={scenario}
            replayKey={replayKey}
            motionEnabled={motionEnabled}
            setHoverPaused={setHoverPaused}
            inView={inView} />
        </div>
      </div>
    </div>
  );
};

/* ------------------------------------------------------------------
   At-a-glance section — full-bleed photo + frosted-glass WisAI card
   ------------------------------------------------------------------ */
const Glance = () => {
  const t = useT();
  const centerRef = useRef(null);
  useParallax(centerRef, 0.05);

  return (
    <section className="lp-glance" id="glance">
      <div className="lp-shell" style={{ textAlign: 'center' }}>
        <span className="lp-eyebrow lp-reveal"><span className="num">02</span>{t("glance.eyebrow", "At a glance")}</span>
        <h2 className="lp-reveal" style={{ margin: '18px auto 0', maxWidth: '20ch' }}>
          {t("glance.title", "One workspace, four intelligence layers, every site connected.")}
        </h2>
        <p className="lede lp-reveal" data-stagger="1" style={{ margin: '20px auto 0' }}>
          {t("glance.lede", "Modular by site, building or estate. Hosted in Singapore. Connects to the email, calendar and accounting tools your team already uses.")}
        </p>
      </div>

      <div ref={centerRef} className="lp-glance-photo wai-hero-photo lp-reveal">
        <img src="assets/glance-bg.png" alt={t("glance.imageAlt", "Facilities technician walking the corridor with a tablet")} />
        <WisAiScenarioShowcase />
      </div>
    </section>);
};

/* ------------------------------------------------------------------
   Deep-dive modules — sticky left, scrollable right
   ------------------------------------------------------------------ */
const DIVE_DATA = [
{
  id: "supplier",
  num: "03",
  cat: "Supplier Intelligence",
  title: "Every vendor, every DLP, every signed sign-off — in one place.",
  desc: "Centralise vendor records, contracts and performance. Wisbid keeps DLPs, response SLAs and prior closure rates attached to every dispatch decision.",
  stat: { num: "98%", label: "First-attempt closure rate · DLP-vetted vendors" },
  quote: {
    q: "We stopped chasing vendors. Wisbid surfaces the ones already accountable to us — and shows when a DLP is the right path.",
    name: "Priya Suresh",
    role: "Head of FM, Northbridge Estates",
    initials: "PS"
  },
  features: [
  ["building", "Single vendor record", "Contracts, contacts, sites, DLP windows."],
  ["trend", "Performance scoring", "Response SLA, closure rate, evidence completeness."],
  ["shield", "DLP & warranty awareness", "Wisbid knows when work is owed under existing terms."],
  ["users", "Vendor portal", "Vendors accept work, upload evidence, sign off in one flow."],
  ["lock", "Insurance & licence tracking", "Auto-flag expired BizSafe, WSH or PUB licences."],
  ["file", "Invoice match", "Reconcile invoice to work order, evidence and approver."]]

},
{
  id: "spend",
  num: "04",
  cat: "Spend & Cost Intelligence",
  title: "See where every facilities dollar actually goes.",
  desc: "Reactive vs planned. Block vs estate. Vendor vs in-house. Wisbid attributes every line item — invoice, part, hour — to the request that caused it.",
  stat: { num: "18%", label: "Average reduction in reactive spend within 90 days" },
  quote: {
    q: "Before Wisbid we knew the total. Now we know the why. We cut $40k of repeat seepage spend in one quarter.",
    name: "Marcus Tan",
    role: "Finance Director, Pacific Estate",
    initials: "MT"
  },
  features: [
  ["trend", "Live budget vs actual", "Per block, per category, per vendor."],
  ["compass", "Repeat-cause detection", "Group recurring issues to the underlying asset."],
  ["box", "Asset lifecycle cost", "True cost-of-ownership across the asset's life."],
  ["clock", "Overtime visibility", "After-hours dispatch broken out from BAU."],
  ["file", "Approver trails", "Every PO, quote and invoice with the human who said yes."],
  ["wrench", "Parts & consumables", "Inventory burn tied to work orders, not stockrooms."]]

},
{
  id: "sourcing",
  num: "05",
  cat: "Sourcing Intelligence",
  title: "Run RFQs without the spreadsheet circus.",
  desc: "Issue, compare and award sourcing requests in one workspace. WisAI scores bids against prior closure performance, not just price.",
  stat: { num: "11d", label: "Median RFQ-to-award cycle, down from 28 days" },
  quote: {
    q: "I used to chase quotes for two weeks. Now vendors bid in Wisbid, scores rank themselves, and I approve the right one without leaving the inbox.",
    name: "Cheryl Ng",
    role: "Procurement Lead, Sentosa Quay",
    initials: "CN"
  },
  features: [
  ["send", "One-click RFQ", "Pull scope from the work order, fan out to qualified vendors."],
  ["thumb", "Bid scoring", "Price, lead time, prior closure, evidence completeness."],
  ["sparkles", "WisAI recommendation", "Sourced, ranked, with reasoning attached."],
  ["users", "Vendor short-listing", "Auto-filter for DLP, licence, capacity."],
  ["file", "Quote audit trail", "Every revision and approver kept by default."],
  ["check", "Award & convert", "Winning bid becomes a work order with one click."]]

},
{
  id: "compliance",
  num: "06",
  cat: "Compliance Intelligence",
  title: "Audit-ready before the auditor asks.",
  desc: "SOPs, statutory checks, vendor licences and evidence attach to every closure. Inspection packs assemble themselves — for BCA, MCST chair, or insurer.",
  stat: { num: "32 pages", label: "Average auto-assembled BCA inspection pack" },
  quote: {
    q: "When BCA visited unannounced, we exported the pack in three minutes. The auditor signed off the same day.",
    name: "Raj Kumar",
    role: "Estate Manager, Marina One MCST",
    initials: "RK"
  },
  features: [
  ["shield", "Statutory checks", "Quarterly, annual and ad-hoc due dates tracked per asset."],
  ["file", "SOP attachment", "The right SOP travels with the dispatch, not a shared drive."],
  ["camera", "Evidence completeness", "Closure blocked until photos, readings and signatures land."],
  ["lock", "Vendor licence guardrails", "Expired BizSafe or WSH stops dispatch automatically."],
  ["users", "Approver routing", "MCST chair, FM director, insurer — routed by policy."],
  ["box", "One-click pack export", "PDF or signed JSON for downstream systems."]]

}];


const DiveModule = ({ data }) =>
<section className="lp-dive" id={data.id}>
    <div className="lp-shell lp-dive-inner">
      <div className="lp-dive-sticky lp-reveal">
        <div className="lp-dive-cat">
          <span className="num">{data.num}</span>{data.cat}
        </div>
        <h2>{data.title}</h2>
        <p className="desc">{data.desc}</p>
        <div className="lp-dive-stat">
          <div className="num">{data.stat.num}</div>
          <div className="lbl">{data.stat.label}</div>
        </div>
        <div className="lp-dive-quote">
          <div className="q">"{data.quote.q}"</div>
          <div className="who">
            <span className="avatar">{data.quote.initials}</span>
            <div>
              <div className="nm">{data.quote.name}</div>
              <div className="role">{data.quote.role}</div>
            </div>
          </div>
        </div>
      </div>
      <div>
        <div className="lp-reveal" style={{ marginBottom: 24 }}>
          <DiveShot kind={data.id} />
        </div>
        <div className="lp-dive-features">
          {data.features.map(([ico, t, d], i) =>
        <div key={t} className="lp-dive-feat lp-reveal" data-stagger={i % 4 + 1}>
              <div className="ico"><Icon name={ico} size={20} /></div>
              <div>
                <h4>{t}</h4>
                <p>{d}</p>
              </div>
            </div>
        )}
        </div>
      </div>
    </div>
  </section>;


const DeepDives = () =>
<div id="dive">
    {DIVE_DATA.map((d) => <DiveModule key={d.id} data={d} />)}
  </div>;


/* ------------------------------------------------------------------
   Comparison → replaced by Governance section (assets/landing-governance.jsx)
   ------------------------------------------------------------------ */
const Comparison = () => window.Governance ? <window.Governance /> : null;

/* ------------------------------------------------------------------
   Pricing — single plan, slashed launch price
   ------------------------------------------------------------------ */
const Pricing = () => {
  const t = useT();
  const includes = [
  t("price.include0", "1 Site"),
  t("price.include1", "Unlimited requests, work orders and assets"),
  t("price.include2", "WisAI co-pilot, intake agent and skills"),
  t("price.include3", "Cross-platform workspace: desktop and mobile (Android & iOS)"),
  t("price.include4", "Onboarding and dedicated success manager"),
  t("price.include5", "All future modules included")];


  return (
    <section className="lp-pricing" id="pricing">
      <div className="lp-shell">
        <div className="lp-pricing-head lp-reveal">
          <span className="lp-eyebrow"><span className="num">08</span>{t("price.eyebrow").replace(/^08/, "") || "Pricing"}</span>
          <h2 className="is-large">{t("price.title")}</h2>
          <p className="lede">{t("price.lede")}</p>
        </div>

        <div className="lp-price-card lp-reveal" data-stagger="1">
          <div className="lp-price-glow" aria-hidden="true" />

          <div className="lp-price-top">
            <span className="lp-price-tag">
              <span className="dot" />{t("price.tag", "Invited demo · limited cohort")}
            </span>
            <span className="lp-price-meta lp-mono">{t("price.meta")}</span>
          </div>

          <div className="lp-price-body">
            <div className="lp-price-amount">
              <div className="lp-price-old" aria-label={t("price.originalAria", "Original price: forty-five Singapore dollars")}>
                <span className="cur">S$</span>
                <span className="num">45</span>
                <span className="lp-price-slash" aria-hidden="true" />
              </div>
              <div className="lp-price-new">
                <span className="cur">S$</span>
                <span className="num">0</span>
                <span className="suffix">{t("price.suffix")}</span>
              </div>
              <div className="lp-price-save lp-price-save--big">{t("price.trial", "3-month free trial")}</div>
            </div>

            <div className="lp-price-divider" aria-hidden="true" />

            <ul className="lp-price-includes">
              {includes.map((line) =>
              <li key={line}>
                  <span className="check"><Icon name="check" size={12} /></span>
                  {line}
                </li>
              )}
            </ul>
          </div>

          <div className="lp-price-foot">
            <a href="#cta" className="lp-btn-primary" onClick={(e) => {e.preventDefault();openDemo();}}>
              {t("price.newsletter", "Book Demo")}<Icon name="arrow-right" size={16} className="arrow" />
            </a>
            <span className="lp-price-fine">
              {t("price.fine")}
            </span>
          </div>
        </div>

        <div className="lp-price-notes lp-reveal" data-stagger="2">
          <div className="lp-price-note">
            <Icon name="shield" size={14} />
            <span><strong>{t("price.note1Strong")}</strong> {t("price.note1")}</span>
          </div>
          <div className="lp-price-note">
            <Icon name="users" size={14} />
            <span><strong>{t("price.note2Strong")}</strong> {t("price.note2")}</span>
          </div>
          <div className="lp-price-note">
            <Icon name="sparkles" size={14} />
            <span><strong>{t("price.note3Strong")}</strong> {t("price.note3")}</span>
          </div>
        </div>
      </div>
    </section>);

};

/* ------------------------------------------------------------------
   Final CTA + footer
   ------------------------------------------------------------------ */
const FinalCTA = () => {
  const t = useT();
  return (
    <section className="lp-cta" id="cta">
      <div className="lp-shell">
        <h2 className="lp-reveal">
          {t("cta.proactive", "Be proactive,")}<br /><em>{t("cta.notReactive", "not reactive")}</em>
        </h2>
        <p className="lp-reveal" data-stagger="1" style={{ fontSize: 19, lineHeight: 1.55, color: 'rgba(255,255,255,0.65)', maxWidth: '52ch', margin: '0 auto 40px' }}>
          {t("cta.finalLede")}
        </p>
        <div className="lp-cta-buttons lp-reveal" data-stagger="2">
          <a href="#book" className="lp-btn-primary" onClick={(e) => {e.preventDefault();openDemo();}}>
            {t("btn.bookDemo")}<Icon name="arrow-right" size={16} className="arrow" />
          </a>
        </div>
    </div>
    <Footer />
  </section>);

};


const Footer = () => {
  const t = useT();
  return (
    <footer className="lp-footer">
      <div className="lp-shell lp-footer-grid">
        <div>
          <div className="lp-footer-brand">
            <img src="assets/wisbid-icon.png" alt="" />
            Wisbid
          </div>
          <p className="lp-footer-tag">{t("footer.tag")}</p>
        </div>
        <div className="lp-footer-col">
          <h5>{t("footer.products", "Products")}</h5>
          <a href="cmms.html">{t("mega.fmMaintenance")}</a>
        </div>
        <div className="lp-footer-col">
          <h5>{t("footer.features")}</h5>
          <a href="#features">{t("mega.copilot")}</a>
          <a href="#features">{t("mega.intake")}</a>
          <a href="#features">{t("mega.agentTask")}</a>
        </div>
        <div className="lp-footer-col">
          <h5>{t("footer.company")}</h5>
          <a href="about.html">{t("footer.about", "About")}</a>
          <a href="#book" onClick={(e) => {e.preventDefault();openDemo();}}>{t("btn.bookDemo")}</a>
        </div>
        <div className="lp-footer-col">
          <h5>{t("footer.legal")}</h5>
          <a href="privacy-policy.html">{t("footer.privacy")}</a>
          <a href="#">{t("footer.terms")}</a>
        </div>
      </div>
      <div className="lp-shell lp-footer-bottom">
        <div>{t("footer.copyright")}</div>
      </div>
    </footer>);

};


/* ------------------------------------------------------------------
   App
   ------------------------------------------------------------------ */
const App = () => {
  useReveal();
  return (
    <div className="lp-app">
      <Navigation />
      <DemoDrawer />
      <main>
        <Hero />
        <WisbidLoop />
        <Integrations />
        <Glance />
        <Features />
        <Comparison />
        <Pricing />
        <FinalCTA />
      </main>
    </div>);

};

Object.assign(window, { App, Navigation, Hero, Strategy, Logos, Glance, DeepDives, Comparison, Pricing, FinalCTA, Footer });
