/* global React */
const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

/* ─────────────────────────────────────────────────────────────────
   Icons, minimal lucide-style strokes, 18px default.
   ───────────────────────────────────────────────────────────────── */
function Icon({ d, size = 18, fill, stroke = "currentColor", style, ...rest }) {
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill={fill || "none"}
      stroke={stroke}
      strokeWidth="1.5"
      strokeLinecap="round"
      strokeLinejoin="round"
      style={style}
      {...rest}
    >
      {typeof d === "string" ? <path d={d} /> : d}
    </svg>
  );
}
const ICONS = {
  search: "M21 21l-4.35-4.35M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z",
  bag: "M6 7h12l-1 13H7L6 7Zm3 0a3 3 0 0 1 6 0",
  user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-7 8a7 7 0 0 1 14 0",
  arrow: "M5 12h14M13 5l7 7-7 7",
  arrowL: "M19 12H5M11 19l-7-7 7-7",
  arrowUp: "M12 19V5M5 12l7-7 7 7",
  close: "M6 6l12 12M18 6L6 18",
  plus: "M12 5v14M5 12h14",
  minus: "M5 12h14",
  check: "M4 12l5 5L20 6",
  star: "M12 2l3 7h7l-5.6 4.5L18 21l-6-3.8L6 21l1.6-7.5L2 9h7l3-7Z",
  heart: "M12 21s-7-4.5-7-11a4 4 0 0 1 7-2 4 4 0 0 1 7 2c0 6.5-7 11-7 11Z",
  cal: "M3 6h18v15H3V6Zm5-3v6m8-6v6M3 11h18",
  clock: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0-13v5l3 2",
  cam: "M3 7h4l1.5-2h7L17 7h4v12H3V7Zm9 9a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z",
  film: "M4 3h16v18H4V3Zm0 5h16M4 16h16M8 3v18m8-18v18",
  monitor: "M4 4h16v12H4V4Zm6 16h4M8 20h8",
  pin: "M12 21s-7-7-7-12a7 7 0 1 1 14 0c0 5-7 12-7 12Zm0-9.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Z",
  mail: "M3 6h18v12H3V6Zm0 0l9 7 9-7",
  phone: "M5 4h4l2 5-3 2a11 11 0 0 0 5 5l2-3 5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2Z",
  google: "M22 12c0 5.5-4.5 10-10 10S2 17.5 2 12 6.5 2 12 2c2.7 0 5 1 6.8 2.6l-2.7 2.7A6 6 0 0 0 12 6a6 6 0 0 0-6 6 6 6 0 0 0 6 6 5.5 5.5 0 0 0 5.4-4H12v-4h10",
  apple: "M16.5 8.5c1.4-1.7 1.3-4 1.2-4.8-1.2.1-2.6.9-3.5 1.9-.8.9-1.4 2.2-1.2 3.4 1.3.1 2.6-.7 3.5-1.5ZM20 17.5a8 8 0 0 1-1.7 2.4c-.9.9-1.9 1.6-3.1 1.6-1.2 0-1.6-.7-3-.7-1.4 0-1.8.7-3 .7-1.2 0-2.1-.7-3-1.6C4 18 2.5 14 4.5 11a4.5 4.5 0 0 1 3.7-2.3c1.4 0 2.3.8 3.5.8 1.1 0 1.8-.8 3.4-.8 1.5 0 3 .8 3.7 2.2-3.3 1.8-2.7 6.5 1.2 6.6Z",
  filter: "M3 5h18M6 12h12M10 19h4",
  sliders: "M4 6h12m4 0h0M4 12h2m6 0h12M4 18h10m6 0h0M16 4v4M8 10v4M14 16v4",
  chev: "M9 6l6 6-6 6",
  chevD: "M6 9l6 6 6-6",
  chevU: "M6 15l6-6 6 6",
  ext: "M14 5h5v5M19 5l-9 9M9 5H5v14h14v-4",
  spark: "M12 2v6M12 16v6M2 12h6M16 12h6M5 5l4 4M15 15l4 4M19 5l-4 4M9 15l-4 4",
  play: "M6 4l14 8-14 8V4Z",
  trash: "M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14",
  send: "M22 2L11 13M22 2l-7 20-4-9-9-4 20-7Z",
  msg: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10Z",
};

function I({ name, size = 18, ...rest }) {
  return <Icon d={ICONS[name]} size={size} {...rest} />;
}

/* ─────────────────────────────────────────────────────────────────
   Striped placeholder image, variants: 'warm' | 'cool' | 'deep'
   ───────────────────────────────────────────────────────────────── */
function Placeholder({ label = "image", variant = "warm", code, style, className = "", src, video, poster, fit = "cover", focal }) {
  if (video) {
    return (
      <div className={`ph ${variant} ph-media ${className}`} style={style}>
        <video
          className="ph-video"
          src={video}
          poster={poster}
          autoPlay
          muted
          loop
          playsInline
          preload="metadata"
          style={{ objectFit: fit, objectPosition: focal || "center" }}
        />
        {code && <span className="ph-corner">{code}</span>}
      </div>
    );
  }
  if (src) {
    return (
      <div className={`ph ${variant} ph-media ${className}`} style={style}>
        <img
          className="ph-img"
          src={src}
          alt={label}
          loading="lazy"
          style={{ objectFit: fit, objectPosition: focal || "center" }}
        />
        {code && <span className="ph-corner">{code}</span>}
      </div>
    );
  }
  return (
    <div className={`ph ${variant} ${className}`} style={style}>
      <span className="ph-label">{label}</span>
      {code && <span className="ph-corner">{code}</span>}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────
   Untitled.stream embedded player.
   Pass a track / album ID; renders an iframe matching Untitled's
   recommended embed.  Returns null if no id is supplied so callers
   can use it as a drop-in fallback.
   ───────────────────────────────────────────────────────────────── */
function UntitledEmbed({ id, height = 344, radius = 12, style }) {
  if (!id) return null;
  return (
    <iframe
      src={`https://untitled.stream/embed/${id}`}
      width="100%"
      height={height}
      title={`Untitled.stream player ${id}`}
      style={{ border: 0, borderRadius: radius, display: "block", background: "#0a0a0a", ...style }}
      allow="picture-in-picture"
      allowFullScreen
      loading="lazy"
    />
  );
}

/* ─────────────────────────────────────────────────────────────────
   Logo, uses the provided PNG, zoomed to the centered monogram.
   ───────────────────────────────────────────────────────────────── */
function Logo({ size = 32 }) {
  return (
    <span
      className="brand-mark"
      style={{
        width: size,
        height: size,
        display: "inline-block",
      }}
      aria-label="Eleven Views"
    />
  );
}

/* ─────────────────────────────────────────────────────────────────
   Toast helper, minimal, single global toast.
   ───────────────────────────────────────────────────────────────── */
const ToastCtx = createContext(null);
function ToastProvider({ children }) {
  const [t, setT] = useState(null);
  const tref = useRef(null);
  const show = useCallback((message) => {
    setT({ message, id: Date.now() });
    clearTimeout(tref.current);
    tref.current = setTimeout(() => setT(null), 2400);
  }, []);
  return (
    <ToastCtx.Provider value={show}>
      {children}
      {t && (
        <div className="toast" key={t.id}>
          <span className="dot" />
          {t.message}
        </div>
      )}
    </ToastCtx.Provider>
  );
}
function useToast() { return useContext(ToastCtx); }

/* ─────────────────────────────────────────────────────────────────
   Cart store (in-memory).
   ───────────────────────────────────────────────────────────────── */
const CartCtx = createContext(null);
function CartProvider({ children }) {
  const [items, setItems] = useState([]); // { id, name, variant, price, qty, kind }
  const [open, setOpen] = useState(false);
  const add = useCallback((it) => {
    setItems((prev) => {
      const ex = prev.find((p) => p.id === it.id && p.variant === it.variant);
      if (ex) return prev.map((p) => p === ex ? { ...p, qty: p.qty + (it.qty || 1) } : p);
      return [...prev, { ...it, qty: it.qty || 1 }];
    });
  }, []);
  const remove = useCallback((id, variant) => {
    setItems((prev) => prev.filter((p) => !(p.id === id && p.variant === variant)));
  }, []);
  const setQty = useCallback((id, variant, qty) => {
    setItems((prev) =>
      qty <= 0
        ? prev.filter((p) => !(p.id === id && p.variant === variant))
        : prev.map((p) => (p.id === id && p.variant === variant ? { ...p, qty } : p))
    );
  }, []);
  const subtotal = items.reduce((s, x) => s + x.price * x.qty, 0);
  const count = items.reduce((s, x) => s + x.qty, 0);
  return (
    <CartCtx.Provider value={{ items, add, remove, setQty, subtotal, count, open, setOpen }}>
      {children}
    </CartCtx.Provider>
  );
}
function useCart() { return useContext(CartCtx); }

/* ─────────────────────────────────────────────────────────────────
   Router, page string state + scroll-to-top on change.
   ───────────────────────────────────────────────────────────────── */
/* ── URL routing ───────────────────────────────────────────────────
   The site reads the URL on load AND pushes to history on every goto(),
   so reloading any page stays put and individual page links can be shared.

   Single-segment routes map directly. Two-segment routes carry one
   parameter (id / key). Examples:
     /                          → home
     /studio                    → about
     /services                  → services
     /services/photography      → service           {key: "photography"}
     /work                      → work
     /work/yolanda-rivera-look  → project           {id: "yolanda-rivera-look"}
     /store                     → store
     /store/ev-001              → pdp               {id: "ev-001"}
     /intelligence              → intelligence
     /intelligence/playa        → intelligence-detail {key: "playa"}
   ───────────────────────────────────────────────────────────────── */

// segment-1 → route name
const PATH_ROUTES = {
  "":              "home",
  "home":          "home",
  "work":          "work",
  "services":      "services",
  "service":       "services",
  "intelligence":  "intelligence",
  "panel":         "panel",
  "membership":    "membership",
  "join":          "membership",
  "atelier":       "atelier",
  "boost":         "panel",
  "store":         "store",
  "shop":          "store",
  "booking":       "booking",
  "book":          "booking",
  "studio":        "about",
  "about":         "about",
  "contact":       "contact",
  "press":         "press",
  "journal":       "journal",
  "faq":           "faq",
  "shipping":      "shipping",
  "privacy":       "privacy",
  "terms":         "terms",
  "accessibility": "accessibility",
  "sitemap":       "sitemap",
  "login":         "login",
  "checkout":      "checkout",
  "desk":          "desk",
  "portal":        "portal",
};

// route name → URL builder (returns a path string, /-prefixed, no trailing slash)
function pathFromRoute(name, params = {}) {
  const sub = params || {};
  switch (name) {
    case "home":                 return "/";
    case "about":                return "/studio";
    case "service":              return sub.key ? `/services/${sub.key}` : "/services";
    case "project":              return sub.id  ? `/work/${sub.id}`      : "/work";
    case "pdp":                  return sub.id  ? `/store/${sub.id}`     : "/store";
    case "intelligence-detail":  return sub.key ? `/intelligence/${sub.key}` : "/intelligence";
    case "work":
    case "services":
    case "intelligence":
    case "store":
    case "booking":
    case "contact":
    case "press":
    case "journal":
    case "faq":
    case "shipping":
    case "privacy":
    case "terms":
    case "accessibility":
    case "sitemap":
    case "login":
    case "checkout":
    case "desk":
    case "panel":
    case "membership":
    case "atelier":
      return `/${name}`;
    case "portal":               return "/portal";
    default:                     return "/";
  }
}

function routeFromPath() {
  const host = (window.location.hostname || "").toLowerCase();
  const segs = (window.location.pathname || "/").split("/").filter(Boolean);
  const a = (segs[0] || "").toLowerCase();
  const b = segs[1];
  if (host.startsWith("sell.") && (!a || a === "desk")) {
    return { name: "desk", params: {} };
  }
  // Two-segment paths
  if (a === "services" && b)     return { name: "service",             params: { key: b } };
  if (a === "service"  && b)     return { name: "service",             params: { key: b } };
  if (a === "work" && b)         return { name: "project",             params: { id: b } };
  if (a === "store" && b)        return { name: "pdp",                 params: { id: b } };
  if (a === "intelligence" && b) return { name: "intelligence-detail", params: { key: b } };
  // One-segment paths
  return { name: PATH_ROUTES[a] || "home", params: {} };
}

const RouteCtx = createContext(null);
function RouteProvider({ children }) {
  const [route, setRoute] = useState(() => routeFromPath());
  const goto = useCallback((name, params = {}) => {
    const path = pathFromRoute(name, params);
    // Update URL only if it's actually changing — avoids spamming history with dupes
    if (path !== window.location.pathname + window.location.search) {
      try { window.history.pushState({ name, params }, "", path); } catch (_) {}
    }
    setRoute({ name, params });
    requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: "instant" }));
  }, []);
  // Re-sync if user uses browser back / forward
  useEffect(() => {
    const handler = () => setRoute(routeFromPath());
    window.addEventListener("popstate", handler);
    return () => window.removeEventListener("popstate", handler);
  }, []);
  return <RouteCtx.Provider value={{ route, goto }}>{children}</RouteCtx.Provider>;
}
function useRoute() { return useContext(RouteCtx); }

/* ─────────────────────────────────────────────────────────────────
   Header, full top nav + mega-nav for Services & Work + mobile drawer
   ───────────────────────────────────────────────────────────────── */
function Header() {
  const { route, goto } = useRoute();
  const { count, setOpen: setCartOpen } = useCart();
  const toast = useToast();
  const [mega, setMega] = useState(null); // 'services' | 'work' | null
  const [mobile, setMobile] = useState(false);
  const navRef = useRef(null);

  // close mega-nav on outside click
  useEffect(() => {
    function onClick(e) { if (navRef.current && !navRef.current.contains(e.target)) setMega(null); }
    function onKey(e) { if (e.key === "Escape") { setMega(null); setMobile(false); } }
    document.addEventListener("click", onClick);
    document.addEventListener("keydown", onKey);
    return () => { document.removeEventListener("click", onClick); document.removeEventListener("keydown", onKey); };
  }, []);

  // close mobile when route changes
  useEffect(() => { setMobile(false); setMega(null); }, [route.name, route.params]);

  const isActive = (k) => {
    if (k === route.name) return true;
    if (k === "services" && route.name === "service") return true;
    if (k === "work" && route.name === "project") return true;
    return false;
  };

  function go(name, params) { setMega(null); setMobile(false); goto(name, params); }

  function onTrigger(key, hasMega) {
    if (hasMega) {
      setMega(prev => prev === key ? null : key);
    } else {
      go(key === "book" ? "booking" : key);
    }
  }

  return (
    <>
      <header className="hdr">
        <div className="container hdr-row">
          <div onClick={() => go("home")} className="brand" style={{ cursor: "pointer" }}>
            <Logo size={28} />
            <span style={{ fontFamily: "var(--serif)", fontSize: 17, lineHeight: 1 }}>Eleven Views</span>
          </div>
          <nav className="nav nav-desktop" ref={navRef}>
            {window.NAV.map((n) => {
              const hasMega = n.key === "services" || n.key === "work";
              return (
                <a key={n.key}
                  data-active={isActive(n.key)}
                  data-open={mega === n.key ? "true" : undefined}
                  onClick={(e) => { e.stopPropagation(); onTrigger(n.key, hasMega); }}>
                  {n.label}
                  {hasMega && <I name="chevD" size={11} className="nav-chev" data-open={mega === n.key ? "true" : undefined} style={{ marginLeft: 4, opacity: 0.55 }} />}
                </a>
              );
            })}

            {/* MEGA NAV. Services */}
            {mega === "services" && (
              <div className="mega">
                <div className="container mega-grid">
                  <div className="mega-col">
                    <span className="eyebrow eyebrow-gold">§ Services</span>
                    <p className="serif" style={{ fontSize: 24, lineHeight: 1.2, margin: "12px 0 16px" }}>
                      Image, film, and web, one team, no handoffs.
                    </p>
                    <p style={{ color: "var(--text-2)", fontSize: 13, lineHeight: 1.6, margin: "0 0 18px" }}>
                      Three disciplines, one team. Founded 2021. Booking briefs continuously.
                    </p>
                    <a className="lk" style={{ fontSize: 13, cursor: "pointer" }} onClick={() => go("services")}>All services →</a>
                  </div>
                  {Object.values(window.SERVICES).map((s) => (
                    <div key={s.key} className="mega-col mega-tile" onClick={() => go("service", { key: s.key })}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                        <I name={s.icon} size={20} stroke="var(--gold)" />
                        <I name="arrow" size={14} stroke="var(--text-3)" className="mega-arrow" />
                      </div>
                      <h4 className="serif" style={{ fontSize: 22, margin: "0 0 6px" }}>{s.name}</h4>
                      <p style={{ color: "var(--text-2)", fontSize: 12.5, margin: "0 0 14px", lineHeight: 1.5 }}>{s.tagline}</p>
                      <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 6 }}>
                        {s.descriptors.map((d) => (
                          <li key={d} style={{ fontSize: 12, color: "var(--text-1)", display: "flex", gap: 8, alignItems: "center" }}>
                            <span style={{ width: 4, height: 4, borderRadius: "50%", background: "var(--gold)" }} />
                            {d}
                          </li>
                        ))}
                      </ul>
                    </div>
                  ))}
                </div>
                <div className="mega-foot">
                  <span className="mono" style={{ fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", color: "var(--text-3)" }}>
                    Booking briefs continuously · founded 2021
                  </span>
                  <button className="btn btn-gold btn-sm" onClick={() => go("booking")}>Start a project <I name="arrow" size={12} /></button>
                </div>
              </div>
            )}

            {/* MEGA NAV. Work */}
            {mega === "work" && (
              <div className="mega">
                <div className="container mega-grid mega-grid-work">
                  <div className="mega-col">
                    <span className="eyebrow eyebrow-gold">§ Selected Work</span>
                    <p className="serif" style={{ fontSize: 24, lineHeight: 1.2, margin: "12px 0 16px" }}>
                      The case studies behind the practice.
                    </p>
                    <ul style={{ listStyle: "none", padding: 0, margin: "12px 0 18px", display: "flex", flexDirection: "column", gap: 8 }}>
                      {window.WORK_FILTERS.filter(f => f.key !== "all").map((f) => (
                        <li key={f.key}>
                          <a className="lk" style={{ fontSize: 13, cursor: "pointer" }} onClick={() => go("work", { filter: f.key })}>{f.label}</a>
                        </li>
                      ))}
                    </ul>
                    <a className="lk" style={{ fontSize: 13, cursor: "pointer" }} onClick={() => go("work")}>All projects →</a>
                  </div>
                  {window.WORK.slice(0, 3).map((p) => (
                    <div key={p.id} className="mega-col mega-tile" onClick={() => go("project", { id: p.id })}>
                      <Placeholder
                        label={p.title.toLowerCase()}
                        variant={p.cover.v}
                        code={p.cover.code}
                        src={p.cover.image}
                        video={p.cover.video}
                        poster={p.cover.poster}
                        focal={p.cover.focal || "center"}
                        fit="contain"
                        style={{ aspectRatio: "5/4", marginBottom: 14 }} />
                      <div className="mono" style={{ fontSize: 9.5, letterSpacing: "0.14em", color: "var(--text-3)", textTransform: "uppercase", marginBottom: 6 }}>
                        {p.client} · {p.year}
                      </div>
                      <h4 className="serif" style={{ fontSize: 18, margin: 0 }}>{p.title}</h4>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </nav>
          <div className="hdr-actions">
            <button className="icon-btn" title="Search" aria-label="Search" onClick={() => { toast("Search · coming soon"); }}>
              <I name="search" size={17} />
            </button>
            <button className="icon-btn" title="Account" aria-label="Account" onClick={() => go("login")}>
              <I name="user" size={17} />
            </button>
            <button className="icon-btn" title="Cart" aria-label="Cart" onClick={() => setCartOpen(true)} style={{ position: "relative" }}>
              <I name="bag" size={17} />
              {count > 0 && <span className="cart-count">{count}</span>}
            </button>
            <button className="icon-btn icon-btn-mobile" aria-label="Menu" onClick={() => setMobile(true)}>
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><path d="M2 5h14M2 9h14M2 13h14"/></svg>
            </button>
          </div>
        </div>
      </header>

      {/* MOBILE DRAWER */}
      {mobile && (
        <>
          <div className="sheet-bg" onClick={() => setMobile(false)} />
          <aside className="sheet" role="dialog" aria-label="Menu">
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 22px", borderBottom: "1px solid var(--border)" }}>
              <div className="brand">
                <Logo size={26} />
                <span style={{ fontFamily: "var(--serif)", fontSize: 16 }}>Eleven Views</span>
              </div>
              <button className="icon-btn" onClick={() => setMobile(false)} aria-label="Close"><I name="close" size={18} /></button>
            </div>
            <nav style={{ flex: 1, overflowY: "auto", padding: "8px 22px 28px" }}>
              {window.NAV.map((n) => (
                <button key={n.key} onClick={() => go(n.key === "book" ? "booking" : n.key)}
                  style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%", padding: "18px 0", borderBottom: "1px solid var(--border-1)", background: "transparent", border: 0, color: isActive(n.key) ? "var(--gold)" : "var(--text)", fontFamily: "var(--serif)", fontSize: 24, cursor: "pointer", textAlign: "left" }}>
                  {n.label} <I name="arrow" size={16} />
                </button>
              ))}
              <div style={{ marginTop: 28 }}>
                <span className="eyebrow">Utility</span>
                <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 12 }}>
                  {[["faq", "FAQ"], ["shipping", "Shipping & Returns"], ["privacy", "Privacy"], ["terms", "Terms"]].map(([k, l]) => (
                    <a key={k} className="lk" style={{ fontSize: 13, cursor: "pointer" }} onClick={() => go(k)}>{l}</a>
                  ))}
                </div>
              </div>
              <button className="btn btn-gold btn-lg" style={{ marginTop: 32, width: "100%" }} onClick={() => go("booking")}>
                Start a project <I name="arrow" size={16} />
              </button>
            </nav>
          </aside>
        </>
      )}
    </>
  );
}

/* ─────────────────────────────────────────────────────────────────
   Footer, newsletter, IA, locations, legal
   ───────────────────────────────────────────────────────────────── */
function Footer() {
  const { goto } = useRoute();
  const [email, setEmail] = useState("");
  const [subbed, setSubbed] = useState(false);
  const toast = useToast();

  function subscribe(e) {
    e.preventDefault();
    if (!/^[^@]+@[^@]+\.[^@]+$/.test(email)) { toast("Enter a valid email"); return; }
    setSubbed(true);
    toast("You're on the list, thank you.");
  }

  return (
    <footer className="foot">
      {/* Newsletter band */}
      <div className="foot-news">
        <div className="container foot-news-row">
          <div>
            <span className="eyebrow eyebrow-gold">§ Letters from the studio</span>
            <h3 className="serif" style={{ fontSize: "clamp(28px, 3.4vw, 44px)", lineHeight: 1.05, margin: "10px 0 6px", letterSpacing: "-0.01em" }}>
              Eleven Views, in your inbox.
            </h3>
            <p style={{ color: "var(--text-2)", fontSize: 14, lineHeight: 1.6, margin: 0, maxWidth: 460 }}>
              Quiet correspondence, new work, studio openings, occasional essays.
              No tracking, no selling, unsubscribe in one click.
            </p>
          </div>
          {!subbed ? (
            <form className="foot-news-form" onSubmit={subscribe}>
              <input
                type="email"
                placeholder="you@studio.com"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                aria-label="Email address"
              />
              <button className="btn btn-gold" type="submit">Subscribe <I name="arrow" size={14} /></button>
            </form>
          ) : (
            <div className="foot-news-confirm">
              <I name="check" size={16} stroke="var(--gold)" />
              <span style={{ fontSize: 13.5 }}>Confirmation sent to <strong>{email}</strong></span>
            </div>
          )}
        </div>
      </div>

      <div className="container">
        <div className="foot-grid">
          <div className="foot-col foot-brand-col">
            <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
              <Logo size={36} />
              <span className="serif" style={{ fontSize: 22 }}>Eleven Views</span>
            </div>
            <p className="pretty" style={{ color: "var(--text-2)", maxWidth: 320, fontSize: 13.5, lineHeight: 1.65, margin: "0 0 24px" }}>
              A boutique creative studio for image, film, and craft. Founded 2021. We make work meant to last.
            </p>
            <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 24 }}>
              <div style={{ display: "flex", gap: 10, alignItems: "center", color: "var(--text-2)", fontSize: 12.5 }}>
                <I name="pin" size={13} stroke="var(--text-3)" /> Remote studio · travels for the shoot
              </div>
              <div style={{ display: "flex", gap: 10, alignItems: "center", color: "var(--text-2)", fontSize: 12.5 }}>
                <I name="mail" size={13} stroke="var(--text-3)" /> support@elevenviews.io
              </div>
              <div style={{ display: "flex", gap: 10, alignItems: "center", color: "var(--text-2)", fontSize: 12.5 }}>
                <I name="mail" size={13} stroke="var(--text-3)" /> press@elevenviews.io
              </div>
            </div>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
              {["Instagram", "Vimeo", "Bandcamp", "Are.na", "LinkedIn"].map((s) => (
                <a key={s} className="social-chip" href="#">{s} <I name="arrow" size={10} /></a>
              ))}
            </div>
          </div>

          <div className="foot-col">
            <h4>Studio</h4>
            <ul>
              <li><a onClick={() => goto("about")}>About</a></li>
              <li><a onClick={() => goto("about", { section: "process" })}>Process</a></li>
              <li><a onClick={() => goto("about", { section: "people" })}>The eleven</a></li>
              <li><a onClick={() => goto("contact")}>Contact</a></li>
              <li><a onClick={() => goto("press")}>Press</a></li>
              <li><a onClick={() => goto("journal")}>Journal</a></li>
            </ul>
          </div>

          <div className="foot-col">
            <h4>Services</h4>
            <ul>
              {Object.values(window.SERVICES).map((s) => (
                <li key={s.key}><a onClick={() => goto("service", { key: s.key })}>{s.name}</a></li>
              ))}
              <li><a onClick={() => goto("services")}>Pricing & timelines</a></li>
              <li><a onClick={() => goto("booking")}>Start a project</a></li>
              <li><a onClick={() => goto("desk")}>Eleven Views Desk</a></li>
            </ul>
          </div>

          <div className="foot-col">
            <h4>Work</h4>
            <ul>
              {window.WORK_FILTERS.filter(f => f.key !== "all").map((f) => (
                <li key={f.key}><a onClick={() => goto("work", { filter: f.key })}>{f.label}</a></li>
              ))}
              <li><a onClick={() => goto("work")}>All projects</a></li>
            </ul>
          </div>

          <div className="foot-col">
            <h4>Store</h4>
            <ul>
              <li><a onClick={() => goto("store", { cat: "apparel" })}>Apparel</a></li>
              <li><a onClick={() => goto("store", { cat: "accessories" })}>Accessories</a></li>
              <li><a onClick={() => goto("store", { cat: "music" })}>Music</a></li>
              <li><a onClick={() => goto("store", { cat: "objects" })}>Objects</a></li>
              <li><a onClick={() => goto("shipping")}>Shipping & returns</a></li>
              <li><a onClick={() => goto("faq")}>FAQ</a></li>
            </ul>
          </div>
        </div>

        <hr className="rule" style={{ margin: "56px 0 22px" }} />

        <div className="foot-bottom">
          <p className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--text-3)", textTransform: "uppercase", margin: 0 }}>
            © 2026 Eleven Views Studio · A remote studio · Made slowly
          </p>
          <div style={{ display: "flex", gap: 18, flexWrap: "wrap" }}>
            <a className="lk lk-mute" onClick={() => goto("privacy")}>Privacy</a>
            <a className="lk lk-mute" onClick={() => goto("terms")}>Terms</a>
            <a className="lk lk-mute" onClick={() => goto("accessibility")}>Accessibility</a>
            <a className="lk lk-mute" onClick={() => goto("sitemap")}>Sitemap</a>
          </div>
          <p className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--text-3)", textTransform: "uppercase", margin: 0 }}>
            v.11 · MMXXVI
          </p>
        </div>
      </div>
    </footer>
  );
}

/* ─────────────────────────────────────────────────────────────────
   Cart drawer (mounted globally)
   ───────────────────────────────────────────────────────────────── */
function CartDrawer() {
  const { items, setQty, remove, subtotal, open, setOpen } = useCart();
  const { goto } = useRoute();
  if (!open) return null;
  return (
    <>
      <div className="sheet-bg" onClick={() => setOpen(false)} />
      <aside className="sheet" role="dialog" aria-label="Cart">
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 22px", borderBottom: "1px solid var(--border)" }}>
          <div>
            <p className="eyebrow" style={{ marginBottom: 4 }}>Bag</p>
            <p className="serif" style={{ fontSize: 22, margin: 0 }}>{items.length} {items.length === 1 ? "piece" : "pieces"}</p>
          </div>
          <button className="icon-btn" onClick={() => setOpen(false)} aria-label="Close">
            <I name="close" size={18} />
          </button>
        </div>
        <div style={{ flex: 1, overflowY: "auto", padding: "8px 22px" }}>
          {items.length === 0 && (
            <div style={{ padding: "80px 0", textAlign: "center" }}>
              <div style={{ fontFamily: "var(--serif)", fontSize: 22, marginBottom: 8 }}>Your bag is empty.</div>
              <div style={{ color: "var(--text-2)", fontSize: 13.5, maxWidth: 280, margin: "0 auto 24px" }}>
                Studio editions, music, and objects, find something that holds the room.
              </div>
              <button className="btn btn-line" onClick={() => { setOpen(false); goto("store"); }}>Open the store</button>
            </div>
          )}
          {items.map((it) => (
            <div key={`${it.id}-${it.variant}`} style={{ display: "flex", gap: 14, padding: "16px 0", borderBottom: "1px solid var(--border-1)" }}>
              <div style={{ width: 78, height: 96, flexShrink: 0 }}>
                <Placeholder label={it.kind === "music" ? "cover" : "shot"} variant={it.variant === "Black" ? "deep" : "warm"} />
              </div>
              <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "space-between" }}>
                <div>
                  <div className="serif" style={{ fontSize: 16 }}>{it.name}</div>
                  <div className="mono" style={{ fontSize: 10, letterSpacing: "0.1em", color: "var(--text-3)", textTransform: "uppercase", marginTop: 2 }}>
                    {it.variant}
                  </div>
                </div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                  <div style={{ display: "flex", alignItems: "center", border: "1px solid var(--border)", borderRadius: 999 }}>
                    <button className="icon-btn" onClick={() => setQty(it.id, it.variant, it.qty - 1)} style={{ width: 28, height: 28 }}><I name="minus" size={14} /></button>
                    <span className="mono" style={{ fontSize: 12, minWidth: 22, textAlign: "center" }}>{it.qty}</span>
                    <button className="icon-btn" onClick={() => setQty(it.id, it.variant, it.qty + 1)} style={{ width: 28, height: 28 }}><I name="plus" size={14} /></button>
                  </div>
                  <span className="mono" style={{ fontSize: 13 }}>${(it.price * it.qty).toFixed(0)}</span>
                </div>
              </div>
              <button className="icon-btn" onClick={() => remove(it.id, it.variant)} aria-label="Remove" style={{ alignSelf: "start" }}>
                <I name="close" size={14} />
              </button>
            </div>
          ))}
        </div>
        {items.length > 0 && (
          <div style={{ padding: "20px 22px", borderTop: "1px solid var(--border)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6 }}>
              <span className="eyebrow">Subtotal</span>
              <span className="mono" style={{ fontSize: 14 }}>${subtotal.toFixed(0)}</span>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", color: "var(--text-3)", fontSize: 12, marginBottom: 16 }}>
              <span>Shipping & tax</span><span className="mono">Calculated at checkout</span>
            </div>
            <button className="btn btn-gold btn-lg" style={{ width: "100%" }} onClick={() => { setOpen(false); goto("checkout"); }}>
              Checkout · ${subtotal.toFixed(0)} <I name="arrow" size={16} />
            </button>
            <button className="btn btn-ghost btn-sm" style={{ width: "100%", marginTop: 8 }} onClick={() => setOpen(false)}>Keep browsing</button>
          </div>
        )}
      </aside>
    </>
  );
}

/* ─────────────────────────────────────────────────────────────────
   VideoPlayer. Eleven Views branded film frame.
   Click frame to toggle. Bottom transport reveals on hover, with
   scrubber, mute, and fullscreen. Corner stamp + footer caption.
   ───────────────────────────────────────────────────────────────── */
function fmtTime(s) {
  if (!s || !isFinite(s)) return "00:00";
  const m = Math.floor(s / 60);
  const r = Math.floor(s % 60);
  return `${String(m).padStart(2, "0")}:${String(r).padStart(2, "0")}`;
}

function VideoPlayer({ src, poster, code, title, runtime, variant = "warm", aspect = "16/9", muted: mutedDefault = true, autoPlay = false, loop = false }) {
  const ref = useRef(null);
  const wrapRef = useRef(null);
  const [playing, setPlaying] = useState(false);
  const [muted, setMuted] = useState(mutedDefault);
  const [time, setTime] = useState(0);
  const [dur, setDur] = useState(0);
  const [hover, setHover] = useState(false);

  useEffect(() => {
    const v = ref.current; if (!v) return;
    const onTime = () => setTime(v.currentTime);
    const onMeta = () => setDur(v.duration || 0);
    const onPlay = () => setPlaying(true);
    const onPause = () => setPlaying(false);
    v.addEventListener("timeupdate", onTime);
    v.addEventListener("loadedmetadata", onMeta);
    v.addEventListener("play", onPlay);
    v.addEventListener("pause", onPause);
    return () => {
      v.removeEventListener("timeupdate", onTime);
      v.removeEventListener("loadedmetadata", onMeta);
      v.removeEventListener("play", onPlay);
      v.removeEventListener("pause", onPause);
    };
  }, []);

  function toggle(e) {
    if (e) e.stopPropagation();
    const v = ref.current; if (!v) return;
    if (v.paused) { v.muted = muted; v.play().catch(() => {}); }
    else v.pause();
  }
  function toggleMute(e) {
    e.stopPropagation();
    const v = ref.current; if (!v) return;
    v.muted = !v.muted; setMuted(v.muted);
  }
  function seek(e) {
    e.stopPropagation();
    const v = ref.current; const r = e.currentTarget.getBoundingClientRect();
    const pct = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
    if (v && v.duration) v.currentTime = pct * v.duration;
  }
  function fullscreen(e) {
    e.stopPropagation();
    const w = wrapRef.current; if (!w) return;
    if (!document.fullscreenElement) w.requestFullscreen?.();
    else document.exitFullscreen?.();
  }
  const pct = dur ? (time / dur) * 100 : 0;

  return (
    <div className={`ev-vplayer ph ${variant}`}
         ref={wrapRef}
         style={{ aspectRatio: aspect, position: "relative", overflow: "hidden", cursor: "pointer" }}
         onMouseEnter={() => setHover(true)}
         onMouseLeave={() => setHover(false)}
         onClick={toggle}>
      <video
        ref={ref}
        src={src}
        poster={poster}
        muted={muted}
        autoPlay={autoPlay}
        loop={loop}
        playsInline
        preload="metadata"
        className="ev-vplayer-video"
      />
      <div className="ev-vplayer-stamp"><span className="mono">⌘ {code || "EV-FILM"}</span></div>
      {!playing && (
        <button className="ev-vplayer-cta" onClick={toggle} aria-label="Play">
          <I name="play" size={22} />
        </button>
      )}
      <div className="ev-vplayer-bar" data-show={(!playing || hover) ? "true" : "false"}>
        <button className="ev-vplayer-btn" onClick={toggle} aria-label={playing ? "Pause" : "Play"}>
          {playing
            ? <svg width="12" height="12" viewBox="0 0 12 12"><rect x="2" y="2" width="2.5" height="8" fill="currentColor"/><rect x="7.5" y="2" width="2.5" height="8" fill="currentColor"/></svg>
            : <I name="play" size={12} />}
        </button>
        <span className="ev-vplayer-time mono">{fmtTime(time)}</span>
        <div className="ev-vplayer-track" onClick={seek}>
          <div className="ev-vplayer-fill" style={{ width: `${pct}%` }} />
          <div className="ev-vplayer-knob" style={{ left: `${pct}%` }} />
        </div>
        <span className="ev-vplayer-time mono">{fmtTime(dur)}</span>
        <button className="ev-vplayer-btn" onClick={toggleMute} aria-label={muted ? "Unmute" : "Mute"}>
          {muted
            ? <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"><path d="M2 6h3l4-3v10L5 10H2z"/><path d="M11 6l4 4M15 6l-4 4"/></svg>
            : <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"><path d="M2 6h3l4-3v10L5 10H2z"/><path d="M12 5a4 4 0 0 1 0 6"/></svg>}
        </button>
        <button className="ev-vplayer-btn" onClick={fullscreen} aria-label="Fullscreen">
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"><path d="M1 4V1h3M11 4V1H8M1 8v3h3M11 8v3H8"/></svg>
        </button>
      </div>
      {(title || runtime) && (
        <div className="ev-vplayer-caption">
          {runtime && <span className="mono">{runtime}</span>}
          {title && <span className="serif">{title}</span>}
        </div>
      )}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────
   MusicPlayer. Eleven Views LP frame with playlist, scrubber, transport.
   ───────────────────────────────────────────────────────────────── */
function MusicPlayer({ src, title, subtitle, code, variant = "deep", tracks }) {
  const ref = useRef(null);
  const list = (tracks && tracks.length) ? tracks : (src ? [{ src, title }] : []);
  const [playing, setPlaying] = useState(false);
  const [time, setTime] = useState(0);
  const [dur, setDur] = useState(0);
  const [trackIdx, setTrackIdx] = useState(0);
  const cur = list[trackIdx] || { title };

  useEffect(() => {
    const a = ref.current; if (!a) return;
    setTime(0); setDur(0);
    const onTime = () => setTime(a.currentTime);
    const onMeta = () => setDur(a.duration || 0);
    const onPlay = () => setPlaying(true);
    const onPause = () => setPlaying(false);
    const onEnd = () => {
      if (trackIdx < list.length - 1) {
        setTrackIdx(trackIdx + 1);
      } else {
        setPlaying(false);
      }
    };
    a.addEventListener("timeupdate", onTime);
    a.addEventListener("loadedmetadata", onMeta);
    a.addEventListener("play", onPlay);
    a.addEventListener("pause", onPause);
    a.addEventListener("ended", onEnd);
    return () => {
      a.removeEventListener("timeupdate", onTime);
      a.removeEventListener("loadedmetadata", onMeta);
      a.removeEventListener("play", onPlay);
      a.removeEventListener("pause", onPause);
      a.removeEventListener("ended", onEnd);
    };
    // eslint-disable-next-line
  }, [trackIdx]);

  // when track changes during playback, auto-resume
  useEffect(() => {
    const a = ref.current; if (!a) return;
    if (playing) { a.play().catch(() => {}); }
    // eslint-disable-next-line
  }, [trackIdx]);

  function toggle() {
    const a = ref.current; if (!a) return;
    if (a.paused) a.play().catch(() => {}); else a.pause();
  }
  function seek(e) {
    const a = ref.current; if (!a) return;
    const r = e.currentTarget.getBoundingClientRect();
    const pct = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
    if (a.duration) a.currentTime = pct * a.duration;
  }
  function next() {
    if (trackIdx < list.length - 1) setTrackIdx(trackIdx + 1);
  }
  function prev() {
    const a = ref.current;
    if (a && a.currentTime > 2) { a.currentTime = 0; return; }
    if (trackIdx > 0) setTrackIdx(trackIdx - 1);
  }
  const pct = dur ? (time / dur) * 100 : 0;

  return (
    <div className={`ev-mplayer ${variant}`}>
      <audio ref={ref} src={cur?.src} preload="metadata" />
      <div className="ev-mplayer-art">
        <Placeholder label={(title || "music").toLowerCase()} variant={variant} code={code} style={{ aspectRatio: "1/1", width: "100%" }} />
        <div className="ev-mplayer-stamp mono">⌘ EV · LP</div>
        <button className={`ev-mplayer-overlay ${playing ? "is-playing" : ""}`} onClick={toggle} aria-label={playing ? "Pause" : "Play"}>
          {playing
            ? <svg width="22" height="22" viewBox="0 0 16 16" fill="currentColor"><rect x="3" y="3" width="3.5" height="10"/><rect x="9.5" y="3" width="3.5" height="10"/></svg>
            : <I name="play" size={22} />}
        </button>
      </div>
      <div className="ev-mplayer-body">
        <span className="eyebrow eyebrow-gold">§ Now playing</span>
        <h4 className="serif ev-mplayer-title">{cur?.title || title}</h4>
        <p className="ev-mplayer-sub mono">
          {subtitle}{list.length > 1 && ` · Track ${String(trackIdx + 1).padStart(2, "0")} / ${String(list.length).padStart(2, "0")}`}
        </p>
        <div className="ev-mplayer-track" onClick={seek}>
          <div className="ev-mplayer-fill" style={{ width: `${pct}%` }} />
          <div className="ev-mplayer-knob" style={{ left: `${pct}%` }} />
        </div>
        <div className="ev-mplayer-times mono"><span>{fmtTime(time)}</span><span>{fmtTime(dur)}</span></div>
        <div className="ev-mplayer-controls">
          <button className="ev-mplayer-btn" onClick={prev} aria-label="Previous">
            <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor"><rect x="2" y="2" width="2" height="10"/><path d="M5 7l7-5v10z"/></svg>
          </button>
          <button className="ev-mplayer-play" onClick={toggle} aria-label={playing ? "Pause" : "Play"}>
            {playing
              ? <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><rect x="3" y="3" width="3.5" height="10"/><rect x="9.5" y="3" width="3.5" height="10"/></svg>
              : <I name="play" size={16} />}
          </button>
          <button className="ev-mplayer-btn" onClick={next} aria-label="Next">
            <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor"><rect x="10" y="2" width="2" height="10"/><path d="M9 7L2 2v10z"/></svg>
          </button>
        </div>
        {list.length > 1 && (
          <ul className="ev-mplayer-tracks">
            {list.map((t, i) => (
              <li key={i} data-active={i === trackIdx ? "true" : "false"} onClick={() => { setTrackIdx(i); setPlaying(true); }}>
                <span className="mono">{String(i + 1).padStart(2, "0")}</span>
                <span className="serif">{t.title}</span>
                <span className="mono ev-mplayer-trackdur">{t.duration || "—"}</span>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

/* expose to other Babel files */
Object.assign(window, {
  Icon, I, ICONS,
  Placeholder, Logo, UntitledEmbed,
  ToastProvider, useToast,
  CartProvider, useCart,
  RouteProvider, useRoute,
  Header, Footer, CartDrawer,
  VideoPlayer, MusicPlayer,
});
