// shell.jsx — Shared nav, footer, hero, film components for multi-page site.

// ── i18n — UI-string translations ────────────────────────────────────────────
const T = {
  en: {
    nav_omlah: "Omlah", nav_studio: "Studio", nav_contact: "Contact",
    section_cast: "Cast", section_crew: "Crew", section_sponsors: "Sponsors",
    section_bts: "Behind the Scenes", section_archive: "The Archive",
    section_team: "The team", section_practice: "Working practice",
    section_idea: "Idea & Story", section_summary: "Summary", section_takeaway: "Takeaway",
    read_more: "Read more ↓", read_less: "Less ↑",
    view_film: "View film →", open_frame: "Open ↗",
    become_partner: "Become a partner",
    scroll_begin: "Scroll to begin ↓",
    close: "Close", prev: "Previous", next: "Next",
    frame: "Frame", clip: "Clip", fig: "Fig",
    theme: "Theme", language: "Language",
    copyright: "All films reserved",
    collaborators: "collaborators",
    dispatches: "Dispatches · On Set", on_location: "On Location",
    presented_with: "Presented In Association With",
    played_by: "played by", age: "Age",
    meet_team: "Meet the team →",
    about_studio: "About the studio",
    roll: "Roll",
    ar_wip: "Film content translation in progress",
    ar_wip_dismiss: "Dismiss",
  },
  ar: {
    nav_omlah: "عُملة", nav_studio: "الاستوديو", nav_contact: "تواصل",
    section_cast: "الطاقم", section_crew: "طاقم العمل", section_sponsors: "الرعاة",
    section_bts: "من كواليس العمل", section_archive: "الأرشيف",
    section_team: "الفريق", section_practice: "طريقة العمل",
    section_idea: "الفكرة والقصة", section_summary: "الملخص", section_takeaway: "الرسالة",
    read_more: "اقرأ المزيد ↓", read_less: "أقل ↑",
    view_film: "شاهد الفيلم ←", open_frame: "افتح ↗",
    become_partner: "كن شريكاً",
    scroll_begin: "اسحب للبدء ↓",
    close: "إغلاق", prev: "السابق", next: "التالي",
    frame: "لقطة", clip: "مقطع", fig: "شكل",
    theme: "السمة", language: "اللغة",
    copyright: "جميع الحقوق محفوظة",
    collaborators: "متعاونون",
    dispatches: "من الموقع",
    on_location: "في الموقع",
    presented_with: "يُقدَّم بالتعاون مع",
    played_by: "يؤديه", age: "العمر",
    meet_team: "تعرّف على الفريق ←",
    about_studio: "عن الاستوديو",
    roll: "مجموعة",
    ar_wip: "محتوى الأفلام قيد الترجمة",
    ar_wip_dismiss: "إخفاء",
  },
};

const LanguageContext = React.createContext({
  lang: "en",
  t: (k) => (T.en && T.en[k]) || k,
  pick: (obj, field) => (obj ? obj[field] : undefined),
});

function useLang() {
  return React.useContext(LanguageContext);
}

function makeI18n(lang) {
  const dict = T[lang] || T.en;
  return {
    lang,
    t: (k) => dict[k] || (T.en[k] || k),
    pick: (obj, field) => {
      if (!obj) return undefined;
      if (lang === "ar") {
        return obj[field + "Ar"] || obj[field + "Arabic"] || obj[field];
      }
      return obj[field];
    },
  };
}

function LangToggle({ lang, onToggle }) {
  const isEn = lang !== "ar";
  return (
    <button
      type="button"
      onClick={onToggle}
      aria-label={isEn ? "التبديل إلى العربية" : "Switch to English"}
      title={isEn ? "العربية" : "English"}
      data-cursor="lang"
      style={{
        appearance: "none", border: "1px solid var(--line)", background: "transparent",
        color: "var(--fg)", height: 34, minWidth: 54, borderRadius: 999,
        padding: "0 12px",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".18em",
        textTransform: isEn ? "none" : "uppercase",
        transition: "background .2s ease, border-color .2s ease",
      }}
      onMouseEnter={(e) => { e.currentTarget.style.background = "color-mix(in oklab, var(--fg) 8%, transparent)"; }}
      onMouseLeave={(e) => { e.currentTarget.style.background = "transparent"; }}
    >
      {isEn ? "العربية" : "EN"}
    </button>
  );
}

function ArWipBanner() {
  const { lang, t } = useLang();
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    if (lang !== "ar") { setVisible(false); return; }
    try {
      const seen = localStorage.getItem("clacket:ar_wip_seen") === "1";
      setVisible(!seen);
    } catch { setVisible(true); }
  }, [lang]);
  if (!visible || lang !== "ar") return null;
  const dismiss = () => {
    try { localStorage.setItem("clacket:ar_wip_seen", "1"); } catch {}
    setVisible(false);
  };
  return (
    <div style={{
      position: "fixed", bottom: 20, left: "50%", transform: "translateX(-50%)",
      zIndex: 9998,
      display: "flex", alignItems: "center", gap: 14,
      padding: "10px 18px",
      background: "color-mix(in oklab, var(--bg) 90%, transparent)",
      backdropFilter: "blur(14px)", WebkitBackdropFilter: "blur(14px)",
      border: "1px solid var(--line)",
      fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".18em",
      textTransform: "uppercase", color: "var(--fg-dim)",
      maxWidth: "calc(100vw - 32px)",
    }}>
      <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--accent)" }} />
      <span>{t("ar_wip")}</span>
      <button
        type="button"
        onClick={dismiss}
        aria-label={t("ar_wip_dismiss")}
        style={{
          appearance: "none", border: 0, background: "transparent",
          color: "var(--fg)", padding: "2px 6px",
          fontFamily: "var(--font-mono)", fontSize: 12,
        }}
      >×</button>
    </div>
  );
}

function ThemeToggle({ theme, onToggle }) {
  const isDark = theme === "dark";
  return (
    <button
      type="button"
      onClick={onToggle}
      aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
      title={isDark ? "Light mode" : "Dark mode"}
      data-cursor={isDark ? "sun" : "moon"}
      style={{
        appearance: "none", border: "1px solid var(--line)", background: "transparent",
        color: "var(--fg)", width: 34, height: 34, borderRadius: 999,
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        padding: 0, cursor: "none", transition: "background .2s ease, border-color .2s ease",
      }}
      onMouseEnter={(e) => { e.currentTarget.style.background = "color-mix(in oklab, var(--fg) 8%, transparent)"; }}
      onMouseLeave={(e) => { e.currentTarget.style.background = "transparent"; }}
    >
      {isDark ? (
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="4" />
          <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
        </svg>
      ) : (
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" />
        </svg>
      )}
    </button>
  );
}

function MobileNavOverlay({ open, onClose, items, current, theme, onToggleTheme, lang, onToggleLanguage }) {
  const [mounted, setMounted] = React.useState(false);
  React.useEffect(() => {
    if (!open) return;
    const r = requestAnimationFrame(() => setMounted(true));
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      cancelAnimationFrame(r);
      setMounted(false);
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div
      onClick={onClose}
      style={{
        position: "fixed", inset: 0, zIndex: 10000,
        background: mounted ? "color-mix(in oklab, var(--bg) 92%, transparent)" : "color-mix(in oklab, var(--bg) 0%, transparent)",
        backdropFilter: mounted ? "blur(22px)" : "blur(0px)",
        WebkitBackdropFilter: mounted ? "blur(22px)" : "blur(0px)",
        transition: "background .35s ease, backdrop-filter .35s ease",
        display: "flex", flexDirection: "column",
        padding: "80px 28px 32px",
      }}
    >
      <button
        type="button"
        onClick={(e) => { e.stopPropagation(); onClose(); }}
        aria-label="Close menu"
        style={{
          position: "absolute", top: 18, right: 18,
          appearance: "none", border: "1px solid var(--line)", background: "transparent",
          color: "var(--fg)", width: 44, height: 44, borderRadius: 999,
          display: "inline-flex", alignItems: "center", justifyContent: "center",
          fontSize: 22, padding: 0,
        }}
      >×</button>
      <nav
        onClick={(e) => e.stopPropagation()}
        style={{
          flex: 1, display: "flex", flexDirection: "column", justifyContent: "center",
          gap: 14,
          opacity: mounted ? 1 : 0, transform: mounted ? "translateY(0)" : "translateY(12px)",
          transition: "opacity .4s ease .05s, transform .5s cubic-bezier(.22,.61,.36,1) .05s",
        }}
      >
        {items.map((it, i) => {
          const isCurrent = current === it.id;
          return (
            <a
              key={it.id}
              href={it.href}
              style={{
                display: "flex", alignItems: "baseline", gap: 18,
                textDecoration: "none",
                fontFamily: "var(--font-display)", fontWeight: 300,
                fontSize: "clamp(44px, 11vw, 72px)", lineHeight: 1.02,
                letterSpacing: "-0.025em",
                color: isCurrent ? "var(--accent)" : "var(--fg)",
                padding: "6px 0",
                borderBottom: "1px solid var(--line)",
              }}
            >
              <span style={{
                fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".2em",
                color: "var(--fg-dim)", alignSelf: "flex-start", paddingTop: 14,
              }}>
                {String(i + 1).padStart(2, "0")}
              </span>
              <span>{it.label}</span>
            </a>
          );
        })}
      </nav>
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          display: "flex", flexDirection: "column", gap: 12,
          paddingTop: 20, borderTop: "1px solid var(--line)",
          opacity: mounted ? 1 : 0, transition: "opacity .4s ease .15s",
        }}
      >
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".22em", textTransform: "uppercase", color: "var(--fg-dim)" }}>
            {T[lang || "en"].theme}
          </span>
          {onToggleTheme && <ThemeToggle theme={theme} onToggle={onToggleTheme} />}
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".22em", textTransform: "uppercase", color: "var(--fg-dim)" }}>
            {T[lang || "en"].language}
          </span>
          {onToggleLanguage && <LangToggle lang={lang} onToggle={onToggleLanguage} />}
        </div>
      </div>
    </div>
  );
}

function Nav({ current, theme, onToggleTheme, lang, onToggleLanguage }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    const f = () => setScrolled(window.scrollY > 40);
    window.addEventListener("scroll", f);
    return () => window.removeEventListener("scroll", f);
  }, []);
  const dict = T[lang || "en"];
  const items = [
    { label: dict.nav_omlah, href: "omlah.html", id: "omlah" },
    { label: dict.nav_studio, href: "studio.html", id: "studio" },
    { label: dict.nav_contact, href: "contact.html", id: "contact" },
  ];
  return (
    <>
      <nav style={{
        position: "fixed", top: 0, left: 0, right: 0, zIndex: 100,
        padding: "22px 48px",
        display: "flex", justifyContent: "space-between", alignItems: "center",
        background: scrolled ? "color-mix(in oklab, var(--bg) 88%, transparent)" : "transparent",
        backdropFilter: scrolled ? "blur(14px)" : "none",
        borderBottom: scrolled ? "1px solid var(--line)" : "1px solid transparent",
        transition: "all .3s ease",
      }}>
        <a href="index.html" data-cursor="home" style={{
          fontFamily: "var(--font-display)", fontSize: 15, letterSpacing: ".24em",
          color: "var(--fg)", textDecoration: "none",
          display: "flex", alignItems: "center", gap: 12,
        }}>
          <span style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--accent)" }} />
          {STUDIO.name}
        </a>
        <div className="nav-desktop" style={{ display: "flex", gap: 32, alignItems: "center" }}>
          {items.map((it) => (
            <a key={it.id} href={it.href} data-cursor={it.label.toLowerCase()}
               style={{
                 fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".16em",
                 textTransform: "uppercase", textDecoration: "none",
                 color: current === it.id ? "var(--fg)" : "var(--fg-dim)",
                 borderBottom: current === it.id ? "1px solid var(--accent)" : "1px solid transparent",
                 paddingBottom: 3,
               }}>
              {it.label}
            </a>
          ))}
          {onToggleLanguage && <LangToggle lang={lang} onToggle={onToggleLanguage} />}
          {onToggleTheme && <ThemeToggle theme={theme} onToggle={onToggleTheme} />}
        </div>
        <button
          type="button"
          className="nav-hamburger"
          aria-label="Open menu"
          onClick={() => setMenuOpen(true)}
          style={{
            display: "none",
            appearance: "none", border: "1px solid var(--line)", background: "transparent",
            color: "var(--fg)", width: 40, height: 40, borderRadius: 999,
            alignItems: "center", justifyContent: "center", padding: 0,
          }}
        >
          <svg width="18" height="14" viewBox="0 0 18 14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
            <line x1="1" y1="2" x2="17" y2="2" />
            <line x1="1" y1="7" x2="17" y2="7" />
            <line x1="1" y1="12" x2="17" y2="12" />
          </svg>
        </button>
      </nav>
      <MobileNavOverlay
        open={menuOpen}
        onClose={() => setMenuOpen(false)}
        items={items}
        current={current}
        theme={theme}
        onToggleTheme={onToggleTheme}
        lang={lang}
        onToggleLanguage={onToggleLanguage}
      />
    </>
  );
}

function Footer() {
  const { t } = useLang();
  return (
    <footer style={{ padding: "80px 48px 48px", borderTop: "1px solid var(--line)", marginTop: 120 }}>
      <div style={{
        fontFamily: "var(--font-display)", fontWeight: 300,
        fontSize: "clamp(80px, 16vw, 240px)", lineHeight: 0.88, letterSpacing: "-0.04em",
        margin: 0,
      }}>
        {STUDIO.name.split(" ")[0]}
      </div>
      <div style={{
        marginTop: 48, display: "flex", justifyContent: "space-between",
        alignItems: "flex-end", flexWrap: "wrap", gap: 24,
        fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".16em",
        textTransform: "uppercase", color: "var(--fg-dim)",
      }}>
        <div>© MMXXVI · {t("copyright")}</div>
        <div>{STUDIO.location}</div>
      </div>
    </footer>
  );
}

// Generic block wrapper with lots of breathing room
function Block({ index, label, labelKey, subtitle, children, pad = 160 }) {
  const { t } = useLang();
  const resolvedLabel = labelKey ? t(labelKey) : label;
  return (
    <section style={{ padding: `${pad}px 48px`, borderTop: "1px solid var(--line)" }}>
      <div style={{ maxWidth: 1400, margin: "0 auto" }}>
        <RevealOnScroll>
          <div style={{
            display: "flex", justifyContent: "space-between",
            alignItems: "baseline", flexWrap: "wrap", gap: 20,
            marginBottom: 80,
          }}>
            <Kicker index={index} label={resolvedLabel} />
            {subtitle && (
              <span style={{
                fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: ".16em",
                color: "var(--fg-dim)", textTransform: "uppercase",
              }}>{subtitle}</span>
            )}
          </div>
        </RevealOnScroll>
        {children}
      </div>
    </section>
  );
}

// Atmospheric sparkle field — dust motes drifting + scroll-reactive
function SparkleField({ intensity = 1, theme = "dark" }) {
  const canvasRef = React.useRef(null);
  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    let particles = [];
    let rafId;
    let lastScrollY = window.scrollY;
    let scrollKick = 0;

    function resize() {
      const w = window.innerWidth;
      const h = window.innerHeight;
      canvas.width = w * dpr;
      canvas.height = h * dpr;
      canvas.style.width = w + "px";
      canvas.style.height = h + "px";
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    function seed() {
      const w = window.innerWidth, h = window.innerHeight;
      const base = Math.floor((w * h) / 20000);
      const count = Math.max(40, Math.min(110, base));
      particles = Array.from({ length: count }).map(() => ({
        x: Math.random() * w,
        y: Math.random() * h,
        r: Math.random() * 0.8 + 0.25,
        vx: (Math.random() - 0.5) * 0.22,
        vy: Math.random() * 0.18 + 0.06,
        phase: Math.random() * Math.PI * 2,
        speed: Math.random() * 0.022 + 0.008,
        tone: Math.random() < 0.28 ? "accent" : "light",
        depth: Math.random() * 0.8 + 0.2, // parallax weight
      }));
    }

    function onScroll() {
      const y = window.scrollY;
      const delta = y - lastScrollY;
      lastScrollY = y;
      // accumulated velocity from scroll (clamped)
      scrollKick += delta * 0.05;
      if (scrollKick > 8) scrollKick = 8;
      if (scrollKick < -8) scrollKick = -8;
    }

    function frame() {
      const w = window.innerWidth, h = window.innerHeight;
      ctx.clearRect(0, 0, w, h);
      // decay scroll kick
      scrollKick *= 0.92;

      for (const p of particles) {
        if (!reduced) {
          p.x += p.vx;
          p.y += p.vy + scrollKick * p.depth * 0.35;
          p.phase += p.speed;
          if (p.y > h + 10) { p.y = -10; p.x = Math.random() * w; }
          if (p.y < -14) { p.y = h + 10; p.x = Math.random() * w; }
          if (p.x < -10) p.x = w + 10;
          if (p.x > w + 10) p.x = -10;
        }
        const osc = (Math.sin(p.phase) + 1) / 2;
        const alpha = (0.25 + osc * 0.55) * intensity;
        const rgb = theme === "light"
          ? (p.tone === "accent" ? "120,70,20" : "60,40,20")
          : (p.tone === "accent" ? "220,155,85" : "255,245,215");
        const glowR = p.r * 4.5;

        const grad = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, glowR);
        grad.addColorStop(0, `rgba(${rgb},${alpha})`);
        grad.addColorStop(0.45, `rgba(${rgb},${alpha * 0.3})`);
        grad.addColorStop(1, `rgba(${rgb},0)`);
        ctx.fillStyle = grad;
        ctx.beginPath();
        ctx.arc(p.x, p.y, glowR, 0, Math.PI * 2);
        ctx.fill();

        ctx.fillStyle = `rgba(${rgb},${Math.min(alpha + 0.25, 0.9)})`;
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
        ctx.fill();
      }
      rafId = requestAnimationFrame(frame);
    }

    resize();
    seed();
    frame();
    const onResize = () => { resize(); seed(); };
    window.addEventListener("resize", onResize);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => {
      cancelAnimationFrame(rafId);
      window.removeEventListener("resize", onResize);
      window.removeEventListener("scroll", onScroll);
    };
  }, [intensity, theme]);

  return (
    <canvas
      ref={canvasRef}
      aria-hidden="true"
      style={{
        position: "fixed",
        top: 0, left: 0,
        width: "100vw", height: "100vh",
        pointerEvents: "none",
        zIndex: 0,
      }}
    />
  );
}

// App wrapper — cursor + grain + tweaks
const TWEAKS_STORAGE_KEY = "clacket:tweaks";
function AppShell({ current, children }) {
  const initialTweaks = React.useMemo(() => {
    const defaults = window.TWEAK_DEFAULTS || {};
    try {
      const stored = JSON.parse(localStorage.getItem(TWEAKS_STORAGE_KEY) || "{}");
      return { ...defaults, ...stored };
    } catch {
      return defaults;
    }
  }, []);
  const [tw, setTweak] = useTweaks(initialTweaks);
  const lang = tw.language === "ar" ? "ar" : "en";
  React.useEffect(() => {
    try { localStorage.setItem(TWEAKS_STORAGE_KEY, JSON.stringify(tw)); } catch {}
    const r = document.documentElement;
    r.style.setProperty("--accent", tw.accentColor);
    r.setAttribute("data-theme", tw.theme);
    r.setAttribute("lang", lang);
    r.setAttribute("dir", lang === "ar" ? "rtl" : "ltr");
  }, [tw, lang]);
  React.useEffect(() => {
    if (window.STUDIO && tw.studioName) window.STUDIO.name = tw.studioName;
  }, [tw.studioName]);
  // Page fade-in on mount + fade-out on internal navigation
  React.useEffect(() => {
    document.body.classList.remove("is-leaving");
    const r = requestAnimationFrame(() => document.body.classList.add("is-ready"));
    const onPageShow = () => {
      document.body.classList.remove("is-leaving");
      document.body.classList.add("is-ready");
    };
    window.addEventListener("pageshow", onPageShow);
    const isInternalNav = (a, e) => {
      if (!a || a.target === "_blank" || a.hasAttribute("download")) return false;
      if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return false;
      const href = a.getAttribute("href");
      if (!href) return false;
      if (href.startsWith("mailto:") || href.startsWith("tel:") || href.startsWith("javascript:")) return false;
      if (href.startsWith("#")) return false;
      try {
        const url = new URL(href, window.location.href);
        if (url.origin !== window.location.origin) return false;
        if (url.pathname === window.location.pathname && url.hash) return false;
        return true;
      } catch { return false; }
    };
    const onClick = (e) => {
      const a = e.target.closest && e.target.closest("a");
      if (!isInternalNav(a, e)) return;
      e.preventDefault();
      const href = a.href;
      document.body.classList.add("is-leaving");
      setTimeout(() => { window.location.href = href; }, 320);
    };
    document.addEventListener("click", onClick);
    return () => {
      cancelAnimationFrame(r);
      window.removeEventListener("pageshow", onPageShow);
      document.removeEventListener("click", onClick);
    };
  }, []);
  const sparklesEnabled = tw.sparkles !== false;
  const langContextValue = React.useMemo(() => makeI18n(lang), [lang]);
  const toggleLanguage = () => setTweak('language', lang === 'ar' ? 'en' : 'ar');
  return (
    <LanguageContext.Provider value={langContextValue}>
      {tw.customCursor && <CustomCursor />}
      {sparklesEnabled && <SparkleField theme={tw.theme} intensity={1} />}
      <GrainOverlay intensity={tw.grainIntensity / 100} />
      <Nav
        current={current}
        theme={tw.theme}
        onToggleTheme={() => setTweak('theme', tw.theme === 'dark' ? 'light' : 'dark')}
        lang={lang}
        onToggleLanguage={toggleLanguage}
      />
      <main style={{ position: "relative", zIndex: 1 }}>{children}</main>
      <div style={{ position: "relative", zIndex: 1 }}><Footer /></div>
      <ArWipBanner />
      <TweaksPanel title="Tweaks">
        <TweakSection label="Brand" />
        <TweakText label="Studio name" value={tw.studioName} onChange={(v) => setTweak('studioName', v)} />
        <TweakColor label="Accent" value={tw.accentColor} onChange={(v) => setTweak('accentColor', v)} />
        <TweakSection label="Atmosphere" />
        <TweakRadio label="Theme" value={tw.theme} options={['light','dark']} onChange={(v) => setTweak('theme', v)} />
        <TweakRadio label="Language" value={lang} options={['en','ar']} onChange={(v) => setTweak('language', v)} />
        <TweakSlider label="Grain" value={tw.grainIntensity} min={0} max={40} unit="%" onChange={(v) => setTweak('grainIntensity', v)} />
        <TweakToggle label="Sparkles" value={sparklesEnabled} onChange={(v) => setTweak('sparkles', v)} />
        <TweakToggle label="Custom cursor" value={tw.customCursor} onChange={(v) => setTweak('customCursor', v)} />
      </TweaksPanel>
    </LanguageContext.Provider>
  );
}

Object.assign(window, { Nav, Footer, Block, AppShell });
