/* ============================================================
   Wonderwild — site chrome: Header, Footer, BookingModal, Page wrapper
   Depends on ww-core.jsx (WW, PAGES, NAV, Button, Logo, Field, Icons, Eyebrow…)
   ============================================================ */

const BookingContext = React.createContext(() => {});
function useBook() { return React.useContext(BookingContext); }

function MenuCardScroll({ children, marginBottom }) {
  const ref = React.useRef(null);
  const [canLeft,  setCanLeft]  = React.useState(false);
  const [canRight, setCanRight] = React.useState(false);
  const check = React.useCallback(() => {
    const el = ref.current; if (!el) return;
    setCanLeft(el.scrollLeft > 4);
    setCanRight(el.scrollLeft < el.scrollWidth - el.clientWidth - 4);
  }, []);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    check();
    el.addEventListener('scroll', check, { passive: true });
    const ro = new ResizeObserver(check);
    ro.observe(el);
    return () => { el.removeEventListener('scroll', check); ro.disconnect(); };
  }, [check]);
  const shift = dir => { const el = ref.current; if (el) el.scrollBy({ left: dir * el.clientWidth * 0.8, behavior: 'smooth' }); };
  const btn = (dir, show, label) => !show ? null : (
    <button aria-label={label} onClick={() => shift(dir)}
      style={{ position: "absolute", top: "50%", transform: "translateY(-50%)",
        [dir === -1 ? "left" : "right"]: "-10px", zIndex: 4,
        background: "rgba(22,38,29,0.85)", border: "1px solid rgba(248,241,233,0.25)",
        borderRadius: "999px", width: "30px", height: "30px",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        color: "var(--cream-100)", cursor: "pointer", backdropFilter: "blur(4px)", padding: 0 }}>
      {dir === -1 ? Icons.arrowLeft : Icons.arrowRight}
    </button>
  );
  return (
    <div style={{ position: "relative", marginBottom }}>
      <div ref={ref} className="ww-menu-cards" style={{ display: "flex", gap: "14px", overflowX: "auto", scrollSnapType: "x mandatory", scrollbarWidth: "none", msOverflowStyle: "none", paddingBottom: "2px" }}>
        {children}
      </div>
      {btn(-1, canLeft,  "Previous")}
      {btn( 1, canRight, "Next")}
    </div>
  );
}

/* ============ SEARCH INDEX ============ */
const SEARCH_INDEX = [
  { title: "Bell Tent Stays", href: "stay", cat: "Accommodation", desc: "Thoughtfully furnished bell tents with fire pits, wild swimming and paddleboards — two hours from London.", tags: ["glamping", "camping", "tent", "accommodation", "stay", "sleep", "overnight", "bed", "book", "bell tent", "norfolk"] },
  { title: "Stay Pricing", href: "stay-pricing", cat: "Accommodation", desc: "Bell tent rates, availability and what's included in every stay.", tags: ["price", "cost", "rates", "how much", "book", "availability", "accommodation"] },
  { title: "Wild Swimming & Sauna", href: "wild-swim-sauna", cat: "Activities", desc: "Book a sauna and wild swim session on our private broad — wood-fired heat, open water and no crowds.", tags: ["sauna", "swim", "swimming", "cold water", "contrast", "heat", "session", "book", "reset"] },
  { title: "Activities & Experiences", href: "activities", cat: "Activities", desc: "Wild swimming, wood-fired sauna, paddleboarding, guided walks and more on the Norfolk Broads.", tags: ["paddleboard", "kayak", "canoe", "swim", "sauna", "walk", "guided", "activities", "things to do", "experiences"] },
  { title: "Things To Do", href: "things-to-do", cat: "Activities", desc: "Everything on offer at Wonderwild — on site and around the Norfolk Broads.", tags: ["activities", "things to do", "explore", "visit", "norfolk broads", "experiences"] },
  { title: "Facilities", href: "facilities", cat: "The Site", desc: "The broad, wood-fired sauna, kitchen hub, fire pits, paddleboards and all site amenities.", tags: ["facilities", "amenities", "sauna", "kitchen", "broad", "fire pit", "paddleboard", "infrastructure", "site"] },
  { title: "The Kitchen Hub", href: "kitchen-hub", cat: "The Site", desc: "A communal kitchen and gathering space — cook together, eat outside, shelter from the rain.", tags: ["kitchen", "food", "cook", "catering", "communal", "hub", "shelter", "gather"] },
  { title: "Family Escapes", href: "family-escape", cat: "Stays", desc: "A weekend escape for families — bell tents, wild swimming, fire pits and space for kids to roam.", tags: ["family", "children", "kids", "parents", "weekend", "escape", "glamping", "nature"] },
  { title: "Wellness Retreats", href: "retreats", cat: "Retreats", desc: "Yoga, breathwork, cold-water and women's circle retreats on a private broad in Norfolk.", tags: ["yoga", "breathwork", "retreat", "wellness", "cold water", "women", "circle", "meditation", "mindfulness", "host"] },
  { title: "Host a Retreat", href: "retreats#host", cat: "Retreats", desc: "Hire Wonderwild for your yoga, breathwork, cold-water or women's circle retreat.", tags: ["host", "hire", "retreat", "yoga", "breathwork", "teacher", "facilitator", "partner", "classes"] },
  { title: "Corporate Away-Days", href: "corporate", cat: "Corporate", desc: "Nature-led wellbeing days and team away-days two hours from London — sauna, swim, lunch and a campfire.", tags: ["corporate", "team", "away day", "offsite", "work", "business", "team building", "wellbeing", "leadership", "workshop"] },
  { title: "Groups & Events", href: "groups-%26-events", cat: "Groups", desc: "Book several tents together or hire the whole site for celebrations, reunions and private events.", tags: ["group", "event", "party", "celebration", "birthday", "wedding", "reunion", "hire", "exclusive", "venue"] },
  { title: "What's On", href: "whats-on", cat: "Events", desc: "Upcoming events, workshops, guided swims and special sessions at Wonderwild.", tags: ["events", "whats on", "calendar", "schedule", "workshop", "upcoming", "classes", "sessions"] },
  { title: "Pricing & Membership", href: "pricing", cat: "Pricing", desc: "Membership options, day session rates and what's included — plus exclusive member perks.", tags: ["membership", "price", "cost", "rates", "member", "annual", "monthly", "discount", "season pass", "how much"] },
  { title: "Editorial", href: "editorial", cat: "Stories", desc: "Stories, guides and seasonal writing from Wonderwild and the Norfolk Broads.", tags: ["editorial", "stories", "blog", "articles", "guides", "read", "writing", "journal"] },
  { title: "About & Our Story", href: "about", cat: "About", desc: "How Wonderwild came to be — the people, the place and the thinking behind it.", tags: ["about", "story", "who we are", "founders", "history", "mission", "values", "ethos"] },
  { title: "Contact & Location", href: "contact", cat: "Info", desc: "Get in touch, find us in the Norfolk Broads, and directions to the gate.", tags: ["contact", "location", "directions", "address", "find us", "get in touch", "map", "email", "phone", "enquiry"] },
  { title: "FAQs", href: "faqs", cat: "Info", desc: "Answers to common questions about staying, sessions, getting here and what to bring.", tags: ["faq", "questions", "help", "info", "what to bring", "arrive", "parking", "dogs", "children", "accessibility"] },
  { title: "Sauna Sessions", href: "wild-swim-sauna#sauna", cat: "Activities", desc: "Book a wood-fired sauna slot — heat, steam and a broad to cool off in.", tags: ["sauna", "wood fired", "heat", "steam", "book", "slot", "session", "contrast therapy"] },
  { title: "Paddleboarding", href: "activities#paddleboard", cat: "Activities", desc: "Hire a paddleboard and explore the private broad at your own pace.", tags: ["paddleboard", "sup", "paddle", "board", "hire", "water", "broad"] },
  { title: "Wild Swimming", href: "wild-swim-sauna#swim", cat: "Activities", desc: "Swim in a private broad — cold, clear and completely undisturbed.", tags: ["wild swimming", "swim", "cold water", "dip", "open water", "broad", "lake"] },
];

function searchIndex(query) {
  if (!query || query.trim().length < 2) return [];
  const q = query.toLowerCase().trim();
  const words = q.split(/\s+/);
  return SEARCH_INDEX
    .map(item => {
      const haystack = [item.title, item.cat, item.desc, ...(item.tags || [])].join(" ").toLowerCase();
      let score = 0;
      if (item.title.toLowerCase().includes(q)) score += 10;
      if (item.cat.toLowerCase().includes(q)) score += 4;
      words.forEach(w => {
        if (item.title.toLowerCase().includes(w)) score += 5;
        if (haystack.includes(w)) score += 1;
      });
      return { ...item, score };
    })
    .filter(item => item.score > 0)
    .sort((a, b) => b.score - a.score)
    .slice(0, 6);
}

/* ============ HEADER ============ */
function Header({ active, onBook, banner, navOnLight, navDark }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [navHovered, setNavHovered] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [expandedSection, setExpandedSection] = React.useState(null);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [searchQuery, setSearchQuery] = React.useState("");
  React.useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 10);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  React.useEffect(() => {
    if (!searchOpen) return;
    const bd = document.createElement('div');
    bd.style.cssText = 'position:fixed;inset:0;background:rgba(22,38,29,0.45);z-index:89;cursor:pointer;';
    bd.addEventListener('click', () => setSearchOpen(false));
    document.body.appendChild(bd);
    return () => { bd.remove(); };
  }, [searchOpen]);

  const onLight = navOnLight && !navDark && !scrolled && !navHovered && !searchOpen;
  const tc = onLight ? "var(--green-900)" : "rgba(248,241,233,0.93)";
  const sep = onLight ? "rgba(0,0,0,0.08)" : "rgba(255,255,255,0.12)";
  const eng = (sz = "0.68rem") => ({ fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.22em", fontSize: sz, color: tc });

  const NAV_SECTIONS = [
    { label: "Stay", items: [
      { label: "Bell Tent Stays", href: "stay", img: "assets/images/two-bell-tents.jpg" },
      { label: "Family Escape", href: "family-escape", img: "assets/images/Paddleboard-copy.jpg" },
    ]},
    { label: "Experiences", items: [
      { label: "Wild Swimming", href: "activities", img: "assets/images/woman-wild-swimming.jpg" },
      { label: "Sauna", href: "activities", img: "assets/images/person-inside-sauna.jpg", imgPos: "50% 30%" },
      { label: "Paddleboarding", href: "activities", img: "assets/images/woman-paddelboarding.webp" },
      { label: "Things to do Nearby", href: "things-to-do", img: "assets/images/woodbastwick-village-sign.jpg" },
    ]},
    { label: "Gather", items: [
      { label: "Wellness Retreats", href: "retreats", img: "assets/images/yoga-session.jpg" },
      { label: "Corporate Wellbeing", href: "corporate", img: "assets/images/corporate-wellbeing.jpg" },
      { label: "Groups & Events", href: "groups-%26-events", img: "assets/images/birds-eye-view-campsite.jpg" },
    ]},
  ];
  const NAV_SIMPLE = [
    { label: "Facilities", href: "facilities" },
    { label: "What's On", href: "whats-on" },
    { label: "Story", href: "about" },
    { label: "Pricing & Membership", href: "pricing" },
    { label: "FAQs", href: "faqs" },
    { label: "Contact & Location", href: "contact" },
  ];
  const CTAS = [
    { label: "Book", action: () => onBook("menu"), chevron: true },
    { label: "Become Member", href: "pricing" },
    { label: "Directions", href: "contact" },
  ];
  const ChevDown = () => (
    <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ marginLeft: "4px", opacity: 0.8 }}>
      <polyline points="6 9 12 15 18 9" />
    </svg>
  );
  const CalIcon = () => (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="4" width="18" height="18" rx="2" /><path d="M16 2v4M8 2v4M3 10h18" />
    </svg>
  );
  const SearchIcon = ({ color = "currentColor", size = 20 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="11" cy="11" r="8" /><path d="m21 21-4.35-4.35" />
    </svg>
  );
  const SEARCH_SUGGESTIONS = ["Bell tent stays", "Wild swimming", "Sauna session", "Paddleboard hire", "Wellness retreat", "What's on"];
  const searchResults = React.useMemo(() => searchIndex(searchQuery), [searchQuery]);

  return (
    <header style={{ position: "fixed", top: 0, left: 0, right: 0, zIndex: 90, background: navDark || scrolled || navHovered || searchOpen ? "var(--green-900)" : onLight ? "white" : "transparent", borderBottom: (navDark || scrolled || navHovered || searchOpen) ? "1px solid rgba(248,241,233,0.18)" : onLight ? "1px solid rgba(0,0,0,0.08)" : "none", transition: "background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out)" }}>
      {/* info banner */}
      {banner && (
        <div className="ww-top-banner" style={{ overflow: "hidden", maxHeight: scrolled ? "0" : "44px", opacity: scrolled ? 0 : 1, transition: "max-height var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out)", borderBottom: `1px solid ${sep}` }}>
          <div style={{ maxWidth: "1440px", margin: "0 auto", padding: "0 36px", display: "flex", alignItems: "center", justifyContent: "space-between", height: "44px" }}>
            {banner}
          </div>
        </div>
      )}

      {/* main bar — MENU left · Logo center · BOOK + Search right */}
      <div className="ww-nav-bar" onMouseEnter={() => setNavHovered(true)} onMouseLeave={() => setNavHovered(false)} style={{ position: "relative", zIndex: 2 }}>
      <div style={{ maxWidth: "1440px", margin: "0 auto", padding: "12px clamp(20px, 4vw, 64px)", display: "flex", alignItems: "center" }}>
        <div style={{ flex: 1, display: "flex", alignItems: "center" }}>
          <button onClick={() => setMenuOpen(true)} aria-label="Open menu"
            style={{ display: "inline-flex", alignItems: "center", gap: "10px", background: "none", border: "none", cursor: "pointer", padding: 0, ...eng("0.82rem") }}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18" /><path d="M3 12h18" /><path d="M3 18h18" /></svg><span className="ww-menu-label">Menu</span>
          </button>
        </div>
        <Logo variant={onLight ? "green" : "cream"} size={52} />
        <div style={{ flex: 1, display: "flex", justifyContent: "flex-end", alignItems: "center", gap: "20px" }}>
          <a className="ww-book-text" href="#" onClick={(e) => { e.preventDefault(); onBook("menu"); }}
            style={{ ...eng("0.82rem"), textDecoration: "none", whiteSpace: "nowrap", display: "inline-flex", alignItems: "center" }}
          >Book <ChevDown /></a>
          <button className="ww-book-icon" onClick={() => onBook("menu")} aria-label="Book"
            style={{ background: "none", border: "none", cursor: "pointer", padding: "4px", display: "none", alignItems: "center", justifyContent: "center", color: tc }}>
            <CalIcon />
          </button>
          <button className="ww-nav-search" onClick={() => setSearchOpen(true)} aria-label="Search"
            style={{ background: "none", border: "none", cursor: "pointer", padding: "4px", display: "inline-flex", alignItems: "center", justifyContent: "center", color: tc }}>
            <SearchIcon size={22} />
          </button>
        </div>
      </div>
      </div>

      {/* full-screen Naked-style overlay — all screen sizes */}
      {menuOpen && (
        <div style={{ position: "fixed", inset: 0, background: "var(--green-900)", zIndex: 130, display: "flex", flexDirection: "column", overflowY: "auto" }}>
          {/* overlay header — mirrors main nav layout */}
          <div style={{ flexShrink: 0 }}>
          <div style={{ maxWidth: "1440px", margin: "0 auto", padding: "12px clamp(20px, 4vw, 64px)", display: "flex", alignItems: "center" }}>
            <div style={{ flex: 1, display: "flex", alignItems: "center" }}>
              <button onClick={() => setMenuOpen(false)} aria-label="Close menu" style={{ display: "inline-flex", alignItems: "center", gap: "10px", background: "none", border: "none", cursor: "pointer", padding: 0, ...eng("0.82rem") }}>
                {Icons.close}<span className="ww-menu-label">Close</span>
              </button>
            </div>
            <Logo variant="cream" size={52} />
            <div style={{ flex: 1, display: "flex", justifyContent: "flex-end", alignItems: "center", gap: "20px" }}>
              <a className="ww-book-text" href="#" onClick={(e) => { e.preventDefault(); setMenuOpen(false); onBook("menu"); }}
                style={{ ...eng("0.82rem"), textDecoration: "none", whiteSpace: "nowrap", opacity: 0.85, transition: "opacity var(--dur-fast)", display: "inline-flex", alignItems: "center" }}
                onMouseEnter={(e) => e.currentTarget.style.opacity = "1"}
                onMouseLeave={(e) => e.currentTarget.style.opacity = "0.85"}
              >Book <ChevDown /></a>
              <button className="ww-book-icon" onClick={() => { setMenuOpen(false); onBook("menu"); }} aria-label="Book" style={{ background: "none", border: "none", cursor: "pointer", padding: "4px", display: "none", alignItems: "center", justifyContent: "center", color: tc }}>
                <CalIcon />
              </button>
              <button className="ww-nav-search" onClick={() => { setMenuOpen(false); setSearchOpen(true); }} aria-label="Search" style={{ background: "none", border: "none", cursor: "pointer", padding: "4px", display: "inline-flex", alignItems: "center", justifyContent: "center", color: tc, opacity: 0.85 }}>
                <SearchIcon size={22} />
              </button>
            </div>
          </div>
          </div>

          {/* accordion sections */}
          <div style={{ flex: 1, padding: "0 clamp(24px,5vw,64px)" }}>
          <div style={{ maxWidth: "780px", margin: "0 auto", width: "100%" }}>
            {NAV_SECTIONS.map((section) => {
              const open = expandedSection === section.label;
              const withImg = section.items.filter(i => i.img);
              const textOnly = section.items.filter(i => !i.img);
              return (
                <div key={section.label}>
                  {/* section heading row */}
                  <button onClick={() => setExpandedSection(open ? null : section.label)}
                    style={{ width: "100%", display: "flex", justifyContent: "space-between", alignItems: "center", padding: "clamp(8px,1.3vh,18px) 0", background: "none", border: "none", cursor: "pointer" }}>
                    <span style={{ fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "clamp(1.4rem,4vh,2.2rem)", color: tc, lineHeight: 1 }}>{section.label}</span>
                    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={tc} strokeWidth="1.2"
                      style={{ transition: "transform var(--dur-base)", transform: open ? "rotate(180deg)" : "none", flexShrink: 0, opacity: 0.7 }}>
                      <polyline points="6 9 12 15 18 9" />
                    </svg>
                  </button>

                  {/* expanded: image cards + text-only items */}
                  {open && (
                    <div style={{ paddingBottom: "clamp(24px,3vw,40px)" }}>
                      {withImg.length > 0 && (
                        <MenuCardScroll marginBottom={textOnly.length ? "16px" : 0}>
                          {withImg.map((item) => (
                            <a key={item.label} href={item.href} onClick={() => setMenuOpen(false)}
                              style={{ textDecoration: "none", display: "block", flex: "0 0 clamp(180px,29%,230px)", scrollSnapAlign: "start" }}
                              onMouseEnter={(e) => e.currentTarget.querySelector('img').style.transform = "scale(1.04)"}
                              onMouseLeave={(e) => e.currentTarget.querySelector('img').style.transform = "scale(1)"}>
                              <div style={{ aspectRatio: "4/3", overflow: "hidden", borderRadius: "var(--radius-sm)", marginBottom: "10px" }}>
                                <img src={item.img} alt={item.label}
                                  style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: item.imgPos || "center", transition: "transform 0.4s var(--ease-out)", display: "block" }} />
                              </div>
                              <span style={{ ...eng("0.68rem"), color: tc, opacity: 0.85 }}>{item.label}</span>
                            </a>
                          ))}
                        </MenuCardScroll>
                      )}
                      {textOnly.map((item) => (
                        <a key={item.label} href={item.href} onClick={() => setMenuOpen(false)}
                          style={{ display: "block", ...eng("0.78rem"), textDecoration: "none", padding: "8px 0", color: "rgba(248,241,233,0.55)", transition: "color var(--dur-fast)" }}
                          onMouseEnter={(e) => e.currentTarget.style.color = tc}
                          onMouseLeave={(e) => e.currentTarget.style.color = "rgba(248,241,233,0.55)"}>
                          {item.label}
                        </a>
                      ))}
                    </div>
                  )}
                </div>
              );
            })}

            {/* simple nav links */}
            <div style={{ padding: "clamp(8px,1.3vh,18px) 0 clamp(20px,3vh,40px)", display: "flex", flexDirection: "column" }}>
              {NAV_SIMPLE.map((item) => (
                <a key={item.label} href={item.href} onClick={() => setMenuOpen(false)}
                  style={{ fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "clamp(1.4rem,4vh,2.2rem)", color: tc, lineHeight: 1, textDecoration: "none", padding: "clamp(8px,1.3vh,18px) 0", display: "block", transition: "opacity var(--dur-fast)" }}
                  onMouseEnter={(e) => e.currentTarget.style.opacity = "0.5"}
                  onMouseLeave={(e) => e.currentTarget.style.opacity = "1"}
                >{item.label}</a>
              ))}
            </div>
          </div>{/* end centered box */}
          </div>
        </div>
      )}

      {/* Search dropdown — slides down below the nav bar; backdrop injected at body level via useEffect */}
      {searchOpen && (
        <div onClick={(e) => e.stopPropagation()} style={{ position: "absolute", top: "100%", left: 0, right: 0, background: "var(--green-900)", padding: "clamp(28px,4vw,44px) clamp(24px,6vw,80px) clamp(36px,5vw,56px)", boxShadow: "0 12px 40px rgba(0,0,0,0.3)", animation: "wwFade 0.25s ease both", zIndex: 1 }}>
          {/* input row */}
          <div style={{ display: "flex", alignItems: "center", gap: "16px", borderBottom: "1px solid rgba(248,241,233,0.2)", paddingBottom: "14px", marginBottom: "28px" }}>
            <SearchIcon color="rgba(248,241,233,0.65)" size={22} />
            <input autoFocus type="text" placeholder="Search — stays, sauna, wild swim, events…" value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Escape") { setSearchOpen(false); setSearchQuery(""); }
                if (e.key === "Enter" && searchResults.length > 0) { window.location.href = searchResults[0].href; }
              }}
              style={{ flex: 1, border: "none", outline: "none", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "clamp(1rem,2vw,1.4rem)", color: "var(--cream-100)", background: "transparent", caretColor: "var(--clay-300)" }} />
            <button onClick={() => { setSearchOpen(false); setSearchQuery(""); }} aria-label="Close search" style={{ background: "none", border: "none", cursor: "pointer", color: "rgba(248,241,233,0.55)", display: "flex", alignItems: "center" }}>
              {Icons.close}
            </button>
          </div>
          {/* results or suggestions */}
          {searchResults.length > 0 ? (
            <div style={{ display: "flex", flexDirection: "column", gap: "2px" }}>
              {searchResults.map((r, i) => (
                <a key={r.href + i} href={r.href}
                  style={{ display: "flex", alignItems: "baseline", gap: "14px", padding: "13px 12px", borderRadius: "var(--radius-sm)", textDecoration: "none", transition: "background var(--dur-fast)" }}
                  onMouseEnter={(e) => e.currentTarget.style.background = "rgba(248,241,233,0.07)"}
                  onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}>
                  <span style={{ fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.16em", fontSize: "0.58rem", color: "var(--clay-300)", whiteSpace: "nowrap", minWidth: "90px" }}>{r.cat}</span>
                  <div>
                    <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.08em", fontSize: "0.88rem", color: "var(--cream-100)", marginBottom: "3px" }}>{r.title}</div>
                    <div style={{ fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.82rem", color: "rgba(248,241,233,0.55)", lineHeight: 1.4 }}>{r.desc}</div>
                  </div>
                </a>
              ))}
            </div>
          ) : searchQuery.trim().length >= 2 ? (
            <p style={{ fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.95rem", color: "rgba(248,241,233,0.45)", margin: 0 }}>No results for "{searchQuery}" — try something else.</p>
          ) : (
            <div style={{ display: "flex", alignItems: "center", gap: "10px", flexWrap: "wrap" }}>
              <span style={{ fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.16em", fontSize: "0.62rem", color: "rgba(248,241,233,0.4)", marginRight: "4px" }}>Try</span>
              {SEARCH_SUGGESTIONS.map((s) => (
                <button key={s} onClick={() => setSearchQuery(s)}
                  style={{ background: "none", border: "1px solid rgba(248,241,233,0.2)", borderRadius: "var(--radius-pill)", padding: "7px 16px", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.88rem", color: "rgba(248,241,233,0.8)", cursor: "pointer", transition: "border-color var(--dur-fast), background var(--dur-fast)" }}
                  onMouseEnter={(e) => { e.currentTarget.style.borderColor = "rgba(248,241,233,0.6)"; e.currentTarget.style.background = "rgba(248,241,233,0.08)"; }}
                  onMouseLeave={(e) => { e.currentTarget.style.borderColor = "rgba(248,241,233,0.2)"; e.currentTarget.style.background = "none"; }}>
                  {s}
                </button>
              ))}
            </div>
          )}
        </div>
      )}
    </header>
  );
}

/* ============ FOOTER ============ */
function Footer() {
  const NAV_LINKS = [
    { label: "What's On", href: "whats-on" },
    { label: "Contact & Location", href: "contact" },
    { label: "FAQs", href: "faqs" },
  ];
  const BOTTOM_LINKS = [
    { label: "Legal", href: "legal" },
    { label: "Privacy", href: "privacy-policy" },
    { label: "Cookies", href: "cookies-policy" },
    { label: "Terms of Use", href: "terms-of-use" },
  ];
  const sep = "rgba(255,255,255,0.12)";
  const lbl = { fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.2em" };
  const ArrowDiag = () => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" style={{ flexShrink: 0, opacity: 0.5 }}>
      <path d="M7 17L17 7M17 7H7M17 7v10" />
    </svg>
  );
  return (
    <footer style={{ background: "var(--green-900)" }}>
      <div style={{ maxWidth: "1240px", margin: "0 auto", padding: "0 clamp(20px,5vw,44px)" }}>

        {/* Back to top row — eyebrow left, back-to-top right */}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: "clamp(28px,4vw,40px)", paddingBottom: "clamp(20px,3vw,32px)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: "14px" }}>
            <span style={{ ...lbl, fontSize: "0.62rem", color: "var(--clay-300)" }}>The Wonderwild Story</span>
            <div style={{ width: "40px", height: "1px", background: "rgba(198,160,120,0.4)" }} />
          </div>
          <button onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
            style={{ display: "flex", alignItems: "center", gap: "8px", background: "none", border: "none", cursor: "pointer", padding: 0 }}>
            <span style={{ ...lbl, fontSize: "0.6rem", color: "var(--green-400)" }}>Back to top</span>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--green-400)" strokeWidth="2"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
          </button>
        </div>

        {/* Two-column on desktop, stacked on mobile */}
        <div className="ww-footer-main" style={{ display: "flex", gap: "clamp(48px,8vw,100px)", alignItems: "flex-start", padding: "var(--space-7) 0 var(--space-8)", borderBottom: `1px solid ${sep}` }}>

          {/* Left: editorial + CTA */}
          <div style={{ flex: "1 1 0", minWidth: 0 }}>
            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.08em", fontSize: "clamp(2.2rem,5vw,4rem)", lineHeight: 1.0, color: "var(--cream-100)", margin: "0 0 clamp(16px,2vw,22px)" }}>Life at the<br />Water's Edge</h2>
            <p style={{ fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "clamp(0.9rem,1.2vw,1rem)", lineHeight: 1.65, color: "var(--green-200)", margin: "0 0 clamp(22px,2.5vw,32px)", maxWidth: "38ch" }}>Stories, seasons and slow moments from our corner of the Norfolk Broads.</p>
            <div style={{ display: "flex", alignItems: "center", gap: "24px", flexWrap: "wrap" }}>
              <a href="editorial"
                style={{ display: "inline-block", ...lbl, fontSize: "0.66rem", color: "var(--cream-100)", border: "1px solid rgba(248,241,233,0.35)", padding: "14px 26px", textDecoration: "none", transition: "border-color var(--dur-fast)", whiteSpace: "nowrap" }}
                onMouseEnter={(e) => e.currentTarget.style.borderColor = "rgba(248,241,233,0.9)"}
                onMouseLeave={(e) => e.currentTarget.style.borderColor = "rgba(248,241,233,0.35)"}>
                Read Our Stories
              </a>
              <div style={{ display: "flex", gap: "18px" }}>
                <a href="https://www.instagram.com/wewonderwild/" target="_blank" rel="noreferrer"
                  style={{ color: "var(--cream-100)", display: "inline-flex", transition: "color var(--dur-fast)" }}
                  onMouseEnter={(e) => e.currentTarget.style.color = "rgba(248,241,233,0.55)"}
                  onMouseLeave={(e) => e.currentTarget.style.color = "var(--cream-100)"}>
                  {Icons.instagram}
                </a>
                <a href="https://www.facebook.com/wewonderwild/" target="_blank" rel="noreferrer"
                  style={{ color: "var(--cream-100)", display: "inline-flex", transition: "color var(--dur-fast)" }}
                  onMouseEnter={(e) => e.currentTarget.style.color = "rgba(248,241,233,0.55)"}
                  onMouseLeave={(e) => e.currentTarget.style.color = "var(--cream-100)"}>
                  {Icons.facebook}
                </a>
              </div>
            </div>
          </div>

          {/* Right: nav links */}
          <div style={{ flex: "1 1 0", minWidth: 0, borderTop: `1px solid ${sep}` }}>
            {NAV_LINKS.map((link) => (
              <a key={link.label} href={link.href}
                style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "clamp(14px,1.8vw,22px) 0", borderBottom: `1px solid ${sep}`, textDecoration: "none", fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", fontSize: "clamp(1rem,1.6vw,1.4rem)", color: "var(--cream-100)", transition: "opacity var(--dur-fast)" }}
                onMouseEnter={(e) => e.currentTarget.style.opacity = "0.5"}
                onMouseLeave={(e) => e.currentTarget.style.opacity = "1"}>
                <span>{link.label}</span>
                <ArrowDiag />
              </a>
            ))}
          </div>

        </div>

        {/* Bottom bar */}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: "10px", padding: "18px 0 24px" }}>
          <div style={{ display: "flex", gap: "clamp(14px,2vw,28px)", flexWrap: "wrap" }}>
            {BOTTOM_LINKS.map(({ label, href }) => (
              <a key={label} href={href}
                onClick={href === "#" ? (e) => e.preventDefault() : undefined}
                style={{ ...lbl, fontSize: "0.66rem", color: "var(--cream-100)", textDecoration: "none", transition: "color var(--dur-fast)" }}
                onMouseEnter={(e) => e.currentTarget.style.color = "rgba(248,241,233,0.55)"}
                onMouseLeave={(e) => e.currentTarget.style.color = "var(--cream-100)"}>
                {label}
              </a>
            ))}
          </div>
          <span style={{ ...lbl, fontSize: "0.66rem", color: "var(--green-400)" }}>
            © Wonderwild 2026 · Woodbastwick Estate, Norfolk Broads
          </span>
        </div>

      </div>
    </footer>
  );
}

/* ============ BOOKING MODAL ============ */
const BOOK_OPTIONS = [
  { key: "stay",       icon: "tent",     label: "Bell Tent Stay",           price: "From £130 / night",  href: "https://wonderwild.sb.anytimebooking.eu/checkout/#forward", external: true },
  { key: "swim",       icon: "swim",     label: "Wild Swim Session",        price: "From £10 per person", href: "https://app.acuityscheduling.com/schedule.php?owner=38782571&appointmentType=97910548", external: true },
  { key: "sauna",      icon: "sauna",    label: "Sauna Session",            price: "From £18 per person", href: "https://app.acuityscheduling.com/schedule.php?owner=38782571&appointmentType=97910534", external: true },
  { key: "paddle1",    icon: "paddle",   label: "Paddleboard Hire — 1 hr",  price: "From £15 per board",  href: "https://app.acuityscheduling.com/schedule.php?owner=38782571&appointmentType=97910571", external: true },
  { key: "paddle2",    icon: "paddle",   label: "Paddleboard Hire — 2 hrs", price: "From £25 per board",  href: "https://app.acuityscheduling.com/schedule.php?owner=38782571&appointmentType=97910579", external: true },
  { key: "membership", icon: "lotus",    label: "Become a Member",          price: "From £18 / month",    href: "https://app.acuityscheduling.com/schedule/daf19911", external: true },
  { key: "retreat",    icon: "wellness", label: "Retreat or Private Hire",  price: "Enquire for rates",  href: "contact#get-in-touch", external: false },
];

function BookingModal({ intent, onClose }) {
  const open = intent !== null && intent !== undefined;
  const [rendered, setRendered] = React.useState(false);
  const [visible, setVisible] = React.useState(false);

  React.useEffect(() => {
    if (open) {
      setRendered(true);
      requestAnimationFrame(() => requestAnimationFrame(() => setVisible(true)));
    } else {
      setVisible(false);
      const t = setTimeout(() => setRendered(false), 380);
      return () => clearTimeout(t);
    }
  }, [open]);

  if (!rendered) return null;

  const panelW = "min(480px, 100vw)";
  const title = { fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", fontSize: "1.3rem", color: "var(--text-strong)", margin: "0 0 22px" };

  return (
    <>
      {/* Backdrop */}
      <div onClick={onClose}
        style={{ position: "fixed", inset: 0, zIndex: 200, background: "rgba(22,38,29,0.45)", backdropFilter: "blur(2px)", opacity: visible ? 1 : 0, transition: "opacity 0.35s ease" }} />
      {/* Slide-in panel */}
      <div style={{ position: "fixed", top: 0, right: 0, bottom: 0, width: panelW, zIndex: 201, background: "var(--green-900)", boxShadow: "-8px 0 48px rgba(0,0,0,0.3)", display: "flex", flexDirection: "column", transform: visible ? "translateX(0)" : "translateX(100%)", transition: "transform 0.38s cubic-bezier(0.4,0,0.2,1)" }}>
        {/* Panel header */}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "22px 28px", borderBottom: "1px solid rgba(248,241,233,0.12)", flexShrink: 0 }}>
          <Eyebrow color="on-ink">Book now</Eyebrow>
          <button onClick={onClose} aria-label="Close" style={{ background: "none", border: "none", color: "rgba(248,241,233,0.55)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>{Icons.close}</button>
        </div>
        {/* Panel body — rows */}
        <div style={{ flex: 1, overflowY: "auto" }}>
          {BOOK_OPTIONS.map((x) => (
            <a key={x.key} href={x.href} target={x.external ? "_blank" : "_self"} rel={x.external ? "noopener noreferrer" : undefined}
              onClick={onClose}
              style={{ display: "flex", alignItems: "center", gap: "18px", padding: "20px 28px", borderBottom: "1px solid rgba(248,241,233,0.1)", textDecoration: "none", transition: "background var(--dur-fast)" }}
              onMouseEnter={(e) => e.currentTarget.style.background = "rgba(248,241,233,0.06)"}
              onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}>
              <div style={{ width: "36px", height: "36px", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }}>
                <img src={WW.ICON + x.icon + "-cream.png"} alt="" style={{ width: "36px", height: "36px", objectFit: "contain", opacity: 0.65, display: "block" }} />
              </div>
              <span style={{ flex: 1 }}>
                <span style={{ display: "block", fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", fontSize: "0.82rem", color: "var(--cream-100)" }}>{x.label}</span>
                {x.price && <span style={{ display: "block", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.78rem", color: "rgba(248,241,233,0.5)", marginTop: "3px" }}>{x.price}</span>}
              </span>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="rgba(248,241,233,0.45)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="m9 6 6 6-6 6" /></svg>
            </a>
          ))}
        </div>
        {/* Phone footer */}
        <a href="tel:01603397578"
          style={{ display: "flex", alignItems: "center", gap: "14px", padding: "20px 28px", borderTop: "1px solid rgba(248,241,233,0.12)", textDecoration: "none", flexShrink: 0, transition: "background var(--dur-fast)" }}
          onMouseEnter={(e) => e.currentTarget.style.background = "rgba(248,241,233,0.06)"}
          onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}>
          <div style={{ width: "36px", height: "36px", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center", background: "rgba(248,241,233,0.08)", borderRadius: "50%" }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="rgba(248,241,233,0.7)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
              <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.27h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.91a16 16 0 0 0 6 6l.91-.91a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7a2 2 0 0 1 1.72 2.02z" />
            </svg>
          </div>
          <span style={{ flex: 1 }}>
            <span style={{ display: "block", fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", fontSize: "0.82rem", color: "var(--cream-100)" }}>Call Us</span>
            <span style={{ display: "block", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.78rem", color: "rgba(248,241,233,0.5)", marginTop: "3px" }}>01603 397578</span>
          </span>
        </a>
      </div>
    </>
  );
}

/* ============ PAGE WRAPPER ============ */
function Page({ active, children, topBanner, navOnLight, navDark }) {
  const [intent, setIntent] = React.useState(null);
  const openBooking = (i = "menu") => setIntent(i);
  return (
    <BookingContext.Provider value={openBooking}>
      <Header active={active} onBook={openBooking} banner={topBanner} navOnLight={navOnLight} navDark={navDark} />
      {children}
      <NewsletterSignup />
      <Footer />
      <BookingModal intent={intent} onClose={() => setIntent(null)} />
    </BookingContext.Provider>
  );
}

/* ============ NEWSLETTER SIGNUP ============ */
function NewsletterSignup() {
  const [form, setForm] = React.useState({ first: "", last: "", email: "" });
  const [submitted, setSubmitted] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const [error, setError] = React.useState("");

  const lbl = { fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.16em", fontSize: "0.65rem", color: "var(--green-800)", display: "block", marginBottom: "8px" };
  const inp = { width: "100%", border: "1px solid var(--cream-300)", borderRadius: "var(--radius-sm)", padding: "13px 15px", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "0.95rem", color: "var(--text-body)", background: "white", outline: "none", boxSizing: "border-box", transition: "border-color var(--dur-fast)" };

  return (
    <section style={{ background: "white", padding: "64px 36px" }}>
      <div style={{ maxWidth: "1060px", margin: "0 auto", border: "1px solid var(--cream-300)", borderRadius: "var(--radius-lg)", padding: "clamp(40px, 6vw, 72px) clamp(28px, 6vw, 64px) clamp(36px, 5vw, 56px)", background: "white", boxShadow: "var(--shadow-sm)" }}>
        {submitted ? (
          <div style={{ textAlign: "center", padding: "32px 0" }}>
            <p style={{ ...lbl, color: "var(--green-700)", marginBottom: "18px" }}>Thank you</p>
            <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", fontSize: "clamp(1.6rem, 3vw, 2.2rem)", color: "var(--green-900)", margin: "0 0 16px" }}>You're in the wild loop.</h2>
            <p style={{ font: "var(--serif-md)", color: "var(--text-body)" }}>We'll be in touch with news, offers and updates from Wonderwild.</p>
          </div>
        ) : (
          <>
            <div style={{ textAlign: "center", marginBottom: "44px" }}>
              <p style={{ ...lbl, color: "var(--green-700)", marginBottom: "14px" }}>Stay in the loop</p>
              <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", fontSize: "clamp(1.8rem, 3.2vw, 2.8rem)", color: "var(--green-900)", margin: "0 0 16px", lineHeight: 1.1 }}>Subscribe to Wonderwild</h2>
              <p style={{ font: "var(--serif-md)", color: "var(--text-body)", maxWidth: "54ch", margin: "0 auto" }}>Be the first to hear about new dates, special offers and wild events in the Norfolk Broads.</p>
            </div>
            <form onSubmit={(e) => {
                e.preventDefault();
                if (!form.email || sending) return;
                setSending(true);
                setError("");
                const cb = "_mc_" + Date.now();
                const url = "https://wewonderwild.us15.list-manage.com/subscribe/post-json?u=9d1e1dc02c0d90001c7bb0d84&id=7825efe407&f_id=009c90e1f0"
                  + "&EMAIL=" + encodeURIComponent(form.email)
                  + "&FNAME=" + encodeURIComponent(form.first)
                  + "&LNAME=" + encodeURIComponent(form.last)
                  + "&b_9d1e1dc02c0d90001c7bb0d84_7825efe407="
                  + "&c=" + cb;
                window[cb] = (data) => {
                  delete window[cb];
                  setSending(false);
                  if (data.result === "success") {
                    setSubmitted(true);
                  } else {
                    setError((data.msg || "Something went wrong. Please try again.").replace(/<[^>]+>/g, ""));
                  }
                };
                const s = document.createElement("script");
                s.src = url;
                s.onerror = () => { delete window[cb]; setSending(false); setError("Something went wrong. Please try again."); s.remove(); };
                s.onload = () => s.remove();
                document.body.appendChild(s);
              }}>
              <div className="ww-nl-row" style={{ display: "flex", gap: "14px", alignItems: "flex-end", flexWrap: "wrap" }}>
                <div style={{ flex: 1, minWidth: "180px" }}>
                  <label style={lbl}>First Name</label>
                  <input type="text" placeholder="First Name" value={form.first} onChange={(e) => setForm(f => ({ ...f, first: e.target.value }))} style={inp}
                    onFocus={(e) => e.target.style.borderColor = "var(--green-600)"} onBlur={(e) => e.target.style.borderColor = "var(--cream-300)"} />
                </div>
                <div style={{ flex: 1, minWidth: "180px" }}>
                  <label style={lbl}>Last Name</label>
                  <input type="text" placeholder="Last Name" value={form.last} onChange={(e) => setForm(f => ({ ...f, last: e.target.value }))} style={inp}
                    onFocus={(e) => e.target.style.borderColor = "var(--green-600)"} onBlur={(e) => e.target.style.borderColor = "var(--cream-300)"} />
                </div>
                <div style={{ flex: "1.4", minWidth: "220px" }}>
                  <label style={lbl}>Email Address</label>
                  <input type="email" placeholder="Email Address" value={form.email} onChange={(e) => setForm(f => ({ ...f, email: e.target.value }))} required style={inp}
                    onFocus={(e) => e.target.style.borderColor = "var(--green-600)"} onBlur={(e) => e.target.style.borderColor = "var(--cream-300)"} />
                </div>
                <button type="submit" disabled={sending} style={{ fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.18em", fontSize: "0.72rem", background: "var(--green-800)", color: "var(--cream-100)", border: "none", borderRadius: "var(--radius-sm)", padding: "14px 28px", cursor: sending ? "default" : "pointer", whiteSpace: "nowrap", alignSelf: "flex-end", transition: "background var(--dur-fast)", height: "48px", opacity: sending ? 0.65 : 1 }}
                  onMouseEnter={(e) => { if (!sending) e.currentTarget.style.background = "var(--green-900)"; }}
                  onMouseLeave={(e) => e.currentTarget.style.background = "var(--green-800)"}>
                  {sending ? "Signing up…" : "Sign Up"}
                </button>
              </div>
              {error && <p style={{ fontSize: "0.72rem", color: "var(--signal-error)", marginTop: "14px", lineHeight: 1.65 }}>{error}</p>}
              <p style={{ fontSize: "0.72rem", color: "var(--text-muted)", marginTop: "18px", lineHeight: 1.65 }}>
                By clicking 'sign up' you are accepting the terms of Wonderwild's{" "}
                <a href="privacy-policy" style={{ color: "inherit", textDecoration: "underline" }}>privacy notice</a>.
              </p>
            </form>
          </>
        )}
      </div>
    </section>
  );
}

function PolicyTOC({ items }) {
  const [activeId, setActiveId] = React.useState(items[0]?.id || "");
  const [hoveredId, setHoveredId] = React.useState("");
  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    if (!items.length) return;
    const onScroll = () => {
      const offset = 150;
      let current = items[0].id;
      for (const { id } of items) {
        const el = document.getElementById(id);
        if (el && el.getBoundingClientRect().top <= offset) current = id;
      }
      setActiveId(current);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const linkEl = (t) => {
    const isActive = t.id === activeId;
    const isHovered = t.id === hoveredId;
    return (
      <a key={t.id} href={"#" + t.id}
        onMouseEnter={() => setHoveredId(t.id)}
        onMouseLeave={() => setHoveredId("")}
        onClick={() => setOpen(false)}
        style={{
          display: "block", padding: "9px 14px", textDecoration: "none",
          fontFamily: "var(--font-serif)", fontSize: "0.88rem", lineHeight: 1.4,
          fontWeight: isActive ? 500 : 400,
          color: isActive ? "var(--text-strong)" : "var(--text-body)",
          background: isActive ? "var(--cream-200)" : isHovered ? "var(--cream-100)" : "transparent",
          borderBottom: "1px solid var(--cream-200)",
          borderLeft: `3px solid ${isActive ? "var(--clay-400)" : "transparent"}`,
          transition: "background 0.12s, color 0.12s",
        }}
      >{t.label}</a>
    );
  };

  return (
    <>
      <div className="ww-toc-sidebar" style={{ width: "220px", flexShrink: 0, position: "sticky", top: "90px", alignSelf: "flex-start" }}>
        <p style={{ fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.16em", fontSize: "0.6rem", color: "var(--text-muted)", margin: "0 0 10px", paddingBottom: "10px", borderBottom: "1px solid var(--cream-300)" }}>Table of Contents</p>
        <div style={{ border: "1px solid var(--cream-200)", borderRadius: "var(--radius-sm)", overflow: "hidden" }}>
          {items.map(linkEl)}
        </div>
      </div>
      <div className="ww-toc-accordion">
        <button
          onClick={() => setOpen(v => !v)}
          style={{
            display: "flex", alignItems: "center", justifyContent: "space-between",
            width: "100%", padding: "14px 18px", cursor: "pointer",
            background: "var(--cream-50)", border: "1px solid var(--cream-300)",
            borderBottom: open ? "none" : "1px solid var(--cream-300)",
            borderRadius: open ? "var(--radius-md) var(--radius-md) 0 0" : "var(--radius-md)",
            fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase",
            letterSpacing: "0.14em", fontSize: "0.65rem", color: "var(--text-muted)",
          }}
        >
          <span>On This Page</span>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"
            style={{ transition: "transform 0.2s", transform: open ? "rotate(180deg)" : "none", flexShrink: 0 }}>
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </button>
        {open && (
          <div style={{ border: "1px solid var(--cream-300)", borderTop: "none", borderRadius: "0 0 var(--radius-md) var(--radius-md)", overflow: "hidden", background: "white" }}>
            {items.map(linkEl)}
          </div>
        )}
      </div>
    </>
  );
}

function PolicySubNav({ active }) {
  const links = [
    { label: "Legal", href: "legal", key: "legal" },
    { label: "Terms & Conditions", href: "terms-and-conditions", key: "terms" },
    { label: "Privacy", href: "privacy-policy", key: "privacy" },
    { label: "Cookies", href: "cookies-policy", key: "cookies" },
    { label: "Terms of Use", href: "terms-of-use", key: "use" },
  ];
  return (
    <div style={{ background: "var(--green-900)", borderBottom: "1px solid rgba(255,255,255,0.1)" }}>
      <div style={{ maxWidth: "1240px", margin: "0 auto", padding: "0 clamp(20px,5vw,44px)", display: "flex", alignItems: "center", overflowX: "auto" }}>
        {links.map((l, i) => (
          <React.Fragment key={l.key}>
            {i > 0 && <span style={{ color: "rgba(248,241,233,0.18)", padding: "0 2px", fontSize: "0.7rem" }}>|</span>}
            <a href={l.href === "#" ? undefined : l.href}
              onClick={l.href === "#" ? e => e.preventDefault() : undefined}
              style={{ fontFamily: "var(--font-label)", fontWeight: l.key === active ? 700 : 400, textTransform: "uppercase", letterSpacing: "0.14em", fontSize: "0.63rem", color: l.key === active ? "var(--cream-50)" : "rgba(248,241,233,0.5)", textDecoration: "none", padding: "13px 14px", whiteSpace: "nowrap", display: "block", borderBottom: l.key === active ? "2px solid var(--clay-400)" : "2px solid transparent", transition: "color 0.15s" }}>
              {l.label}
            </a>
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { BookingContext, useBook, Header, Footer, BookingModal, NewsletterSignup, Page, PolicySubNav, PolicyTOC });
