const { Card, Tile, Badge, Divider, Button, Input } = window.TheMahjClubsDesignSystem_b7bc49;

// Each chapter maps to its own GHL booking group. Add new clubs here as they launch.
const CLUBS = [
  { id: "scottsdale", label: "Scottsdale · Old Town", group: "bucBVoKduVYnQRsBtnMR" },
  { id: "phoenix", label: "More locations coming soon", group: "" },
];

// Branded date-grouped schedule fed by /api/events (GHL feed; sample mode
// until the GHL token is configured). Booking still happens on GHL pages.
// Branded on-site booking: GHL's booking widget (date/time + form + payment)
// opens in a modal instead of navigating away. Bookings land in GHL as before.
function BookingModal({ url, name, onClose }) {
  React.useEffect(() => {
    const esc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", esc);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", esc); document.body.style.overflow = prev; };
  }, []);
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(30,10,14,.6)", display: "flex", alignItems: "center", justifyContent: "center", padding: 18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--tmc-cream)", borderRadius: "var(--radius-md)", position: "relative", width: "min(1020px, 100%)", maxHeight: "94vh", display: "flex", flexDirection: "column", overflow: "hidden", boxShadow: "0 30px 80px rgba(0,0,0,.4)", animation: "tmc-modal-pop .28s var(--ease-out)" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 10, right: 12, zIndex: 2, background: "var(--tmc-cream)", border: "1px solid var(--tmc-burgundy)", borderRadius: "50%", width: 34, height: 34, fontSize: 20, lineHeight: 1, cursor: "pointer", color: "var(--tmc-burgundy)", boxShadow: "0 2px 8px rgba(30,10,14,.18)" }}>×</button>
        <iframe src={url} title={"Book " + name} allow="payment *" style={{ border: "none", width: "100%", height: "min(80vh, 820px)", display: "block", background: "#FFFFFF" }} />
        <div style={{ textAlign: "center", fontSize: 12, color: "var(--tmc-olive)", padding: "8px 0 10px", flexShrink: 0 }}>
          Seating is limited — cancellations within 7 days are non-refundable (credit available with prior notice). Trouble booking? <a href={url} target="_blank" rel="noreferrer" style={{ color: "var(--tmc-raspberry)" }}>Open in a new tab</a>
        </div>
      </div>
    </div>, document.body);
}

function WaitlistModal({ event, when, onClose }) {
  const [f, setF] = React.useState({ name: "", email: "", phone: "", seats: "1" });
  const [state, setState] = React.useState("form"); // form | sending | done | error
  React.useEffect(() => {
    const esc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", esc);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", esc); document.body.style.overflow = prev; };
  }, []);
  const submit = async ev => {
    ev.preventDefault();
    if (!f.name.trim() || !/.+@.+\..+/.test(f.email)) return;
    setState("sending");
    try {
      const r = await fetch("/api/contact", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: f.name, email: f.email, phone: f.phone, source: "waitlist",
          message: "WAITLIST REQUEST — " + event + " (" + when + ") — seats needed: " + f.seats }),
      });
      const j = await r.json();
      setState(j && j.ok ? "done" : "error");
    } catch (e) { setState("error"); }
  };
  const inp = { fontFamily: "var(--font-body)", fontSize: 15, padding: "11px 13px", border: "1px solid var(--tmc-burgundy)", borderRadius: "var(--radius-sm)", background: "#FFFFFF", color: "var(--tmc-burgundy)", width: "100%", boxSizing: "border-box" };
  const lbl = { ...tmcEyebrow, fontSize: 9, color: "var(--tmc-olive)", display: "block", margin: "14px 0 6px" };
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(30,10,14,.6)", display: "flex", alignItems: "center", justifyContent: "center", padding: 18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--tmc-cream)", borderRadius: "var(--radius-md)", position: "relative", width: "min(440px, 100%)", maxHeight: "94vh", overflowY: "auto", padding: "34px 30px 30px", boxShadow: "0 30px 80px rgba(0,0,0,.4)", animation: "tmc-modal-pop .28s var(--ease-out)" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 10, right: 12, background: "transparent", border: "none", fontSize: 22, cursor: "pointer", color: "var(--tmc-burgundy)" }}>×</button>
        {state === "done" ? (
          <div style={{ textAlign: "center", padding: "26px 0 14px" }}>
            <div style={{ ...tmcDisplay, fontSize: 28, color: "var(--tmc-emerald)" }}>You're on the list!</div>
            <p style={{ fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6, color: "var(--text-body)", margin: "12px 0 0" }}>If a seat opens for {event}, we'll reach out right away.</p>
            <button onClick={onClose} style={{ marginTop: 22, fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase", padding: "11px 26px", border: "none", borderRadius: "var(--radius-sm)", background: "var(--tmc-emerald)", color: "var(--tmc-cream)", cursor: "pointer" }}>Done</button>
          </div>
        ) : (
          <form onSubmit={submit}>
            <div style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Join the waitlist</div>
            <div style={{ ...tmcDisplay, fontSize: 24, color: "var(--tmc-burgundy)", margin: "8px 0 2px" }}>{event}</div>
            <div style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--tmc-olive)" }}>{when}</div>
            <label style={lbl}>Name *</label>
            <input style={inp} value={f.name} onChange={e => setF({ ...f, name: e.target.value })} autoFocus />
            <label style={lbl}>Email *</label>
            <input style={inp} type="email" value={f.email} onChange={e => setF({ ...f, email: e.target.value })} />
            <label style={lbl}>Phone</label>
            <input style={inp} type="tel" value={f.phone} onChange={e => setF({ ...f, phone: e.target.value })} />
            <label style={lbl}>Seats needed</label>
            <select style={inp} value={f.seats} onChange={e => setF({ ...f, seats: e.target.value })}>
              {["1","2","3","4"].map(n => <option key={n} value={n}>{n}</option>)}
            </select>
            {state === "error" && <p style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--tmc-raspberry)", margin: "12px 0 0" }}>Something hiccuped — please try again, or email <a href="mailto:hello@themahjclubs.com" style={{ color: "var(--tmc-raspberry)" }}>hello@themahjclubs.com</a>.</p>}
            <button type="submit" disabled={state === "sending"} style={{ marginTop: 20, width: "100%", fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".08em", textTransform: "uppercase", padding: "13px 0", border: "none", borderRadius: "var(--radius-sm)", background: "var(--tmc-raspberry)", color: "var(--tmc-cream)", cursor: "pointer", opacity: state === "sending" ? .6 : 1 }}>
              {state === "sending" ? "Adding you…" : "Add me to the waitlist"}
            </button>
          </form>
        )}
      </div>
    </div>, document.body);
}

function ScheduleView({ groupUrl, onFail, clubRow, lockCats }) {
  const [data, setData] = React.useState(null);
  const [failed, setFailed] = React.useState(false);
  const [filters, setFilters] = React.useState([]);
  const [q, setQ] = React.useState("");
  const [open, setOpen] = React.useState(false);
  const [booking, setBooking] = React.useState(null);
  const [bundle, setBundle] = React.useState(null);
  const [waitlist, setWaitlist] = React.useState(null);
  const ddRef = React.useRef(null);
  React.useEffect(() => {
    const cacheKey = "tmc-events-v1";
    let cached = null;
    try {
      cached = JSON.parse(sessionStorage.getItem(cacheKey) || "null");
      if (cached && cached.days) setData(cached);
    } catch (e) { /* ignore unusable browser cache */ }
    fetch("/api/events").then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
      .then(j => {
        setData(j);
        try { sessionStorage.setItem(cacheKey, JSON.stringify(j)); } catch (e) { /* storage unavailable */ }
      })
      .catch(() => {
        if (!cached) {
          setFailed(true);
          onFail && onFail();
        }
      });
  }, []);
  React.useEffect(() => {
    const close = e => { if (ddRef.current && !ddRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);
  const fmt = t => { const p = t.split(":"); const H = +p[0]; return (((H + 11) % 12) + 1) + ":" + p[1] + (H >= 12 ? " PM" : " AM"); };
  const dayLabel = iso => { const d = new Date(iso + "T12:00:00"); return { wd: d.toLocaleDateString("en-US", { weekday: "long" }), md: d.toLocaleDateString("en-US", { month: "short", day: "numeric" }) }; };
  // Four fixed event-type filters (client direction, Sep 2026). Events are
  // keyword-mapped; anything unmatched lands in Special Events.
  const CATS = ["Beginner", "Skills", "Play", "Special Events"];
  const catOf = (name, override) => {
    if (override) return override;
    const n = name.toLowerCase();
    if (n.includes("beginner")) return "Beginner";
    if (n.includes("102") || n.includes("strategies") || n.includes("guided") || n.includes("clinic") || n.includes("skills")) return "Skills";
    if (n.includes("drop-in") || n.includes("drop in") || n.includes("open play") || n.includes("social") || n.includes("trinket") || n.includes("canasta")) return "Play";
    return "Special Events";
  };
  const names = CATS;
  const toggle = n => setFilters(f => f.includes(n) ? f.filter(x => x !== n) : [...f, n]);
  const needle = q.trim().toLowerCase();
  const days = data ? data.days.map(d => ({ ...d, events: d.events.filter(e => (!lockCats || lockCats.includes(catOf(e.name, e.cat))) && (!filters.length || filters.includes(catOf(e.name, e.cat))) && (!needle || (e.name + " " + (e.desc || "")).toLowerCase().includes(needle))) })).filter(d => d.events.length) : [];
  // Same field style as the club <select> so the pair reads as one control set.
  const fieldStyle = { fontFamily: "var(--font-body)", fontSize: 15, color: "var(--text-body)", background: "#FFFFFF", border: "1px solid var(--tmc-olive)", borderRadius: "var(--radius-sm)", padding: "11px 40px 11px 16px", cursor: "pointer", appearance: "none", backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%235B6A4C' stroke-width='1.5'/></svg>\")", backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center" };
  return (
    <div style={{ maxWidth: 880, margin: "0 auto" }}>
      {!lockCats && <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: "14px 30px", flexWrap: "wrap", marginBottom: 26 }}>
        {clubRow}
        <input
          type="search"
          value={q}
          onChange={e => setQ(e.target.value)}
          placeholder="Search events…"
          aria-label="Search events"
          style={{ ...fieldStyle, cursor: "text", appearance: "none", backgroundImage: "none", padding: "11px 16px", width: 190 }}
        />

        <div ref={ddRef} style={{ display: "flex", alignItems: "center", gap: 12, position: "relative" }}>
          <label style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Choose your event type</label>
          <button onClick={() => setOpen(o => !o)} aria-expanded={open} style={fieldStyle}>
            {filters.length ? filters.length + " selected" : "All"}
          </button>
          {open && (
            <div style={{ position: "absolute", top: "calc(100% + 8px)", right: 0, zIndex: 30, background: "#FFFFFF", border: "1px solid var(--tmc-olive)", borderRadius: "var(--radius-sm)", boxShadow: "var(--shadow-lift)", padding: "8px 0", minWidth: 300, maxHeight: 320, overflowY: "auto", textAlign: "left" }}>
              <button onClick={() => setFilters([])} style={{ display: "block", width: "100%", textAlign: "left", background: "none", border: "none", cursor: "pointer", padding: "9px 16px", fontFamily: "var(--font-body)", fontSize: 13, color: filters.length ? "var(--tmc-raspberry)" : "var(--tmc-olive)" }}>
                {filters.length ? "Clear — show all events" : "Showing all events"}
              </button>
              {names.map(n => (
                <label key={n} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 16px", cursor: "pointer", fontFamily: "var(--font-body)", fontSize: 13, color: "var(--text-body)" }}>
                  <input type="checkbox" checked={filters.includes(n)} onChange={() => toggle(n)} style={{ accentColor: "var(--tmc-raspberry)", width: 15, height: 15, flexShrink: 0 }} />
                  {n}
                </label>
              ))}
            </div>
          )}
        </div>
      </div>}
      {failed && <div style={{ textAlign: "center", padding: "10px 0 4px", fontSize: 13, color: "var(--tmc-olive)" }}>The live schedule couldn't load — book through the full calendar below.</div>}
      {!failed && !data && <div style={{ textAlign: "center", padding: "44px 0", fontSize: 13, color: "var(--tmc-olive)" }}>Setting the table…</div>}
      {data && !data.configured && <div style={{ ...tmcEyebrow, fontSize: 8, textAlign: "center", color: "var(--tmc-olive)", marginBottom: 18 }}>sample schedule · connects to live bookings once the GHL feed is linked</div>}
      {data && !days.length && (needle || filters.length > 0) && (
        <div style={{ textAlign: "center", padding: "40px 0", fontSize: 14.5, color: "var(--tmc-olive)" }}>
          Nothing on the calendar matches{needle ? <> “<b>{q.trim()}</b>”</> : " those filters"} — <button onClick={() => { setQ(""); setFilters([]); }} style={{ background: "none", border: "none", padding: 0, cursor: "pointer", fontFamily: "var(--font-body)", fontSize: 14.5, color: "var(--tmc-raspberry)", textDecoration: "underline" }}>show everything</button>
        </div>
      )}
      {data && days.map(d => { const L = dayLabel(d.date); return (
        <div key={d.date} style={{ display: "grid", gridTemplateColumns: "150px minmax(0,1fr)", gap: 26, padding: "24px 0", borderTop: "var(--rule)" }}>
          <div>
            <div style={{ ...tmcEyebrow, fontSize: 9, color: "var(--tmc-raspberry)" }}>{L.wd}</div>
            <div style={{ ...tmcDisplay, fontSize: 30, color: "var(--text-display)", marginTop: 4 }}>{L.md}</div>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
            {d.events.map(e => (
              <div key={e.id + d.date}>
                <div style={{ ...tmcDisplay, fontSize: 21, color: "var(--tmc-burgundy)" }}>{e.name}</div>
                {e.desc && <p style={{ fontSize: 15.5, lineHeight: 1.55, margin: "5px 0 0", maxWidth: 560, color: "var(--text-body)" }}>{e.desc}</p>}
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 9, alignItems: "center" }}>
                  {e.soldOut && (
                    <>
                      <span style={{ fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".1em", textTransform: "uppercase", padding: "7px 16px", borderRadius: "var(--radius-sm)", background: "var(--tmc-raspberry)", color: "var(--tmc-cream)" }}>Sold out</span>
                      <button onClick={() => setWaitlist({ event: e.name, when: L.wd + " " + L.md })}
                        style={{ fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".06em", textTransform: "uppercase", padding: "7px 14px", border: "1px solid var(--tmc-emerald)", borderRadius: "var(--radius-sm)", color: "var(--tmc-emerald)", background: "transparent", cursor: "pointer" }}>
                        Join the waitlist →
                      </button>
                    </>
                  )}
                  {!e.soldOut && e.slots.slice(0, 6).map(sl => e.url ? (
                    <button key={sl} onClick={() => window.open(e.url, "_blank", "noopener,noreferrer")}
                      style={{ fontFamily: "var(--font-body)", fontSize: 12, padding: "7px 14px", border: "1px solid var(--tmc-raspberry)", borderRadius: "var(--radius-sm)", color: "var(--tmc-raspberry)", background: "transparent", cursor: "pointer" }}>{fmt(sl)}</button>
                  ) : (
                    <span key={sl} title="Booking opens when the GHL calendars are connected"
                      style={{ fontFamily: "var(--font-body)", fontSize: 12, padding: "7px 14px", border: "1px solid var(--tmc-raspberry)", borderRadius: "var(--radius-sm)", color: "var(--tmc-raspberry)", cursor: "default" }}>{fmt(sl)}</span>
                  ))}
                  {!e.soldOut && e.slots.length > 6 && (e.url
                    ? <button onClick={() => window.open(e.url, "_blank", "noopener,noreferrer")} style={{ fontSize: 14, color: "var(--tmc-olive)", background: "none", border: "none", cursor: "pointer", fontFamily: "var(--font-body)", padding: 0 }}>+{e.slots.length - 6} more →</button>
                    : <span style={{ fontSize: 14, color: "var(--tmc-olive)" }}>+{e.slots.length - 6} more</span>)}
                  {!e.soldOut && e.bundleUrl && (
                    <button onClick={() => setBundle(e.bundleUrl)}
                      style={{ fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".06em", textTransform: "uppercase", padding: "8px 14px", border: "none", borderRadius: "var(--radius-sm)", color: "var(--tmc-cream)", background: "var(--tmc-emerald)", cursor: "pointer" }}>
                      Bundle &amp; save →
                    </button>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      ); })}
      {booking && <BookingModal url={booking.url} name={booking.name} onClose={() => setBooking(null)} />}
      {bundle && <BundleModal url={bundle} onClose={() => setBundle(null)} />}
      {waitlist && <WaitlistModal event={waitlist.event} when={waitlist.when} onClose={() => setWaitlist(null)} />}
    </div>
  );
}

// One-click bundle checkout: the GHL payment form (date dropdowns + card) in
// the same branded modal pattern as bookings. Sized by GHL's form_embed.js.
function BundleModal({ url, onClose }) {
  const fid = (url.match(/widget\/form\/([A-Za-z0-9]+)/) || [])[1] || "bundle";
  React.useEffect(() => {
    const esc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", esc);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const sc = document.createElement("script");
    sc.src = "https://link.msgsndr.com/js/form_embed.js";
    document.body.appendChild(sc);
    return () => { document.removeEventListener("keydown", esc); document.body.style.overflow = prev; sc.remove(); };
  }, []);
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(30,10,14,.6)", display: "flex", alignItems: "center", justifyContent: "center", padding: 18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--tmc-cream)", borderRadius: "var(--radius-md)", position: "relative", width: "min(720px, 100%)", maxHeight: "94vh", display: "flex", flexDirection: "column", overflow: "hidden", boxShadow: "0 30px 80px rgba(0,0,0,.4)", animation: "tmc-modal-pop .28s var(--ease-out)" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 10, right: 12, zIndex: 2, background: "var(--tmc-cream)", border: "1px solid var(--tmc-burgundy)", borderRadius: "50%", width: 34, height: 34, fontSize: 20, lineHeight: 1, cursor: "pointer", color: "var(--tmc-burgundy)", boxShadow: "0 2px 8px rgba(30,10,14,.18)" }}>×</button>
        <div style={{ padding: "18px 24px 4px", textAlign: "center" }}>
          <div style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Three classes · one checkout · $40 savings</div>
        </div>
        <div style={{ overflowY: "auto" }}>
          <iframe
            src={url}
            style={{ width: "100%", border: "none", minHeight: 1267, display: "block", background: "#FFFFFF" }}
            id={"inline-" + fid}
            data-layout="{'id':'INLINE'}"
            data-trigger-type="alwaysShow"
            data-trigger-value=""
            data-activation-type="alwaysActivated"
            data-activation-value=""
            data-deactivation-type="neverDeactivate"
            data-deactivation-value=""
            data-form-name="Mahjong Starter Bundle"
            data-height="1267"
            data-layout-iframe-id={"inline-" + fid}
            data-form-id={fid}
            title="Mahjong Starter Bundle"
            allow="payment *"
          />
        </div>
      </div>
    </div>, document.body);
}

function Calendar({ go, page }) {
  const [club, setClub] = React.useState("scottsdale");
  const [showWidget, setShowWidget] = React.useState(false);
  const active = CLUBS.find(c => c.id === club) || CLUBS[0];
  const clubRow = (
        <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 12, flexWrap: "wrap" }}>
          <label htmlFor="club-select" style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Choose your club</label>
          <select id="club-select" value={club} onChange={e => setClub(e.target.value)}
            style={{ fontFamily: "var(--font-body)", fontSize: 15, color: "var(--text-body)", background: "var(--surface-card)", border: "1px solid var(--tmc-olive)", borderRadius: "var(--radius-sm)", padding: "11px 40px 11px 16px", cursor: "pointer", appearance: "none", backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%235B6A4C' stroke-width='1.5'/></svg>\")", backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center" }}>
            {CLUBS.map(c => <option key={c.id} value={c.id} disabled={!c.group}>{c.label}</option>)}
          </select>
        </div>
  );
  React.useEffect(() => {
    if (!showWidget || document.getElementById("ghl-embed-js")) return;
    const s = document.createElement("script");
    s.id = "ghl-embed-js";
    s.src = "https://link.msgsndr.com/js/form_embed.js";
    s.async = true;
    document.body.appendChild(s);
  }, [showWidget]);
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section style={{ position: "relative", overflow: "hidden", backgroundImage: "linear-gradient(rgba(30,10,14,.46), rgba(30,10,14,.56)), url('assets/imagery/patio-brunch.jpg')", backgroundSize: "cover", backgroundPosition: "center 55%", color: "var(--tmc-cream)", padding: "158px 48px 168px", textAlign: "center" }} className="tmc-stagger tmc-hero">
        <video autoPlay muted loop playsInline preload="metadata" poster="assets/imagery/patio-brunch.jpg"
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", zIndex: 0, pointerEvents: "none" }}>
          <source src="assets/video/calendar-hero.mp4" type="video/mp4" />
        </video>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, zIndex: 1, background: "linear-gradient(rgba(30,10,14,.42), rgba(30,10,14,.54))" }}></div>
        <div style={{ position: "relative", zIndex: 2, maxWidth: 720, margin: "0 auto" }}>
          <div className="tmc-cal-eyebrow" style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>Calendar of play</div>
          <h1 style={{ ...tmcDisplay, fontSize: 64, lineHeight: .95, margin: "14px 0 0", color: "var(--tmc-cream)" }}>Grab your seat</h1>
          <div style={{ fontFamily: "var(--font-script)", fontSize: 42, color: "var(--tmc-blush)", marginTop: 8 }}>at the table!</div>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6, margin: "18px auto 0", maxWidth: 560, color: "var(--tmc-cream)", textShadow: "0 1px 6px rgba(30,10,14,.5)" }}>
            Click on the events below to sign up for Drop-ins, Socials, Special Events, and Group Lessons.
          </p>
          <div style={{ ...tmcEyebrow, fontSize: 10, color: "var(--tmc-butter)", marginTop: 16 }}>open to non-members</div>
        </div>
      </section>
      <section style={{ padding: "56px 96px 76px", backgroundImage: "url('assets/imagery/pattern-stripe-olive-paper.jpg')", backgroundRepeat: "repeat", backgroundSize: "1100px auto", backgroundAttachment: "fixed", backgroundPosition: "center" }}>
        <div style={{ background: "#FFFFFF", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lift)", padding: "44px 48px", maxWidth: 1000, margin: "0 auto" }}>
        {!active.group && clubRow}
        {active.group ? (
          <React.Fragment>
            <p style={{ fontSize: 13.5, lineHeight: 1.6, textAlign: "center", maxWidth: 640, margin: "0 auto 26px", color: "var(--tmc-olive)" }}>
              <b style={{ color: "var(--tmc-raspberry)" }}>Please note:</b> because our events are intentionally curated with limited seating, cancellations made within 7 days of the event are non-refundable. We're always happy to issue a credit for a future class or event with prior notice.
            </p>
            <ScheduleView clubRow={clubRow} groupUrl={"https://api.leadconnectorhq.com/widget/group/" + active.group} onFail={() => setShowWidget(true)} />
            <div style={{ textAlign: "center", marginTop: 36 }}>
              <Button variant="outline" onClick={() => setShowWidget(s => !s)}>{showWidget ? "Hide the full booking calendar" : "Open the full booking calendar"}</Button>
            </div>
            {showWidget && (
              <Card padding={8} style={{ marginTop: 22 }}>
                <iframe key={active.group} src={"https://api.leadconnectorhq.com/widget/group/" + active.group}
                  allow="payment" scrolling="no" id={active.group + "_embed"} title="Book an event"
                  style={{ width: "100%", minHeight: 700, border: "none", overflow: "hidden", borderRadius: "var(--radius-sm)", background: "var(--surface-card)" }}></iframe>
              </Card>
            )}
          </React.Fragment>
        ) : (
          <Card padding={52} style={{ textAlign: "center" }}>
            <div style={{ ...tmcDisplay, fontSize: 30, color: "var(--text-display)" }}>Coming soon</div>
            <p style={{ fontSize: 15, lineHeight: 1.55, margin: "10px auto 0", maxWidth: 440 }}>This chapter's calendar isn't live yet. Choose Scottsdale to book now — the Phoenix schedule opens shortly.</p>
          </Card>
        )}
        <div style={{ textAlign: "center", marginTop: 16, fontSize: 14, color: "var(--tmc-olive)" }}>Cancellations within 7 days are non-refundable — we're happy to issue a credit.</div>
        </div>
      </section>
      <InstagramFeed />
      <TmcFooter go={go} />
    </main>
  );
}

// Direct booking links per event type. Fill these with the GHL booking URLs
// once the self-service calendars are live; until then buttons route to Calendar.
const EVENT_BOOKING = { parties: "", junior: "" };

function CorporateForm() {
  const [sent, setSent] = React.useState(false);
  const [f, setF] = React.useState({ name: "", email: "", company: "", guests: "", dates: "", vision: "" });
  const set = k => e => setF(v => ({ ...v, [k]: e.target.value }));
  const submit = () => {
    if (!/.+@.+\..+/.test(f.email)) return alert("Please enter a work email so we can reply.");
    fetch("/api/contact", { method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: f.name, email: f.email, source: "corporate",
        message: "Company: " + f.company + " | Guests: " + f.guests + " | Dates: " + f.dates + " | Vision: " + f.vision }) }).catch(() => {});
    setSent(true);
  };
  return (
    <Card padding={30}>
      {sent ? (
        <div style={{ textAlign: "center", padding: "22px 0" }}>
          <div style={{ ...tmcDisplay, fontSize: 28, color: "var(--text-display)" }}>Thank you</div>
          <p style={{ fontSize: 15, lineHeight: 1.55, margin: "10px 0 0" }}>We'll be in touch to plan your corporate mahjong experience.</p>
        </div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div style={{ display: "flex", gap: 14 }} className="tmc-btnrow">
            <Input label="Name" placeholder="Ruth Katz" style={{ flex: 1 }} value={f.name} onChange={set("name")} />
            <Input label="Work email" type="email" placeholder="you@company.com" style={{ flex: 1 }} value={f.email} onChange={set("email")} />
          </div>
          <div style={{ display: "flex", gap: 14 }} className="tmc-btnrow">
            <Input label="Company" placeholder="Company name" style={{ flex: 1 }} value={f.company} onChange={set("company")} />
            <Input label="Approx. guests" placeholder="e.g. 20" style={{ flex: 1 }} value={f.guests} onChange={set("guests")} />
          </div>
          <Input label="Preferred date(s)" placeholder="e.g. the week of Oct 6" value={f.dates} onChange={set("dates")} />
          <Input label="What are you envisioning?" placeholder="Team workshop, happy hour, offsite…" value={f.vision} onChange={set("vision")} />
          <Button size="lg" fullWidth onClick={submit}>Request info</Button>
          <div style={{ fontSize: 11, textAlign: "center", color: "var(--tmc-olive)" }}>events@themahjclubs.com · (480) 979-2571</div>
        </div>
      )}
    </Card>
  );
}

// Private parties & experiences — content migrated on-site from the club's
// package PDFs (Aug 2026). Booking buttons go straight to Stripe.
const PARTY_PACKAGES = [
  {
    img: "kids-birthday.jpg",
    title: "Kids Birthday Parties",
    price: "From $500",
    lede: "One-of-a-kind birthday celebrations with mahjong, friends, creativity, and fun — for experienced young players or brand-new Mahj learners.",
    sections: [
      ["Mahjong Social Party · $500", ["Two hours of the club with automatic tables and equipment", "Dedicated party host on-site", "Mahjong-themed party space", "Time and space for cake, gifts, and celebration (BYO food & drink)", "Best for ages 8–13 who already know the basics"]],
      ["Mahjong Academy Party · from $600", ["Everything in the Social Party, plus an instructor-led beginner lesson and guided play", "$600 · up to 8 children (1 instructor)", "$700 · 9–16 children (2 instructors)", "$800 · 17–24 children (3 instructors)"]],
      ["Add-on experiences (inquire for pricing)", ["Mahjong Maker Studio craft experience", "Curated mahjong favor bags", "Mahj-ical Moments decor package", "Snack & drink station"]],
    ],
    note: "$150 deposit reserves your date (applied to the party total). Custom packages available for any mix of ages and experience.",
    buttons: [["Book a kids party", "https://book.stripe.com/6oU8wQccn3zEaC02WH5wJ23"]],
  },
  {
    img: "mahj-mail.jpg",
    title: "Mahj Mail Parties",
    price: "$80 per person",
    lede: "Pack a little love, play a little Mahj — a private care-package party for college mom groups, neighbors, and empty nesters. Your group, your date, your time.",
    sections: [
      ["Every Mahj Mail Party includes", ["Care package station with all packing and decorating supplies", "A few curated goodies to start each box — bring your own extras too", "Social mahjong play around the tables", "A mini lesson from an instructor — no experience necessary", "Light bites and refreshments while you pack and play"]],
    ],
    note: "Perfect for college drop-off moms, sorority mom groups, neighborhood friends, and anyone missing their college kid just a little bit.",
    buttons: [["Book a Mahj Mail party", "https://book.stripe.com/9B67sM7W7gmqdOccxh5wJ24"]],
  },
  {
    img: "space-rentals.jpg",
    title: "Space Rentals",
    price: "From $160",
    lede: "A luxury, design-forward social club in the heart of Old Town Scottsdale — about 2,700 square feet with chandeliers, flexible layouts, thirteen automatic tables, and complimentary on-site parking.",
    sections: [
      ["Full facility", ["Up to 68 players or 150 total guests", "$350/hour with a 3-hour minimum, then $250/hour", "$250 retainer secures your date (credited toward your event)"]],
      ["Private room", ["Up to 16 players in the exclusive 4-table room", "$200/hour with a 3-hour minimum", "Serving area for beverages and bites"]],
      ["Single table", ["Up to 4 people in the private room", "$160 for 3 hours on an automatic table"]],
      ["Add-ons & services (inquire)", ["Beverage packages, grazing boards, and light catering", "Event styling and decor enhancements", "Beginner instruction, event planning, and tournament management", "Members receive preferred pricing and priority booking"]],
    ],
    note: "Cancellations: 50% refundable up to 14 days prior; non-refundable within 14 days. Cleaning fee $75–150 for large parties.",
    buttons: [["Reserve the facility", "https://book.stripe.com/5kQ00k3FRc6afWk54P5wJ25"], ["Rent a table", "https://book.stripe.com/00w14o7W7eei11qap95wJ26"]],
  },
];

function PartyCard({ p }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="tmc-pop" style={{ height: "100%" }}>
    <Card padding={0} style={{ overflow: "hidden", height: "100%", display: "flex", flexDirection: "column", boxSizing: "border-box" }}>
      <img src={"assets/imagery/parties/" + p.img} alt={p.title} style={{ display: "block", width: "100%", aspectRatio: "16 / 10", objectFit: "cover" }} />
      <div style={{ padding: "26px 28px 28px", display: "flex", flexDirection: "column", flex: 1 }}>
        <h3 style={{ ...tmcDisplay, fontSize: 27, color: "var(--tmc-burgundy)", margin: 0 }}>{p.title}</h3>
        <div style={{ marginTop: 10 }}><Badge tone="blush">{p.price}</Badge></div>
        <p style={{ fontSize: 15, lineHeight: 1.6, margin: "12px 0 0" }}>{p.lede}</p>
        <div style={{ flex: 1, marginTop: 14 }}>
          {open && (
            <div>
              {p.sections.map(([h, items]) => (
                <div key={h} style={{ marginTop: 14 }}>
                  <div style={{ ...tmcEyebrow, fontSize: 9, color: "var(--tmc-raspberry)" }}>{h}</div>
                  <div style={{ marginTop: 8, display: "flex", flexDirection: "column", gap: 6 }}>
                    {items.map(x => (
                      <div key={x} style={{ display: "flex", gap: 9, fontSize: 13.5, lineHeight: 1.5, alignItems: "baseline" }}>
                        <span style={{ color: "var(--tmc-raspberry)" }}>·</span><span>{x}</span>
                      </div>
                    ))}
                  </div>
                </div>
              ))}
              <p style={{ fontSize: 12.5, lineHeight: 1.55, margin: "16px 0 0", color: "var(--tmc-olive)" }}>{p.note}</p>
            </div>
          )}
          <button onClick={() => setOpen(o => !o)} style={{ marginTop: 12, background: "none", border: "none", padding: 0, cursor: "pointer", fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--tmc-raspberry)" }}>
        {open ? "Hide details ↑" : "See what's included ↓"}
          </button>
        </div>
        <div style={{ marginTop: 18, display: "flex", gap: 10, flexWrap: "wrap" }} className="tmc-btnrow">
          {p.buttons.map(([label, url]) => (
            <Button key={label} onClick={() => window.open(url, "_blank")}>{label}</Button>
          ))}
        </div>
      </div>
    </Card>
    </div>
  );
}

const CORP_GALLERY = [
  "assets/imagery/private-patio.jpg",
  "assets/imagery/corp-gallery/corp-1.jpg",
  "assets/imagery/corp-gallery/corp-2.jpg",
  "assets/imagery/corp-gallery/corp-3.jpg",
  "assets/imagery/corp-gallery/corp-4.jpg",
  "assets/imagery/corp-gallery/corp-5.jpg",
];
function CorpGallery() {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setI(x => (x + 1) % CORP_GALLERY.length), 3600);
    return () => clearInterval(t);
  }, []);
  return (
    <div style={{ position: "relative", minHeight: 520, height: "100%", overflow: "hidden" }}>
      {CORP_GALLERY.map((src, k) => (
        <img key={src} src={src} alt="Corporate and private mahjong events" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block", opacity: k === i ? 1 : 0, transition: "opacity 1.1s ease" }} />
      ))}
    </div>
  );
}

function PrivateEvents({ go, page }) {
  const corp = () => { const el = document.getElementById("corporate-inquiry"); if (el) el.scrollIntoView({ behavior: "smooth" }); };
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section className="tmc-stagger tmc-hero" style={{ background: "var(--tmc-emerald)", textAlign: "center", padding: "88px 24px 96px", position: "relative", overflow: "hidden" }}>
        <FloatTile name="martini" size={96} rotate={-10} speed={0.1} style={{ left: "8%", top: 96 }} />
        <FloatTile name="car" size={96} rotate={11} speed={0.14} style={{ right: "8%", bottom: 70 }} />
        <div style={{ maxWidth: 720, margin: "0 auto" }}>
          <div style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>Private events</div>
          <h1 style={{ ...tmcDisplay, fontSize: 60, lineHeight: .95, color: "var(--tmc-cream)", margin: "16px 0 0" }}>Make it a mahjong experience</h1>
          <div style={{ fontFamily: "var(--font-script)", fontSize: 40, color: "var(--tmc-blush)", marginTop: 8 }}>we come to you, too</div>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6, margin: "18px auto 0", maxWidth: 560, color: "var(--tmc-cream)" }}>
            Our private room accommodates up to 16 guests, while the entire club can be rented exclusively for parties of up to 150. Or host at your home, office, or another location — we'll bring the tables.
          </p>
        </div>
      </section>
      <section style={{ padding: "72px 96px 0", background: "#FFFFFF" }}>
        <h2 style={{ ...tmcDisplay, fontSize: 42, color: "var(--text-display)", textAlign: "center", margin: 0 }}>Private parties & experiences</h2>
        <p style={{ fontSize: 15, lineHeight: 1.6, textAlign: "center", maxWidth: 560, margin: "14px auto 0", color: "var(--tmc-olive)" }}>
          Three signature ways to celebrate at the club — every package includes the tables, the space, and a team that handles the details.
        </p>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3,minmax(0,1fr))", gap: 22, marginTop: 40, alignItems: "start" }}>
          {PARTY_PACKAGES.map(p => <PartyCard key={p.title} p={p} />)}
        </div>
      </section>
      <section id="corporate-inquiry" style={{ marginTop: 84, display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)", alignItems: "stretch" }}>
        <CorpGallery />
        <div style={{ backgroundImage: "url('assets/imagery/pattern-stripe-olive-paper.jpg')", backgroundRepeat: "repeat", backgroundSize: "1100px auto", padding: "56px 40px", display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center" }}>
          <div className="tmc-paper-note" style={{ backgroundImage: "url('assets/imagery/paper-note.webp')", backgroundSize: "100% 100%", backgroundRepeat: "no-repeat", padding: "96px 84px 110px", maxWidth: 560, filter: "drop-shadow(0 18px 36px rgba(20,8,10,.28))" }}>
          <div style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Corporate events · a club favorite</div>
          <h2 style={{ ...tmcDisplay, fontSize: 46, lineHeight: 1.02, color: "var(--tmc-burgundy)", margin: "14px 0 0" }}>Bring the table to your team</h2>
          <div style={{ fontFamily: "var(--font-script)", fontSize: 32, color: "var(--tmc-raspberry)", marginTop: 8 }}>the offsite they'll actually remember</div>
          <p style={{ fontSize: 15, lineHeight: 1.65, margin: "18px 0 0", maxWidth: 460, color: "var(--text-body)" }}>
            A guided mahjong experience makes an unforgettable workshop, offsite, or client event — at the club or at your office. Instruction, tables, and a concierge team included; we design it around your group.
          </p>
          <div style={{ marginTop: 16, display: "flex", flexDirection: "column", gap: 8 }}>
            {["Team workshops, offsites & client entertainment", "At the club — or we bring the tables to you", "Instructors and event concierge included", "Catering, beverages & styling available"].map(x => (
              <div key={x} style={{ display: "flex", gap: 10, fontSize: 14, alignItems: "baseline", color: "var(--text-body)" }}>
                <span style={{ color: "var(--tmc-raspberry)" }}>·</span><span>{x}</span>
              </div>
            ))}
          </div>
          <div style={{ marginTop: 28 }}>
            <Button size="lg" onClick={() => { const el = document.getElementById("corporate-form"); if (el) el.scrollIntoView({ behavior: "smooth" }); }}>Plan a corporate event</Button>
          </div>
          </div>
        </div>
      </section>
      <section id="corporate-form" style={{ padding: "72px 96px 0" }}>
        <div style={{ maxWidth: 640, margin: "0 auto" }}>
          <h2 style={{ ...tmcDisplay, fontSize: 34, color: "var(--text-display)", textAlign: "center", margin: "0 0 24px" }}>Tell us what you're planning</h2>
          <CorporateForm />
        </div>
      </section>
      <InstagramFeed />
      <TmcFooter go={go} />
    </main>
  );
}

// Live Shopify storefront — same store, same checkout as her current site.
// Credentials are the PUBLIC Storefront token already published on the old
// WordPress embed; products are managed entirely in her Shopify admin.
const SHOPIFY = {
  domain: "0vxpjt-eh.myshopify.com",
  token: "e6911869fe328fbdea5ab478f13e1e7c",
  collection: "gid://shopify/Collection/520549433623",
};

function useShopifyProducts() {
  const [state, setState] = React.useState({ loading: true, products: null, error: false });
  React.useEffect(() => {
    let cancelled = false;

    async function loadProducts() {
      const allProducts = [];
      let cursor = null;
      let hasNextPage = true;

      while (hasNextPage) {
        const query = `query ShopProducts($after: String) {
          collection(id: "${SHOPIFY.collection}") {
            products(first: 100, after: $after) {
              nodes {
                title
                description
                descriptionHtml
                featuredImage { url }
                images(first: 6) { nodes { url } }
                variants(first: 10) { nodes { id title availableForSale price { amount } } }
              }
              pageInfo { hasNextPage endCursor }
            }
          }
        }`;

        const response = await fetch("https://" + SHOPIFY.domain + "/api/2024-07/graphql.json", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "X-Shopify-Storefront-Access-Token": SHOPIFY.token
          },
          body: JSON.stringify({ query, variables: { after: cursor } })
        });
        const json = await response.json();
        const page = json && json.data && json.data.collection && json.data.collection.products;
        if (!page || !page.nodes) throw new Error("empty");

        allProducts.push(...page.nodes);
        hasNextPage = page.pageInfo.hasNextPage;
        cursor = page.pageInfo.endCursor;
      }

      if (!cancelled) {
        setState({ loading: false, products: allProducts, error: false });
      }
    }

    loadProducts().catch(() => {
      if (!cancelled) setState({ loading: false, products: null, error: true });
    });

    return () => { cancelled = true; };
  }, []);
  return state;
}

function ProductModal({ p, onClose }) {
  const variants = p.variants.nodes;
  const imgs = (p.images && p.images.nodes && p.images.nodes.length ? p.images.nodes : (p.featuredImage ? [p.featuredImage] : []));
  const [vid, setVid] = React.useState(variants[0] && variants[0].id);
  const [qty, setQty] = React.useState(1);
  const [imgI, setImgI] = React.useState(0);
  const v = variants.find(x => x.id === vid) || variants[0];
  const price = v ? "$" + (Number(v.price.amount) * qty).toFixed(Number(v.price.amount) % 1 ? 2 : 0) : "";
  React.useEffect(() => {
    const esc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", esc);
    const sw = window.innerWidth - document.documentElement.clientWidth;
    document.body.style.overflow = "hidden";
    if (sw > 0) document.body.style.paddingRight = sw + "px";
    return () => { document.removeEventListener("keydown", esc); document.body.style.overflow = ""; document.body.style.paddingRight = ""; };
  }, []);
  const addToCart = () => { if (!v) return; window.TmcCart.add(v.id, qty).then(() => onClose()); };
  const qbtn = { width: 34, height: 34, border: "1px solid var(--tmc-olive)", background: "#FFFFFF", borderRadius: "var(--radius-sm)", cursor: "pointer", fontSize: 16, color: "var(--text-body)", fontFamily: "var(--font-body)" };
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 100, background: "rgba(30,10,14,.55)", display: "flex", alignItems: "center", justifyContent: "center", padding: 20, animation: "tmc-fade-in 150ms var(--ease-out) both" }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--tmc-tile-white)", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lift)", maxWidth: 900, width: "100%", maxHeight: "88vh", overflowY: "auto", position: "relative", animation: "tmc-modal-pop 190ms var(--ease-out) both" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 12, right: 14, zIndex: 2, background: "none", border: "none", fontSize: 26, lineHeight: 1, cursor: "pointer", color: "var(--tmc-burgundy)" }}>×</button>
        <div style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)", gap: 0 }}>
          <div style={{ padding: 18 }}>
            {imgs[imgI] && <img src={imgs[imgI].url} alt={p.title} style={{ display: "block", width: "100%", aspectRatio: "1 / 1", objectFit: "cover", borderRadius: "var(--radius-sm)", background: "var(--tmc-cream)" }} />}
            {imgs.length > 1 && (
              <div style={{ display: "flex", gap: 8, marginTop: 10, flexWrap: "wrap" }}>
                {imgs.map((im, i) => (
                  <img key={i} src={im.url} alt={p.title + " — photo " + (i + 1)} onClick={() => setImgI(i)}
                    style={{ width: 56, height: 56, objectFit: "cover", borderRadius: 4, cursor: "pointer", border: i === imgI ? "2px solid var(--tmc-raspberry)" : "2px solid transparent" }} />
                ))}
              </div>
            )}
          </div>
          <div style={{ padding: "30px 30px 30px 16px" }}>
            <h3 style={{ ...tmcDisplay, fontSize: 30, lineHeight: 1.1, color: "var(--tmc-burgundy)", margin: 0, paddingRight: 26 }}>{p.title}</h3>
            <div style={{ ...tmcEyebrow, fontSize: 13, color: "var(--tmc-raspberry)", marginTop: 10 }}>{price}</div>
            {p.descriptionHtml && <div className="tmc-prodhtml" dangerouslySetInnerHTML={{ __html: p.descriptionHtml }}></div>}
            {variants.length > 1 && (
              <select value={vid} onChange={e => setVid(e.target.value)}
                style={{ marginTop: 18, width: "100%", fontFamily: "var(--font-body)", fontSize: 14, color: "var(--text-body)", background: "#FFFFFF", border: "1px solid var(--tmc-olive)", borderRadius: "var(--radius-sm)", padding: "11px 12px" }}>
                {variants.map(x => <option key={x.id} value={x.id} disabled={!x.availableForSale}>{x.title}{x.availableForSale ? "" : " — sold out"}</option>)}
              </select>
            )}
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 16 }}>
              <span style={{ ...tmcEyebrow, fontSize: 9 }}>Qty</span>
              <button style={qbtn} onClick={() => setQty(q => Math.max(1, q - 1))}>−</button>
              <span style={{ fontSize: 15, minWidth: 22, textAlign: "center" }}>{qty}</span>
              <button style={qbtn} onClick={() => setQty(q => Math.min(20, q + 1))}>+</button>
            </div>
            <div style={{ marginTop: 20 }}>
              <Button fullWidth size="lg" onClick={addToCart} disabled={v && !v.availableForSale}>{v && !v.availableForSale ? "Sold out" : "Add to cart"}</Button>
            </div>
            <div style={{ fontSize: 14, color: "var(--tmc-olive)", marginTop: 10, textAlign: "center" }}>Added items appear in your cart — top right.</div>
          </div>
        </div>
      </div>
    </div>
  );
}

function ProductCard({ p }) {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    const want = window.TMC_OPEN_PRODUCT;
    if (want && p.title.toLowerCase().includes(want.toLowerCase())) { window.TMC_OPEN_PRODUCT = null; setOpen(true); }
  }, []);
  const variants = p.variants.nodes;
  const v = variants[0];
  const price = v ? "$" + Number(v.price.amount).toFixed(Number(v.price.amount) % 1 ? 2 : 0) : "";
  const anyAvailable = variants.some(x => x.availableForSale);
  return (
    <div className="tmc-pop" style={{ height: "100%" }}>
      <Card padding={0} style={{ overflow: "hidden", height: "100%", display: "flex", flexDirection: "column", boxSizing: "border-box" }}>
        <div onClick={() => setOpen(true)} style={{ cursor: "pointer" }}>
          {p.featuredImage
            ? <img src={p.featuredImage.url} alt={p.title} style={{ display: "block", width: "100%", aspectRatio: "1 / 1", objectFit: /(scoring notepad|line highlighter stickers|three flamingos)/i.test(p.title) ? "contain" : "cover", padding: /(scoring notepad|line highlighter stickers|three flamingos)/i.test(p.title) ? "14px" : 0, boxSizing: "border-box", background: "var(--tmc-cream)" }} />
            : <div style={{ aspectRatio: "1 / 1", background: "var(--tmc-cream)" }}></div>}
        </div>
        <div style={{ padding: "20px 22px 24px", display: "flex", flexDirection: "column", flex: 1 }}>
          <h3 style={{ ...tmcDisplay, fontSize: 21, lineHeight: 1.15, color: "var(--tmc-burgundy)", margin: 0, cursor: "pointer" }} onClick={() => setOpen(true)}>{p.title}</h3>
          <div style={{ ...tmcEyebrow, fontSize: 11, color: "var(--tmc-raspberry)", marginTop: 8 }}>{price}{variants.length > 1 ? " +" : ""}</div>
          {p.description && <p style={{ fontSize: 13, lineHeight: 1.55, margin: "10px 0 0", color: "var(--text-body)", display: "-webkit-box", WebkitLineClamp: 3, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{p.description}</p>}
          <div style={{ flex: 1 }}></div>
          <div style={{ marginTop: 16 }}>
            <Button fullWidth variant="outline" onClick={() => setOpen(true)}>{anyAvailable ? "View product" : "Sold out"}</Button>
          </div>
        </div>
      </Card>
      {open && ReactDOM.createPortal(<ProductModal p={p} onClose={() => setOpen(false)} />, document.body)}
    </div>
  );
}

const SHOP_CATS = ["All", "Tiles & Sets", "Mats", "Racks & Tables", "Bags & Totes", "Accessories", "Apparel", "Home & Gifts"];
function shopCatOf(title) {
  const t = " " + title.toLowerCase() + " ";
  if (/sweatshirt|t-shirt|crewneck|pajama/.test(t)) return "Apparel";
  if (/\bmats?\b|\bmats-/.test(t)) return "Mats";
  if (/rack|pusher|\btable\b/.test(t)) return "Racks & Tables";
  if (/\bbags?\b|tote|purse|pouch|carryall|train case/.test(t)) return "Bags & Totes";
  if (/folio|card clutch|keychain|shuffler|display case|coaster/.test(t)) return "Accessories";
  if (/tile|mahjong set|mini mahjer|travel mahjong/.test(t)) return "Tiles & Sets";
  return "Home & Gifts";
}

function Shop({ go, page }) {
  const { loading, products, error } = useShopifyProducts();
  const [q, setQ] = React.useState("");
  const [cat, setCat] = React.useState("All");
  const shown = React.useMemo(() => {
    if (!products) return null;
    let list = products;
    if (cat !== "All") list = list.filter(p => shopCatOf(p.title) === cat);
    const needle = q.trim().toLowerCase();
    if (needle) list = list.filter(p => (p.title + " " + (p.description || "")).toLowerCase().includes(needle));
    return list;
  }, [products, q, cat]);
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section className="tmc-stagger tmc-hero" style={{ background: "var(--tmc-emerald)", textAlign: "center", padding: "88px 24px 96px", position: "relative", overflow: "hidden" }}>
        <FloatTile name="martini" size={96} rotate={-10} speed={0.1} style={{ left: "8%", top: 96 }} />
        <FloatTile name="car" size={96} rotate={11} speed={0.14} style={{ right: "8%", bottom: 70 }} />
        <div style={{ maxWidth: 720, margin: "0 auto" }}>
          <div style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>The boutique</div>
          <h1 style={{ ...tmcDisplay, fontSize: 56, lineHeight: .95, color: "var(--tmc-cream)", margin: "16px 0 0" }}>Shop the club</h1>
          <div style={{ fontFamily: "var(--font-script)", fontSize: 38, color: "var(--tmc-blush)", marginTop: 8 }}>tiles, mats & gifts</div>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.55, margin: "18px auto 0", maxWidth: 560, color: "var(--tmc-cream)" }}>
            Mahjong-themed gifts and a curated selection of tiles, mats, and everything necessary to become a mahjong pro or host a social gathering. Shop online or visit us at 4821 N. Scottsdale Rd, Suite 106, Old Town Scottsdale.
          </p>
        </div>
      </section>
      <section style={{ padding: "48px 96px 0" }}>
        {loading && <div style={{ textAlign: "center", padding: "56px 0", fontSize: 13, color: "var(--tmc-olive)" }}>Opening the boutique…</div>}
        {error && (
          <Card padding={44} style={{ textAlign: "center", maxWidth: 560, margin: "0 auto" }}>
            <div style={{ ...tmcDisplay, fontSize: 26, color: "var(--text-display)" }}>The online boutique is restocking</div>
            <p style={{ fontSize: 15, lineHeight: 1.55, margin: "10px auto 0", maxWidth: 400 }}>Visit us in Old Town Scottsdale, or check back shortly.</p>
          </Card>
        )}
        {products && (
          <p style={{ fontSize: 13, textAlign: "center", color: "var(--tmc-olive)", margin: "0 auto 18px", maxWidth: 560 }}>
            Online purchases may be exchanged within 14 days of delivery; in-store purchases may be exchanged within 30 days of purchase, subject to our<br /><a href="/returns" onClick={e => { e.preventDefault(); go("returns"); }} style={{ color: "var(--tmc-raspberry)" }}>Return & Exchange Policy</a>.
          </p>
        )}
        {products && (
          <div style={{ display: "flex", flexDirection: "column", gap: 12, marginBottom: 30 }}>
            <input
              type="search"
              value={q}
              onChange={e => setQ(e.target.value)}
              placeholder="Search the boutique — tiles, mats, bags…"
              style={{ width: "100%", maxWidth: 520, margin: "0 auto", boxSizing: "border-box", fontFamily: "var(--font-body)", fontSize: 15, color: "var(--text-body)", background: "var(--surface-card)", border: "1px solid var(--border-subtle)", borderRadius: 999, padding: "13px 22px", outline: "none", display: "block" }}
            />
            <div className="tmc-shop-cats" style={{ display: "flex", flexWrap: "wrap", gap: 8, justifyContent: "center" }}>
              {SHOP_CATS.map(c => (
                <button key={c} onClick={() => setCat(c)} style={{ fontFamily: "var(--font-body)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", padding: "9px 16px", borderRadius: 999, cursor: "pointer", border: "1px solid " + (cat === c ? "var(--tmc-raspberry)" : "var(--border-subtle)"), background: cat === c ? "var(--tmc-raspberry)" : "var(--surface-card)", color: cat === c ? "var(--tmc-cream)" : "var(--text-body)", transition: "background .15s ease, color .15s ease" }}>
                  {c}
                </button>
              ))}
            </div>
          </div>
        )}
        {shown && shown.length > 0 && (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(240px,1fr))", gap: 22, alignItems: "stretch" }}>
            {shown.map(p => <ProductCard key={p.title} p={p} />)}
          </div>
        )}
        {shown && shown.length === 0 && (
          <div style={{ textAlign: "center", padding: "44px 0", fontSize: 14, color: "var(--tmc-olive)" }}>
            Nothing matches — try another search or category.
          </div>
        )}
        <div style={{ textAlign: "center", marginTop: 26, fontSize: 14, color: "var(--tmc-olive)" }}>
          Checkout is handled securely by our shop partner. Boutique hours: Tue 12–5 · Wed 12–8 · Thu & Fri 12–7:30 · Sat & Sun 12–5
        </div>
      </section>
      <InstagramFeed />
      <TmcFooter go={go} />
    </main>
  );
}

function Contact({ go, page }) {
  const [sent, setSent] = React.useState(false);
  const [f, setF] = React.useState({ name: "", email: "", msg: "" });
  const set = k => e => setF(v => ({ ...v, [k]: e.target.value }));
  const submit = () => {
    if (!/.+@.+\..+/.test(f.email)) return alert("Please enter your email so we can get back to you.");
    fetch("/api/contact", { method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: f.name, email: f.email, message: f.msg, source: "contact" }) }).catch(() => {});
    setSent(true);
  };
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section className="tmc-contact-hero" style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)", alignItems: "stretch" }}>
        <img data-no-px="true" src="assets/imagery/contact-table.jpg" alt="Members around the table" style={{ width: "100%", height: "100%", minHeight: 620, objectFit: "cover", display: "block" }} />
        <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", padding: "72px 84px", background: "var(--tmc-cream)" }}>
          <div style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Contact</div>
          <h1 style={{ ...tmcDisplay, fontSize: 50, lineHeight: .98, color: "var(--text-display)", margin: "14px 0 0" }}>Write to the club</h1>
          <p style={{ fontSize: 15, lineHeight: 1.6, margin: "16px 0 0", maxWidth: 480 }}>Questions about lessons, membership, private events, or the league? Send us a note and we'll get right back to you.</p>
          <div style={{ marginTop: 28 }}>
        <Card padding={30}>
          {sent ? (
            <div style={{ textAlign: "center", padding: "18px 0" }}>
              <div style={{ ...tmcDisplay, fontSize: 28, color: "var(--text-display)" }}>Thank you</div>
              <p style={{ fontSize: 15, lineHeight: 1.55, margin: "10px 0 0" }}>We'll be in touch shortly.</p>
            </div>
          ) : (
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <div style={{ display: "flex", gap: 14 }} className="tmc-btnrow">
                <Input label="Name" placeholder="Ruth Katz" style={{ flex: 1 }} value={f.name} onChange={set("name")} />
                <Input label="Email" type="email" placeholder="you@example.com" style={{ flex: 1 }} value={f.email} onChange={set("email")} />
              </div>
              <Input label="What can we help with?" placeholder="Lessons, private events, membership…" value={f.msg} onChange={set("msg")} />
              <Button size="lg" fullWidth onClick={submit}>Send</Button>
              <div style={{ fontSize: 11, textAlign: "center", color: "var(--tmc-olive)" }}>hello@themahjclubs.com · (480) 979-2571</div>
            </div>
          )}
        </Card>
          </div>
        </div>
      </section>
      <section style={{ padding: "82px 96px 0" }}>
        <h2 style={{ ...tmcDisplay, fontSize: 42, color: "var(--text-display)", textAlign: "center", margin: 0 }}>Meet the staff</h2>
        <p style={{ fontSize: 15, lineHeight: 1.6, textAlign: "center", maxWidth: 520, margin: "14px auto 0", color: "var(--tmc-olive)" }}>
          The faces that pour the drinks, run the room, and save your seat.
        </p>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3,minmax(0,1fr))", gap: "48px 36px", marginTop: 44, maxWidth: 1020, marginLeft: "auto", marginRight: "auto" }}>
          {[
            ["Julia", "Owner / CEO", "staff-1.jpg"],
            ["Nisa", "Club Manager", "staff-3.jpg"],
            ["Nicole", "Merchandise Manager & Concierge", "staff-4.jpg"],
            ["Suzanne", "Concierge & Marketing Assistant", "staff-5.jpg"],
            ["Leslie", "Event Programming & Charitable Donations Manager · Concierge", "staff-6.jpg?v=2"],
            ["Ruth", "Concierge & Teaching Assistant", "staff-2.jpg"],
          ].map(([name, role, ph]) => (
            <div key={ph} style={{ textAlign: "center" }}>
              <img src={"assets/imagery/staff/" + ph} alt={name} style={{ width: "100%", aspectRatio: "3 / 4", height: "auto", borderRadius: "var(--radius-md)", objectFit: "cover", display: "block", boxShadow: "var(--shadow-card)" }} />
              <h3 style={{ ...tmcDisplay, fontSize: 24, color: "var(--text-display)", margin: "16px 0 0" }}>{name}</h3>
              <p style={{ ...tmcEyebrow, fontSize: 10, color: "var(--tmc-olive)", margin: "10px auto 0", maxWidth: 280, lineHeight: 1.7 }}>{role}</p>
            </div>
          ))}
        </div>
      </section>
      <InstagramFeed />
      <TmcFooter go={go} />
    </main>
  );
}




// Quiet policy page — footer-linked only, not in the nav.
function ReturnPolicy({ go, page }) {
  const H = ({ children }) => <h2 style={{ ...tmcDisplay, fontSize: 26, color: "var(--text-display)", margin: "36px 0 0" }}>{children}</h2>;
  const P = ({ children }) => <p style={{ fontSize: 15, lineHeight: 1.7, margin: "12px 0 0" }}>{children}</p>;
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section style={{ background: "var(--tmc-emerald)", textAlign: "center", padding: "64px 24px 60px" }}>
        <div style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>The fine print</div>
        <h1 style={{ ...tmcDisplay, fontSize: 46, lineHeight: 1, color: "var(--tmc-cream)", margin: "14px 0 0" }}>Return & Exchange Policy</h1>
      </section>
      <section style={{ maxWidth: 680, margin: "0 auto", padding: "48px 24px 72px" }}>
        <P>We want you to love what you take home from the boutique. If something isn't right, here's how returns and exchanges work.</P>
        <H>Boutique purchases</H>
        <P>Online purchases may be exchanged within <b>14 days</b> of delivery. In-store purchases may be exchanged within <b>30 days</b> of purchase. Items must be unused, in their original condition and packaging, with your receipt or order confirmation.</P>
        <P>To start an exchange, email <a href="mailto:hello@themahjclubs.com" style={{ color: "var(--tmc-raspberry)" }}>hello@themahjclubs.com</a> with your order details, or bring the item to the club during boutique hours.</P>
        <H>Shipping costs</H>
        <P>Original shipping charges are non-refundable, and return shipping is the purchaser's responsibility unless the item arrived damaged or defective.</P>
        <H>Exchanges</H>
        <P>Exchanges are subject to availability. If the piece you want isn't in stock, we'll issue boutique credit.</P>
        <H>Damaged or defective items</H>
        <P>If something arrives damaged or defective, contact us within 7 days of delivery and we'll make it right.</P>
        <H>Final sale</H>
        <P>Gift cards and items marked final sale cannot be returned or exchanged.</P>
        <H>Event & class bookings</H>
        <P>Because our events are intentionally curated with limited seating, cancellations made within 7 days of an event are non-refundable. With prior notice, we're always happy to issue a credit toward a future class or event. Membership purchases are governed by their own membership terms.</P>
        <H>Questions?</H>
        <P>Write to <a href="mailto:hello@themahjclubs.com" style={{ color: "var(--tmc-raspberry)" }}>hello@themahjclubs.com</a> or call (480) 979-2571 — we're happy to help.</P>
      </section>
      <TmcFooter go={go} />
    </main>
  );
}

function PrivacyPolicy({ go, page }) {
  const H = ({ children }) => <h2 style={{ ...tmcDisplay, fontSize: 26, color: "var(--text-display)", margin: "36px 0 0" }}>{children}</h2>;
  const P = ({ children }) => <p style={{ fontSize: 15, lineHeight: 1.7, margin: "12px 0 0" }}>{children}</p>;
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section style={{ background: "var(--tmc-emerald)", textAlign: "center", padding: "64px 24px 60px" }}>
        <div style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>The fine print</div>
        <h1 style={{ ...tmcDisplay, fontSize: 46, lineHeight: 1, color: "var(--tmc-cream)", margin: "14px 0 0" }}>Privacy Policy</h1>
      </section>
      <section style={{ maxWidth: 680, margin: "0 auto", padding: "48px 24px 72px" }}>
        <P>The Mahj Clubs ("we," "us") respects your privacy. This policy explains, in plain language, what we collect and how we use it. <i>Effective October 1, 2026.</i></P>
        <H>What we collect</H>
        <P>When you book a class or event, join the waitlist, make a purchase, or contact us, we collect what you give us: your name, email address, phone number, and anything you share in a message or form (like your level of play). Payments are processed securely by our payment providers — <b>we never see or store your card number</b>.</P>
        <H>How we use it</H>
        <P>To run the club: processing your bookings and orders, sending confirmations and class reminders, answering your messages, and letting you know about club news or offers <b>only if you've opted in</b>. We never sell or rent your personal information to anyone.</P>
        <H>Who helps us</H>
        <P>We use a small number of trusted services to operate — a scheduling and contact platform, a payment processor (Stripe), and a shop platform (Shopify). They receive only what's needed to serve you and are bound by their own privacy and security obligations.</P>
        <H>Your choices</H>
        <P>Every marketing email includes an unsubscribe link, and you can reply STOP to any text. To view, update, or delete the information we hold about you, just email <a href="mailto:hello@themahjclubs.com" style={{ color: "var(--tmc-raspberry)" }}>hello@themahjclubs.com</a> — we'll take care of it.</P>
        <H>Cookies</H>
        <P>Our booking and checkout tools use essential cookies so things like reservations and shopping carts work. We don't run advertising trackers.</P>
        <H>Children</H>
        <P>Our website isn't directed to children under 13, and we don't knowingly collect their information. Youth programs (like camps) are booked by a parent or guardian.</P>
        <H>Changes</H>
        <P>If we update this policy, the new version will be posted here with a new effective date.</P>
        <H>Questions?</H>
        <P>Write to <a href="mailto:hello@themahjclubs.com" style={{ color: "var(--tmc-raspberry)" }}>hello@themahjclubs.com</a> or call (480) 979-2571.</P>
      </section>
      <TmcFooter go={go} />
    </main>
  );
}

// Hidden pilot page (?page=test) — the Calendar page's look rebuilt on GHL
// native TICKETED EVENTS (fed by /api/tickets: a hidden "Ticket Events"
// calendar lists event URLs; details are parsed from each event page).
function TicketModal({ url, name, onClose }) {
  React.useEffect(() => {
    const esc = e => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", esc);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const s = document.createElement("script");
    s.src = "https://link.msgsndr.com/js/form_embed.js";
    document.body.appendChild(s);
    return () => { document.removeEventListener("keydown", esc); document.body.style.overflow = prev; s.remove(); };
  }, []);
  return ReactDOM.createPortal(
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 1000, background: "rgba(30,10,14,.6)", display: "flex", alignItems: "center", justifyContent: "center", padding: 18 }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--tmc-cream)", borderRadius: "var(--radius-md)", position: "relative", width: "min(1020px, 100%)", maxHeight: "94vh", display: "flex", flexDirection: "column", overflow: "hidden", boxShadow: "0 30px 80px rgba(0,0,0,.4)", animation: "tmc-modal-pop .28s var(--ease-out)" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 10, right: 12, zIndex: 2, background: "var(--tmc-cream)", border: "1px solid var(--tmc-burgundy)", borderRadius: "50%", width: 34, height: 34, fontSize: 20, lineHeight: 1, cursor: "pointer", color: "var(--tmc-burgundy)", boxShadow: "0 2px 8px rgba(30,10,14,.18)" }}>×</button>
        <div style={{ overflowY: "auto" }}>
          <iframe src={url} style={{ width: "100%", border: "none", minHeight: "86vh", display: "block", background: "#FFFFFF" }} scrolling="no" id={"tmc-ticket-" + url.split("/").pop()} allow="payment *" title={"Tickets — " + name} />
        </div>
      </div>
    </div>, document.body);
}

function TicketSchedule({ go, page }) {
  const [data, setData] = React.useState(null);
  const [buying, setBuying] = React.useState(null);
  const [q, setQ] = React.useState("");
  React.useEffect(() => {
    fetch("/api/tickets").then(r => r.json()).then(setData).catch(() => setData({ days: [] }));
  }, []);
  const dayLabel = iso => { const d = new Date(iso + "T12:00:00"); return { wd: d.toLocaleDateString("en-US", { weekday: "long" }), md: d.toLocaleDateString("en-US", { month: "short", day: "numeric" }) }; };
  const fmt = t => { if (!t) return ""; const p = t.split(":"); const H = +p[0]; return (((H + 11) % 12) + 1) + ":" + p[1] + (H >= 12 ? " PM" : " AM"); };
  const fieldStyle = { fontFamily: "var(--font-body)", fontSize: 15, color: "var(--text-body)", background: "#FFFFFF", border: "1px solid var(--tmc-olive)", borderRadius: "var(--radius-sm)", padding: "11px 16px" };
  const needle = q.trim().toLowerCase();
  const days = data ? data.days.map(d => ({ ...d, events: d.events.filter(e => !needle || (e.name + " " + (e.desc || "")).toLowerCase().includes(needle)) })).filter(d => d.events.length) : [];
  return (
    <main style={{ fontFamily: "var(--font-body)", color: "var(--text-body)" }}>
      <TmcNav go={go} page={page} />
      <section style={{ position: "relative", overflow: "hidden", backgroundImage: "linear-gradient(rgba(30,10,14,.46), rgba(30,10,14,.56)), url('assets/imagery/patio-brunch.jpg')", backgroundSize: "cover", backgroundPosition: "center 55%", color: "var(--tmc-cream)", padding: "158px 48px 168px", textAlign: "center" }} className="tmc-stagger tmc-hero">
        <video autoPlay muted loop playsInline preload="metadata" poster="assets/imagery/patio-brunch.jpg"
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", objectPosition: "center", zIndex: 0, pointerEvents: "none" }}>
          <source src="assets/video/calendar-hero.mp4" type="video/mp4" />
        </video>
        <div aria-hidden="true" style={{ position: "absolute", inset: 0, zIndex: 1, background: "linear-gradient(rgba(30,10,14,.42), rgba(30,10,14,.54))" }}></div>
        <div style={{ position: "relative", zIndex: 2, maxWidth: 720, margin: "0 auto" }}>
          <div className="tmc-cal-eyebrow" style={{ ...tmcEyebrow, color: "var(--tmc-butter)" }}>Calendar of play</div>
          <h1 style={{ ...tmcDisplay, fontSize: 64, lineHeight: .95, margin: "14px 0 0", color: "var(--tmc-cream)" }}>Grab your seat</h1>
          <div style={{ fontFamily: "var(--font-script)", fontSize: 42, color: "var(--tmc-blush)", marginTop: 8 }}>at the table!</div>
          <p style={{ fontFamily: "var(--font-body)", fontSize: 15, lineHeight: 1.6, margin: "18px auto 0", maxWidth: 560, color: "var(--tmc-cream)", textShadow: "0 1px 6px rgba(30,10,14,.5)" }}>
            Click on the events below to sign up for Drop-ins, Socials, Special Events, and Group Lessons.
          </p>
          <div style={{ ...tmcEyebrow, fontSize: 10, color: "var(--tmc-butter)", marginTop: 16 }}>open to non-members</div>
        </div>
      </section>
      <section style={{ padding: "56px 96px 76px", backgroundImage: "url('assets/imagery/pattern-stripe-olive-paper.jpg')", backgroundRepeat: "repeat", backgroundSize: "1100px auto", backgroundAttachment: "fixed", backgroundPosition: "center" }}>
        <div style={{ background: "#FFFFFF", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lift)", padding: "44px 48px", maxWidth: 1000, margin: "0 auto" }}>
          <p style={{ fontSize: 13.5, lineHeight: 1.6, textAlign: "center", maxWidth: 640, margin: "0 auto 26px", color: "var(--tmc-olive)" }}>
            <b style={{ color: "var(--tmc-raspberry)" }}>Please note:</b> because our events are intentionally curated with limited seating, cancellations made within 7 days of the event are non-refundable. We're always happy to issue a credit for a future class or event with prior notice.
          </p>
          <div style={{ maxWidth: 880, margin: "0 auto" }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: "14px 30px", flexWrap: "wrap", marginBottom: 26 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <label style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Choose your club</label>
                <select value="scottsdale" onChange={() => {}} style={{ ...fieldStyle, padding: "11px 40px 11px 16px", cursor: "pointer", appearance: "none", backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%235B6A4C' stroke-width='1.5'/></svg>\")", backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center" }}>
                  <option value="scottsdale">Scottsdale · Old Town</option>
                  <option disabled>More locations coming soon</option>
                </select>
              </div>
              <input type="search" value={q} onChange={e => setQ(e.target.value)} placeholder="Search events…" aria-label="Search events" style={{ ...fieldStyle, width: 190 }} />
            </div>
            {!data && <div style={{ textAlign: "center", padding: "44px 0", fontSize: 13, color: "var(--tmc-olive)" }}>Setting the table…</div>}
            {data && !days.length && <div style={{ textAlign: "center", padding: "40px 0", fontSize: 14.5, color: "var(--tmc-olive)" }}>Nothing on the calendar matches — <button onClick={() => setQ("")} style={{ background: "none", border: "none", padding: 0, cursor: "pointer", fontFamily: "var(--font-body)", fontSize: 14.5, color: "var(--tmc-raspberry)", textDecoration: "underline" }}>show everything</button></div>}
            {data && days.map(d => { const L = dayLabel(d.date); return (
              <div key={d.date} style={{ display: "grid", gridTemplateColumns: "150px minmax(0,1fr)", gap: 26, padding: "24px 0", borderTop: "var(--rule)" }}>
                <div>
                  <div style={{ ...tmcEyebrow, fontSize: 9, color: "var(--tmc-raspberry)" }}>{L.wd}</div>
                  <div style={{ ...tmcDisplay, fontSize: 30, color: "var(--text-display)", marginTop: 4 }}>{L.md}</div>
                </div>
                <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
                  {d.events.map(e => (
                    <div key={e.url}>
                      <div style={{ ...tmcDisplay, fontSize: 21, color: "var(--tmc-burgundy)" }}>{e.name}</div>
                      {e.desc && <p style={{ fontSize: 15.5, lineHeight: 1.55, margin: "5px 0 0", maxWidth: 560, color: "var(--text-body)" }}>{e.desc}</p>}
                      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 9, alignItems: "center" }}>
                        <button onClick={() => setBuying(e)}
                          style={{ fontFamily: "var(--font-body)", fontSize: 12, padding: "7px 14px", border: "1px solid var(--tmc-raspberry)", borderRadius: "var(--radius-sm)", color: "var(--tmc-raspberry)", background: "transparent", cursor: "pointer" }}>{fmt(e.time) || "Get tickets"}</button>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            ); })}
          </div>
          <div style={{ textAlign: "center", marginTop: 16, fontSize: 14, color: "var(--tmc-olive)" }}>Cancellations within 7 days are non-refundable — we're happy to issue a credit.</div>
        </div>
      </section>
      <InstagramFeed />
      <TmcFooter go={go} />
      {buying && <TicketModal url={buying.url} name={buying.name} onClose={() => setBuying(null)} />}
    </main>
  );
}

// Hidden pilot page (?page=ticketsdemo) — GHL native ticketed-event embed for
// client review. Test mode; deliberately unlisted (no nav, no sitemap).
function TicketsDemo() {
  React.useEffect(() => {
    const s = document.createElement("script");
    s.src = "https://link.msgsndr.com/js/form_embed.js";
    document.body.appendChild(s);
    return () => s.remove();
  }, []);
  return (
    <main>
      <section style={{ padding: "56px 20px 20px", textAlign: "center", background: "var(--tmc-cream)" }}>
        <div style={{ ...tmcEyebrow, color: "var(--tmc-raspberry)" }}>Pilot preview · test mode · not a live event</div>
        <h1 style={{ ...tmcDisplay, fontSize: 40, color: "var(--tmc-burgundy)", margin: "12px auto 8px", maxWidth: 700 }}>Ticketed events, on your website</h1>
        <p style={{ fontSize: 15.5, lineHeight: 1.6, maxWidth: 620, margin: "0 auto", color: "var(--text-body)" }}>
          This is GHL's new native ticketing embedded in the site — ticket tiers, quantities, and checkout, all without leaving the page.
          It's in test mode: click all the way through, nothing gets charged.
        </p>
      </section>
      <section style={{ padding: "10px 0 60px", background: "var(--tmc-cream)" }}>
        <div style={{ maxWidth: 1020, margin: "0 auto", background: "#FFFFFF", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lift)", overflow: "hidden" }}>
          <iframe
            src="https://events.leadconnectorhq.com/events/event-details/6aa84786dc92c1935b2f0d57"
            style={{ width: "100%", border: "none", minHeight: "88vh", display: "block" }}
            scrolling="no"
            id="6aa84786dc92c1935b2f0d57_demo"
            allow="payment *"
            title="Ticketed event pilot — Mahj & Mates"
          />
        </div>
      </section>
    </main>
  );
}

Object.assign(window, { Calendar, PrivateEvents, Shop, Contact, ScheduleView, ReturnPolicy, PrivacyPolicy, TicketsDemo, TicketSchedule });
