/* eslint-disable */
/* =============================================================
   App Shell — Brand mark (Quantum Logo), Sidebar, Topbar
   -------------------------------------------------------------
   Icons are unified against the brand reference icon-pack
   (assets/icons/ + reference/17-icon-pack). Stroke-only, 24×24,
   round caps/joins. Navigation glyphs use the canonical paths;
   "genes" uses the animated premium DNA mark (DnaMark); "labs"
   uses the brand spade. The brand orb is the living Quantum Logo.
   ============================================================= */
const { useState: useStateS, useEffect: useEffectS } = React;

// ─── Icons (SVG line, unified from the brand reference set) ───
// 24×24 grid, fill:none, stroke:currentColor, 1.9 weight, round.
function svgIcon(paths, vb) {
  return (p) => {
    const size = p && p.size ? p.size : 20;
    const sw = p && p.sw ? p.sw : 1.9;
    return (
      <svg width={size} height={size} viewBox={vb || "0 0 24 24"} fill="none"
        stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        {paths}
      </svg>
    );
  };
}

const Icon = window.Icon = {
  // ── navigation (canonical reference paths) ──
  home: svgIcon(<><path d="M3.5 10.7 12 3.8l8.5 6.9"/><path d="M5.2 9.8v9.7h5.1v-5.6h3.4v5.6h5.1V9.8"/></>),
  overview: svgIcon(<><rect x="4" y="4" width="16" height="16" rx="2.4"/><path d="M8 8h4.8M8 12h8M8 16h5.6"/><path d="m16.2 7.6 1.2 1.2 2-2"/></>),
  guide: svgIcon(<><path d="M4.5 5.7c2.2-1 4.4-1 6.6.1v14c-2.2-1.1-4.4-1.1-6.6-.1z"/><path d="M19.5 5.7c-2.2-1-4.4-1-6.6.1v14c2.2-1.1 4.4-1.1 6.6-.1z"/><path d="M12 5.8v14"/></>),
  centers: svgIcon(<><circle cx="12" cy="4.5" r="2"/><circle cx="5.2" cy="17.5" r="2"/><circle cx="18.8" cy="17.5" r="2"/><path d="M11 6.2 6.2 15.8M13 6.2l4.8 9.6M7.2 17.5h9.6"/></>),
  planets: svgIcon(<><ellipse cx="12" cy="12" rx="8.6" ry="4.4" transform="rotate(-28 12 12)"/><circle cx="12" cy="12" r="4.2"/><path d="M18.2 5.2h2.7v2.7"/></>),
  compare: svgIcon(<><rect x="3.8" y="4.5" width="7.2" height="7.2" rx="1.4"/><rect x="13" y="12.3" width="7.2" height="7.2" rx="1.4"/><path d="M13.2 5.5h3.1a3 3 0 0 1 3 3v1.1M10.8 18.5H7.7a3 3 0 0 1-3-3v-1.1"/></>),
  // brand spade — for Spade Labs only (drawn, never the unicode glyph)
  spade: svgIcon(<><path d="M12 4C12 4 5.4 9.4 5.4 13.6 5.4 16.1 7.4 17.5 9.2 17 10.1 16.75 10.8 16 11 15 10.9 17.5 10.1 19.2 8.7 20H15.3C13.9 19.2 13.1 17.5 13 15 13.2 16 13.9 16.75 14.8 17 16.6 17.5 18.6 16.1 18.6 13.6 18.6 9.4 12 4 12 4Z"/></>),
  // ── static DNA (fallback / large headers); animated version is <DnaMark/> ──
  dna: svgIcon(<><path d="M7 3c0 4.5 10 5.5 10 9s-10 4.5-10 9"/><path d="M17 3c0 4.5-10 5.5-10 9s10 4.5 10 9"/><path d="M8.4 6.5h7.2M9.4 9.5h5.2M9.4 14.5h5.2M8.4 17.5h7.2"/></>),
  // ── system / utility ──
  crown: svgIcon(<><path d="m4.5 17 1-9 4.1 4 2.4-6 2.4 6 4.1-4 1 9z"/><path d="M5.2 20h13.6"/><circle cx="12" cy="6" r=".6" fill="currentColor" stroke="none"/></>),
  premium: svgIcon(<><path d="m4.5 17 1-9 4.1 4 2.4-6 2.4 6 4.1-4 1 9z"/><path d="M5.2 20h13.6"/><circle cx="12" cy="6" r=".6" fill="currentColor" stroke="none"/></>),
  bell: svgIcon(<><path d="M18 9.8a6 6 0 0 0-12 0c0 7-2.2 6.6-2.2 8h16.4c0-1.4-2.2-1-2.2-8z"/><path d="M9.8 20.2a2.4 2.4 0 0 0 4.4 0"/></>),
  settings: svgIcon(<><path d="M12 8.2a3.8 3.8 0 1 0 0 7.6 3.8 3.8 0 0 0 0-7.6z"/><path d="M19.2 13.4v-2.8l-2-.6a6.4 6.4 0 0 0-.7-1.6l1-1.9-2-2-1.9 1a6.4 6.4 0 0 0-1.6-.7l-.6-2H8.6l-.6 2a6.4 6.4 0 0 0-1.6.7l-1.9-1-2 2 1 1.9a6.4 6.4 0 0 0-.7 1.6l-2 .6v2.8l2 .6c.2.6.4 1.1.7 1.6l-1 1.9 2 2 1.9-1c.5.3 1 .5 1.6.7l.6 2h2.8l.6-2c.6-.2 1.1-.4 1.6-.7l1.9 1 2-2-1-1.9c.3-.5.5-1 .7-1.6z"/></>),
  support: svgIcon(<><path d="M5.2 13.2v-1.7a6.8 6.8 0 0 1 13.6 0v1.7"/><path d="M5.2 13.2h3v5h-3zM15.8 13.2h3v5h-3z"/><path d="M18.8 18.2c-.8 1.5-2.3 2.3-4.4 2.3H12"/></>),
  logout: svgIcon(<><path d="M14.2 7.2V5.5a2 2 0 0 0-2-2H5.8a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h6.4a2 2 0 0 0 2-2v-1.7"/><path d="M10 12h10.2M16.4 8.2l3.8 3.8-3.8 3.8"/></>),
  profile: svgIcon(<><circle cx="12" cy="7.7" r="4"/><path d="M4.6 20.4a7.4 7.4 0 0 1 14.8 0"/></>),
  account: svgIcon(<><circle cx="12" cy="12" r="9"/><circle cx="12" cy="10" r="3"/><path d="M6.3 18.4a6 6 0 0 1 11.4 0"/></>),
  search: svgIcon(<><circle cx="10.5" cy="10.5" r="6.4"/><path d="m15.4 15.4 5 5"/></>),

  // ── aliases (keep older page references working) ──
  // gates → genes/DNA surface; labs → brand spade
  gates: svgIcon(<><path d="M7 3c0 4.5 10 5.5 10 9s-10 4.5-10 9"/><path d="M17 3c0 4.5-10 5.5-10 9s10 4.5 10 9"/><path d="M8.4 6.5h7.2M9.4 9.5h5.2M9.4 14.5h5.2M8.4 17.5h7.2"/></>),
  labs: svgIcon(<><path d="M12 4C12 4 5.4 9.4 5.4 13.6 5.4 16.1 7.4 17.5 9.2 17 10.1 16.75 10.8 16 11 15 10.9 17.5 10.1 19.2 8.7 20H15.3C13.9 19.2 13.1 17.5 13 15 13.2 16 13.9 16.75 14.8 17 16.6 17.5 18.6 16.1 18.6 13.6 18.6 9.4 12 4 12 4Z"/></>),

  // ── content / inline icons (kept; same stroke-only language) ──
  chevDown: svgIcon(<path d="m6 9 6 6 6-6"/>),
  chevLeft: svgIcon(<path d="m15 6-6 6 6 6"/>),
  chevRight: svgIcon(<path d="m9 6 6 6-6 6"/>),
  help: svgIcon(<><circle cx="12" cy="12" r="9"/><path d="M9.5 9a2.5 2.5 0 1 1 4 2c-.8.5-1.5 1-1.5 2"/><circle cx="12" cy="17" r="0.4" fill="currentColor"/></>),
  star: (p) => (<svg width={p?.size||14} height={p?.size||14} viewBox="0 0 24 24" fill="currentColor"><polygon points="12,2 15,9 22,9.5 17,14 18.5,21 12,17.5 5.5,21 7,14 2,9.5 9,9"/></svg>),
  starOutline: svgIcon(<polygon points="12,2 15,9 22,9.5 17,14 18.5,21 12,17.5 5.5,21 7,14 2,9.5 9,9"/>),
  sparkle: svgIcon(<path d="M12 3v4M12 17v4M3 12h4M17 12h4M6.3 6.3l2.8 2.8M14.9 14.9l2.8 2.8M6.3 17.7l2.8-2.8M14.9 9.1l2.8-2.8"/>),
  share: svgIcon(<><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></>),
  heart: svgIcon(<path d="M19 9c0 5-7 11-7 11S5 14 5 9a7 7 0 0 1 14 0Z"/>),
  download: svgIcon(<><path d="M12 4v12M7 11l5 5 5-5"/><path d="M5 20h14"/></>),
  bookOpen: svgIcon(<><path d="M3 4h7a3 3 0 0 1 3 3v13"/><path d="M21 4h-7a3 3 0 0 0-3 3v13"/></>),
  compass: svgIcon(<><circle cx="12" cy="12" r="9"/><polygon points="14 8 10 14 14 16 18 10"/></>),
  beaker: svgIcon(<><path d="M9 3v6L5 18a3 3 0 0 0 2.7 4.3h8.6A3 3 0 0 0 19 18L15 9V3"/><line x1="9" y1="3" x2="15" y2="3"/></>),
  sun: svgIcon(<><circle cx="12" cy="12" r="4"/><line x1="12" y1="2" x2="12" y2="5"/><line x1="12" y1="19" x2="12" y2="22"/><line x1="2" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="22" y2="12"/><line x1="4.5" y1="4.5" x2="6.5" y2="6.5"/><line x1="17.5" y1="17.5" x2="19.5" y2="19.5"/><line x1="4.5" y1="19.5" x2="6.5" y2="17.5"/><line x1="17.5" y1="6.5" x2="19.5" y2="4.5"/></>),
  moon: svgIcon(<path d="M21 13A8 8 0 0 1 11 3a8 8 0 1 0 10 10z"/>),
  diamond: svgIcon(<polygon points="12,2 22,9 12,22 2,9"/>),
  eye: svgIcon(<><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></>),
  leaf: svgIcon(<><path d="M5 19c3 0 11-3 11-12 0 0-7 1-9 5s-2 7-2 7Z"/><line x1="5" y1="19" x2="11" y2="13"/></>),
  flash: svgIcon(<polygon points="13,2 4,14 12,14 11,22 20,10 12,10"/>),
  globe: svgIcon(<><circle cx="12" cy="12" r="9"/><line x1="3" y1="12" x2="21" y2="12"/><path d="M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></>),
  check: svgIcon(<polyline points="20 6 9 17 4 12"/>),
  brain: svgIcon(<><path d="M9 4a3 3 0 0 0-3 3 3 3 0 0 0-2 5 3 3 0 0 0 2 5 3 3 0 0 0 3 3V4z"/><path d="M15 4a3 3 0 0 1 3 3 3 3 0 0 1 2 5 3 3 0 0 1-2 5 3 3 0 0 1-3 3V4z"/></>),
  // ── people / group (profile summary: "البروفايل") ──
  users: svgIcon(<><circle cx="9" cy="8.2" r="3.1"/><path d="M3.6 19.2a5.4 5.4 0 0 1 10.8 0"/><path d="M15.6 5.4a3.1 3.1 0 0 1 0 5.6"/><path d="M17 13.2a5.4 5.4 0 0 1 3.4 5"/></>),
  // ── definition (connected centers: "التعريف") ──
  definition: svgIcon(<><circle cx="8" cy="7.5" r="1.9"/><circle cx="16" cy="7.5" r="1.9"/><circle cx="8" cy="16.5" r="1.9"/><circle cx="16" cy="16.5" r="1.9"/><path d="M9.9 7.5h4.2M9.9 16.5h4.2M8 9.4v5.2M16 9.4v5.2"/></>),
  // ── activity / pulse (not-self theme: "موضوع الذات") ──
  activity: svgIcon(<polyline points="2.5 12 7 12 9.5 5 14.5 19 17 12 21.5 12"/>),
  strengths: svgIcon(<><path d="M4 19h16M6 15l4-4 3 2 6-7M14.5 6H19v4.5"/></>),
  attention: svgIcon(<><circle cx="12" cy="12" r="4.5"/><circle cx="12" cy="12" r="1"/><path d="M9 3H4v5m11-5h5v5m0 8v5h-5m-6 0H4v-5"/></>),
  lock: svgIcon(<><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></>),
  clock: svgIcon(<><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 16 14"/></>),
  plus: svgIcon(<><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></>),
  trash: svgIcon(<><path d="M4 7h16M9 7V5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13"/></>),
  edit: svgIcon(<><path d="M4 20h4L18.5 9.5a2 2 0 0 0-2.8-2.8L5 17.2z"/><path d="M14.5 7.5 16.5 9.5"/></>),
  calendar: svgIcon(<><path d="M7 3v4M17 3v4"/><rect x="4" y="6" width="16" height="14" rx="2"/><path d="M8 11h3M13 11h3M8 15h3M13 15h3"/></>),
  pin: svgIcon(<><path d="M12 21s7-6.4 7-11a7 7 0 1 0-14 0c0 4.6 7 11 7 11Z"/><circle cx="12" cy="10" r="2.6"/></>),
  mail: svgIcon(<><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m4 7 8 6 8-6"/></>),
  google: (p) => (<svg width={p?.size||18} height={p?.size||18} viewBox="0 0 24 24"><path fill="#FFC857" d="M12 11v3.2h4.5A4.5 4.5 0 0 1 12 17.5 5.5 5.5 0 1 1 15.6 7.8l2.3-2.3A8.8 8.8 0 1 0 20.8 12c0-.6-.06-1-.15-1z"/></svg>),
};

// ─── DnaMark — premium ANIMATED double-helix (canvas) ─────────
// Used for the "genes" surface. Subtle continuous rotation at rest;
// brighter + faster when active, with a travelling gold highlight.
window.DnaMark = function DnaMark({ size = 22, active = false, energy }) {
  const cref = React.useRef(null);
  const stateRef = React.useRef({ phase: 0, lvl: 0 });
  const activeRef = React.useRef(active);
  activeRef.current = active;
  const en = energy != null ? energy : 1;

  React.useEffect(() => {
    const canvas = cref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const dpr = Math.min(window.devicePixelRatio || 1, 2.5);
    canvas.width = Math.round(size * dpr);
    canvas.height = Math.round(size * dpr);
    canvas.style.width = size + "px";
    canvas.style.height = size + "px";
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    const CY = "#62DDFF", VI = "#C084FF", GO = "#F8C648";
    const W = size, cx = W / 2;
    const top = W * 0.14, bot = W * 0.86, H = bot - top;
    const amp = W * 0.30, turns = 1.6;
    const rgba = (hex, a) => {
      const h = hex.replace("#", "");
      return `rgba(${parseInt(h.slice(0,2),16)},${parseInt(h.slice(2,4),16)},${parseInt(h.slice(4,6),16)},${a})`;
    };

    let raf, last = performance.now();
    const loop = (now) => {
      const dt = Math.min((now - last) / 1000, 0.05); last = now;
      const st = stateRef.current;
      const tgt = activeRef.current ? 1 : 0;
      st.lvl += (tgt - st.lvl) * Math.min(1, 6 * dt);
      const spd = (0.55 + st.lvl * 1.25) * en;
      st.phase += (reduce ? 0 : spd) * dt;

      ctx.save();
      ctx.scale(dpr, dpr);
      ctx.clearRect(0, 0, W, W);
      ctx.lineCap = "round";

      const SAMPLES = 26;
      const strand = (off, col) => {
        ctx.save();
        ctx.shadowBlur = 5 + st.lvl * 5; ctx.shadowColor = rgba(col, 0.7);
        ctx.strokeStyle = rgba(col, 0.92);
        ctx.lineWidth = 1.5 + st.lvl * 0.4;
        ctx.beginPath();
        for (let i = 0; i <= SAMPLES; i++) {
          const t = i / SAMPLES;
          const y = top + t * H;
          const ang = st.phase + t * turns * Math.PI * 2 + off;
          const x = cx + amp * Math.sin(ang);
          i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
        }
        ctx.stroke();
        ctx.restore();
      };

      // rungs (behind strands) + travelling gold highlight
      const RUNGS = 6;
      const goldIdx = Math.floor((st.phase * 0.5 % 1 + 1) % 1 * RUNGS);
      for (let r = 0; r < RUNGS; r++) {
        const t = (r + 0.5) / RUNGS;
        const y = top + t * H;
        const ang = st.phase + t * turns * Math.PI * 2;
        const x1 = cx + amp * Math.sin(ang);
        const x2 = cx + amp * Math.sin(ang + Math.PI);
        const depth = Math.abs(Math.cos(ang)); // 1 = facing us
        const isGold = active && r === goldIdx;
        ctx.save();
        ctx.shadowBlur = isGold ? 7 : 2;
        ctx.shadowColor = rgba(isGold ? GO : VI, 0.7);
        ctx.strokeStyle = rgba(isGold ? GO : "#9D8BFF", (0.30 + 0.5 * depth) * (0.6 + 0.4 * st.lvl));
        ctx.lineWidth = isGold ? 1.8 : 1.2;
        ctx.beginPath(); ctx.moveTo(x1, y); ctx.lineTo(x2, y); ctx.stroke();
        ctx.restore();
      }
      strand(0, CY);
      strand(Math.PI, VI);

      // base-pair nodes
      for (let r = 0; r < RUNGS; r++) {
        const t = (r + 0.5) / RUNGS;
        const y = top + t * H;
        const ang = st.phase + t * turns * Math.PI * 2;
        [[cx + amp * Math.sin(ang), CY], [cx + amp * Math.sin(ang + Math.PI), VI]].forEach(([x, c]) => {
          ctx.save(); ctx.shadowBlur = 4; ctx.shadowColor = rgba(c, 0.8);
          ctx.fillStyle = rgba(c, 0.95);
          ctx.beginPath(); ctx.arc(x, y, 1.05 + st.lvl * 0.4, 0, Math.PI * 2); ctx.fill();
          ctx.restore();
        });
      }
      ctx.restore();
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [size, en]);

  return <canvas ref={cref} style={{ display: "block" }} aria-hidden="true" />;
};

// ─── Brand orb — the living Quantum Logo (canvas) ─────────────
// At rest: master sacred-geometry sigil. On hover: morphs into a
// quantum atom in motion, then eases smoothly back on leave.
window.BrandOrb = function BrandOrb({ size = 50, variant = "quantum", energy = 1.6 }) {
  const cref = React.useRef(null);
  const wrapRef = React.useRef(null);
  const [hover, setHover] = useStateS(false);

  React.useEffect(() => {
    if (!window.QuantumLogo || !cref.current) return;
    const logo = new window.QuantumLogo(cref.current, {
      variant, size, energy, hoverTarget: wrapRef.current,
    });
    logo.start();
    return () => logo.destroy();
  }, [size, variant, energy]);

  return (
    <div
      ref={wrapRef}
      className={`brand-orb ${hover ? "is-hover" : ""}`}
      style={{ width: size, height: size }}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
      title="HUMAN DESIGN"
    >
      <canvas ref={cref}></canvas>
    </div>
  );
};

// ─── Sidebar ──────────────────────────────────────────────────
// Animated nav item — icon comes alive on hover (DNA spins faster;
// the SVG icons play a CSS keyframe keyed by data-icon).
window.NavItem = function NavItem({ it, active, lang, onRoute }) {
  const L = I18N[lang];
  const [hover, setHover] = useStateS(false);
  const I = Icon[it.icon];
  return (
    <a
      className={`nav-item ${active ? "active" : ""} ${hover ? "is-hover" : ""}`}
      data-icon={it.id}
      onClick={(e) => { e.preventDefault(); onRoute(it.id); }}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
      href="#"
    >
      <span className="ni-icon sigil">
        <svg className="sigil-rings" viewBox="0 0 40 40" width="34" height="34" aria-hidden="true">
          <circle className="sg-outer" cx="20" cy="20" r="18.5" />
          <g className="sg-ticks">
            <line x1="20" y1="0.6" x2="20" y2="3.4" /><line x1="20" y1="36.6" x2="20" y2="39.4" />
            <line x1="0.6" y1="20" x2="3.4" y2="20" /><line x1="36.6" y1="20" x2="39.4" y2="20" />
          </g>
          <circle className="sg-inner" cx="20" cy="20" r="13" strokeDasharray="2.5 5" />
          <circle className="sg-comet" cx="20" cy="1.5" r="1.7" />
        </svg>
        <span className="sigil-core">
          {it.icon === "dna" ? <Icon.dna /> : <I />}
        </span>
      </span>
      <span className="ni-label">{L.nav[it.id]}</span>
      {it.badge && <span className="nav-badge">{it.badge}</span>}
    </a>
  );
};

window.Sigil = function Sigil({ children, size = 34, idle = false }) {
  return (
    <span className="sigil sigil-host">
      <svg className={`sigil-rings ${idle ? "" : "sg-static"}`} viewBox="0 0 40 40" width={size} height={size} aria-hidden="true">
        <circle className="sg-outer" cx="20" cy="20" r="18.5" />
        <g className="sg-ticks">
          <line x1="20" y1="0.6" x2="20" y2="3.4" /><line x1="20" y1="36.6" x2="20" y2="39.4" />
          <line x1="0.6" y1="20" x2="3.4" y2="20" /><line x1="36.6" y1="20" x2="39.4" y2="20" />
        </g>
        <circle className="sg-inner" cx="20" cy="20" r="13" strokeDasharray="2.5 5" />
        <circle className="sg-comet" cx="20" cy="1.5" r="1.7" />
      </svg>
      <span className="sigil-core">{children}</span>
    </span>
  );
};

window.Sidebar = function Sidebar({ lang, route, onRoute }) {
  const L = I18N[lang];
  const items = [
    { id: "home",     icon: "home" },
    { id: "overview", icon: "overview" },
    { id: "guide",    icon: "guide" },
    { id: "centers",  icon: "centers" },
    { id: "planets",  icon: "planets" },
    { id: "gates",    icon: "dna" },     // genes → animated DNA mark
    { id: "compare",  icon: "compare" },
    { id: "labs",     icon: "spade" },   // Spade Labs → brand spade
    { id: "dream",    icon: "moon" },    // مصفوفة الحلم — داخلي حتى الطور 5
  ].filter((it) => !window.SpadeAccess || SpadeAccess.canSee(it.id));
  return (
    <aside className="sidebar" data-galaxy-ui>
      <div className="sidebar-brand">
        <BrandOrb size={50} />
        <div className="brand-text">
          <strong>{L.brand.title}</strong>
          <em>{L.brand.subtitle}</em>
        </div>
      </div>
      <nav className="sidebar-nav">
        {items.map((it) => <NavItem key={it.id} it={it} active={route === it.id} lang={lang} onRoute={onRoute} />)}
      </nav>
      {/* The upgrade card that used to sit here was removed with the rest
          of the paid tier — this is a free educational site, so there is
          nothing to upgrade to. */}
      <div className="sidebar-footer">
        {!window.ChartStore?.remote && <button className="sf-support" onClick={() => onRoute && onRoute("support")}>
          <Icon.support size={14} />
          {lang === "ar" ? "تواصل مع الدعم" : "Contact support"}
        </button>}
        {window.SpadeAccess && SpadeAccess.isAdmin() && (
          <button className="sf-support" onClick={() => onRoute && onRoute("admin")} style={{ borderColor: "rgba(248,198,72,0.4)", color: "var(--gold)" }}>
            <Icon.crown size={14} />
            {lang === "ar" ? "لوحة الأدمن" : "Admin console"}
          </button>
        )}
      </div>
    </aside>
  );
};

// ─── ChartSearch box — always present in the top panel ────────
// Scoped to YOUR chart only (see src/data/chart-search.js): typing
// «قلق» returns your own activated gates/lines/centers, not the whole
// database. Results are grouped by section because the whole point is
// that you don't know which section the thing lives in.
window.SearchBox = function SearchBox({ lang, onRoute }) {
  const { useState, useRef, useEffect } = React;
  const ar = lang === "ar";
  const S = I18N[lang].search || {};
  const [q, setQ] = useState("");
  const [open, setOpen] = useState(false);
  const [hits, setHits] = useState([]);
  const box = useRef(null);

  useEffect(() => {
    const t = setTimeout(() => {
      const r = (window.ChartSearch ? ChartSearch.query(q, lang) : []);
      setHits(r);
    }, 120);
    return () => clearTimeout(t);
  }, [q, lang]);

  useEffect(() => {
    const away = (e) => { if (box.current && !box.current.contains(e.target)) setOpen(false); };
    const esc = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", away);
    document.addEventListener("keydown", esc);
    return () => { document.removeEventListener("mousedown", away); document.removeEventListener("keydown", esc); };
  }, []);

  // group by section, preserving score order
  const groups = [];
  hits.forEach((h) => {
    let g = groups.find((x) => x.section === h.section);
    if (!g) { g = { section: h.section, items: [] }; groups.push(g); }
    g.items.push(h);
  });

  const go = (h) => { setOpen(false); setQ(""); onRoute && onRoute(h.route); };

  return (
    <div className="topbar-search" ref={box}>
      <span className="tbs-ic"><Icon.search size={15} /></span>
      <input
        className="tbs-input"
        type="text"
        value={q}
        placeholder={S.placeholder || (ar ? "ابحث في خريطتك…" : "Search your chart…")}
        onChange={(e) => { setQ(e.target.value); setOpen(true); }}
        onFocus={() => setOpen(true)}
      />
      {q && <button className="tbs-clear" onClick={() => { setQ(""); setOpen(false); }} aria-label={S.clear || (ar ? "مسح" : "Clear")}>×</button>}
      {open && q.trim().length >= 2 && (
        <div className="tbs-panel" data-galaxy-ui>
          {hits.length === 0 ? (
            <div className="tbs-empty">{S.empty || (ar ? "لا شيء في خريطتك يطابق هذا." : "Nothing in your chart matches that.")}</div>
          ) : (
            <React.Fragment>
              <div className="tbs-count">{(S.count || (ar ? "{n} نتيجة في خريطتك" : "{n} results in your chart")).replace("{n}", hits.length)}</div>
              {groups.map((g, i) => (
                <div key={i} className="tbs-group">
                  <div className="tbs-sec">{g.section}</div>
                  {g.items.map((h, j) => (
                    <button key={j} className="tbs-hit" onClick={() => go(h)}>
                      <strong>{h.title}</strong>
                      {h.sub ? <em>{h.sub}</em> : null}
                      <span>{h.snippet}</span>
                    </button>
                  ))}
                </div>
              ))}
            </React.Fragment>
          )}
        </div>
      )}
    </div>
  );
};

// ─── Topbar ───────────────────────────────────────────────────
window.Topbar = function Topbar({ lang, onLangToggle, user, onRoute }) {
  const L = I18N[lang];
  const initial = (lang === "ar" ? "ع" : "A");
  return (
    <header className="topbar" data-galaxy-ui>
      <SearchBox lang={lang} onRoute={onRoute} />
      <div className="topbar-right">
        <button className="topbar-lang" onClick={onLangToggle} title={lang === "ar" ? "English" : "العربية"}>
          <Icon.globe size={15} />
          <span>{L.topbar.lang_toggle}</span>
        </button>
        {!window.ChartStore?.remote && <button className="topbar-bell topbar-create" onClick={() => onRoute && onRoute("create")} title={lang === "ar" ? "إنشاء خريطة" : "Create chart"}>
          <Icon.plus size={18} />
        </button>}
        {!window.ChartStore?.remote && <button className="topbar-bell" onClick={() => onRoute && onRoute("notifications")}>
          <Icon.bell size={18} />
        </button>}
        <div className="topbar-user" onClick={() => onRoute && onRoute("settings")}>
          <span className="topbar-name">{user[lang === "ar" ? "name_ar" : "name_en"]}</span>
          <div className="topbar-avatar">
            <div style={{ width: "100%", height: "100%", background: "linear-gradient(135deg,#8A5CFF,#62DDFF)", display: "grid", placeItems: "center", fontWeight: 700 }}>{initial}</div>
          </div>
          <span className="topbar-chev"><Icon.chevDown /></span>
        </div>
      </div>
    </header>
  );
};

// ─── HelpButton — "How to read this screen?" trigger + modal ────
// Reusable: PageHeader uses it, and custom-header pages drop it in too.
window.HelpButton = function HelpButton({ lang, label, route, className }) {
  const { useState, useEffect } = React;
  const [open, setOpen] = useState(false);
  const ar = lang === "ar";
  const btnLabel = label || (ar ? "كيف تقرأ هذه الشاشة؟" : "How to read this screen?");
  const rt = route || (window.location.hash || "").replace(/^#\/?/, "").split("/")[0] || "home";
  const content = (window.helpFor && window.helpFor(lang, rt)) ||
    { title: btnLabel, intro: "", sections: [], tip: "" };

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  return (
    <React.Fragment>
      <button className={`help-btn ${className || ""}`} onClick={() => setOpen(true)} aria-haspopup="dialog">
        <span className="help-icon"><Icon.help size={11} /></span>
        {btnLabel}
      </button>
      {open && (
        <div className="help-modal-ov" onClick={() => setOpen(false)} role="dialog" aria-modal="true">
          <div className="help-modal" onClick={(e) => e.stopPropagation()}>
            <button className="help-modal-x" onClick={() => setOpen(false)} aria-label={ar ? "إغلاق" : "Close"}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
            </button>
            <div className="help-modal-head">
              <span className="help-modal-badge"><Icon.help size={16} /></span>
              <h3>{content.title}</h3>
            </div>
            {content.intro && <p className="help-modal-intro">{content.intro}</p>}
            <div className="help-modal-sections">
              {(content.sections || []).map((s, i) => (
                <div className="help-modal-block" key={i}>
                  <span className="help-modal-block-h">{s.h}</span>
                  <p>{s.body}</p>
                </div>
              ))}
            </div>
            {content.tip && (
              <div className="help-modal-tip">
                <span className="help-modal-tip-ic"><Icon.sparkle size={15} /></span>
                <span>{content.tip}</span>
              </div>
            )}
            <button className="help-modal-done" onClick={() => setOpen(false)}>
              {ar ? "فهمت، شكرًا" : "Got it, thanks"}
            </button>
          </div>
        </div>
      )}
    </React.Fragment>
  );
};

// ─── PageHeader (with "How to read this screen?" help modal) ────
window.PageHeader = function PageHeader({ title, sub, help, lang }) {
  return (
    <div className="page-header">
      <div className="ph-title-block">
        <h1 className="page-title">{title}</h1>
        {sub && <p className="page-subtitle">{sub}</p>}
      </div>
      <HelpButton lang={lang} label={help} />
    </div>
  );
};
