/* App shell - sidebar + topbar + routing + global record panel + tweaks.
   Exports: App.                                                        */

const NAV_SECTIONS = [
  { label: null, items: [
    { id: "dashboard", label: "Dashboard", icon: "dashboard" },
    { id: "map", label: "Map", icon: "map" },
    { id: "directory", label: "People", icon: "directory" },
    { id: "orgs", label: "Organisations", icon: "building" },
    { id: "initiatives", label: "Initiatives", icon: "grid" },
    { id: "projects", label: "Projects", icon: "folder" },
    { id: "events", label: "Events", icon: "calendar" },
  ]},
  { label: "Intelligence", items: [
    { id: "copilot", label: "NeuroAI", icon: "spark", action: "assistant" },
    { id: "prioritise", label: "Prioritisation", icon: "target" },
    { id: "reports", label: "Reports & Analytics", icon: "analytics" },
    { id: "impact", label: "Impact Tracker", icon: "trendingUp" },
    { id: "forecast", label: "Forecasting", icon: "globe" },
  ]},
  { label: "Operations", items: [
    { id: "booking", label: "Room Booking", icon: "door" },
    { id: "funding", label: "Funding Hub", icon: "funding" },
    { id: "pipeline", label: "Grant Pipeline", icon: "pipeline" },
    { id: "applications", label: "Applications", icon: "inbox" },
    { id: "tasks", label: "Tasks & Reminders", icon: "tasks" },
    { id: "documents", label: "Documents", icon: "document" },
  ]},
  { label: "Tools", items: [
    { id: "linkfinder", label: "Link Finder", icon: "link" },
    { id: "workflows", label: "Workflows", icon: "workflow" },
    { id: "alerts", label: "Alerts & Signals", icon: "signal" },
    { id: "integrations", label: "Integrations", icon: "plug", soon: true },
  ]},
];
const NAV_ADMIN = [
  { id: "settings", label: "Settings", icon: "settings" },
  { id: "admin", label: "Users", icon: "shield" },
  { id: "audit", label: "Audit Log", icon: "history", soon: true },
  { id: "billing", label: "Billing", icon: "receipt", soon: true },
];

/* Aspirational feature teasers - each "soon" route renders a polished
   preview so the demo shows the platform's full potential. */
const FEATURES = {
  integrations: { icon: "plug", tag: "Plays well with your stack",
    blurb: "Connect your CRM, accounting, calendar and email so the ecosystem stays in sync without anyone copying data by hand.",
    caps: [["plug", "Pre-built connectors", "Sync with the tools you already run."], ["layers", "Two-way sync", "Changes flow both ways, automatically."], ["lock", "Secure by design", "Granular scopes and full audit trail."]] },
  audit: { icon: "history", tag: "Total accountability",
    blurb: "A complete, tamper-evident history of every change - who edited what, when, and why - for full governance confidence.",
    caps: [["history", "Full change log", "Every edit captured with author and timestamp."], ["lock", "Tamper-evident", "Immutable record for governance."], ["document", "Export for audit", "One-click compliance reports."]] },
  billing: { icon: "receipt", tag: "Simple, transparent plans",
    blurb: "Manage your subscription, seats and invoices - scale the platform as your ecosystem grows.",
    caps: [["receipt", "Invoices & receipts", "Everything in one place."], ["user", "Seat management", "Add and remove team members easily."], ["trendingUp", "Usage insights", "See how your team uses the platform."]] },
};

/* ---- global topbar search with live results ---- */
function TopSearch({ onOpen, onSeeAll }) {
  const D = window.DATA;
  const [q, setQ] = React.useState("");
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", h);
    return () => document.removeEventListener("mousedown", h);
  }, []);
  const pool = [...D.orgs, ...D.people, ...D.projects, ...D.events];
  const results = q ? pool.filter((e) => e.name.toLowerCase().includes(q.toLowerCase())).slice(0, 7) : [];
  return (
    <div ref={ref} style={{ position: "relative", width: 400, maxWidth: "42vw" }}>
      <Icon name="search" size={17} style={{ position: "absolute", left: 14, top: "50%", transform: "translateY(-50%)", color: "var(--text-faint)", pointerEvents: "none" }} />
      <input className="input focusable" placeholder="Search the ecosystem…" value={q}
        onChange={(e) => { setQ(e.target.value); setOpen(true); }} onFocus={() => setOpen(true)}
        onKeyDown={(e) => { if (e.key === "Enter") { onSeeAll(q); setOpen(false); } }}
        style={{ paddingLeft: 42, height: 46, background: "var(--surface-2)" }} />
      {open && q && (
        <div className="card fade-in" style={{ position: "absolute", top: "calc(100% + 8px)", left: 0, right: 0, zIndex: 30, boxShadow: "var(--shadow-lg)", overflow: "hidden" }}>
          {results.length ? results.map((e) => {
            const k = D.kindOf(e.id);
            return (
              <button key={e.id} className="focusable" onClick={() => { onOpen(e.id); setOpen(false); setQ(""); }}
                style={{ display: "flex", alignItems: "center", gap: 11, width: "100%", padding: "12px 15px", border: "none", borderBottom: "1px solid var(--border)", background: "none", cursor: "pointer", textAlign: "left", color: "var(--text)", font: "inherit" }}
                onMouseEnter={(ev) => (ev.currentTarget.style.background = "var(--surface-2)")}
                onMouseLeave={(ev) => (ev.currentTarget.style.background = "none")}>
                {k === "org" ? <span style={{ width: 9, height: 9, borderRadius: 999, background: domainColor(e.domain), flex: "none" }} />
                  : <Icon name={KIND_META[k].icon} size={15} style={{ color: "var(--text-muted)" }} />}
                <span style={{ flex: 1, fontSize: 14.5, fontWeight: 560 }}>{e.name}</span>
                <span className="badge" style={{ fontSize: 11 }}>{KIND_META[k].label}</span>
              </button>
            );
          }) : <div style={{ padding: "18px", fontSize: 14, color: "var(--text-muted)" }}>No matches for "{q}"</div>}
        </div>
      )}
    </div>
  );
}

/* ---- events view ---- */
function EventsView({ onOpen }) {
  const D = window.DATA;
  const sorted = [...D.events].sort((a, b) => new Date(a.date) - new Date(b.date));
  return (
    <div style={{ position: "absolute", inset: 0, overflow: "auto", background: "var(--bg)" }}>
      <div style={{ maxWidth: 820, margin: "0 auto", padding: "30px 30px 60px" }}>
        <div style={{ marginBottom: 22 }}>
          <div className="display" style={{ fontSize: 28 }}>Events</div>
          <div style={{ fontSize: 14, color: "var(--text-muted)", marginTop: 3 }}>Convenings, galas and forums across the ecosystem.</div>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {sorted.map((ev) => {
            const d = new Date(ev.date);
            return (
              <button key={ev.id} className="card focusable" onClick={() => onOpen(ev.id)}
                style={{ display: "flex", alignItems: "center", gap: 16, padding: 16, cursor: "pointer", textAlign: "left", background: "var(--surface)" }}>
                <div style={{ width: 56, flex: "none", textAlign: "center", padding: "8px 0", borderRadius: 10, background: "var(--surface-2)", border: "1px solid var(--border)" }}>
                  <div className="mono" style={{ fontSize: 19, fontWeight: 600, lineHeight: 1 }}>{d.getDate()}</div>
                  <div style={{ fontSize: 11, color: "var(--text-muted)", textTransform: "uppercase", marginTop: 2 }}>{d.toLocaleDateString("en-GB", { month: "short" })}</div>
                  <div style={{ fontSize: 10.5, color: "var(--text-faint)" }}>{d.getFullYear()}</div>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 15, fontWeight: 650 }}>{ev.name}</div>
                  <div style={{ fontSize: 12.5, color: "var(--text-muted)", marginTop: 3 }}>{ev.notes}</div>
                  <div style={{ display: "flex", gap: 14, marginTop: 8, fontSize: 12, color: "var(--text-faint)" }}>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><Icon name="building" size={13} /> {(ev.orgs || []).length} orgs</span>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><Icon name="user" size={13} /> {(ev.attendees || []).length} attendees</span>
                  </div>
                </div>
                <Icon name="chevronRight" size={18} style={{ color: "var(--text-faint)" }} />
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* ---- feature teaser (aspirational "coming soon" pages) ---- */
function FeatureTeaser({ id, title, onOpenRecord }) {
  const f = FEATURES[id] || { icon: "spark", tag: "Coming soon", blurb: "This module is on the roadmap.", caps: [] };
  return (
    <div style={{ position: "absolute", inset: 0, overflow: "auto", background: "var(--bg)" }}>
      <div style={{ maxWidth: 940, margin: "0 auto", padding: "30px 30px 60px" }}>
        {/* hero */}
        <div className="card grid-texture" style={{ position: "relative", overflow: "hidden", padding: "34px 32px", marginBottom: 18 }}>
          <div style={{ position: "absolute", top: -60, right: -40, width: 320, height: 320, borderRadius: 999, background: "radial-gradient(circle at center, var(--accent-soft-2), transparent 68%)", opacity: 0.8, pointerEvents: "none" }} />
          <div style={{ position: "relative", display: "flex", alignItems: "flex-start", gap: 18 }}>
            <div style={{ width: 56, height: 56, flex: "none", borderRadius: 16, display: "grid", placeItems: "center", background: "var(--accent)", color: "var(--accent-contrast)", boxShadow: "var(--shadow)" }}>
              <Icon name={f.icon} size={28} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 7 }}>
                <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent", fontWeight: 650 }}>
                  <Icon name="spark" size={12} /> On the roadmap
                </span>
              </div>
              <div className="display" style={{ fontSize: 31, lineHeight: 1.08 }}>{title}</div>
              <div style={{ fontSize: 15, color: "var(--accent)", fontWeight: 600, marginTop: 5 }}>{f.tag}</div>
              <div style={{ fontSize: 14.5, color: "var(--text-muted)", lineHeight: 1.6, marginTop: 12, maxWidth: 620 }}>{f.blurb}</div>
              <div style={{ display: "flex", gap: 10, marginTop: 20, flexWrap: "wrap" }}>
                <button className="btn btn-primary"><Icon name="bolt" size={15} /> Request early access</button>
                <button className="btn"><Icon name="bell" size={15} /> Notify me at launch</button>
              </div>
            </div>
          </div>
        </div>

        {/* capabilities */}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14, marginBottom: 18 }}>
          {f.caps.map((c, i) => (
            <div key={i} className="card" style={{ padding: 18 }}>
              <div style={{ width: 38, height: 38, borderRadius: 10, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--accent)", marginBottom: 12 }}>
                <Icon name={c[0]} size={19} />
              </div>
              <div style={{ fontSize: 14, fontWeight: 650, marginBottom: 5 }}>{c[1]}</div>
              <div style={{ fontSize: 12.5, color: "var(--text-muted)", lineHeight: 1.5 }}>{c[2]}</div>
            </div>
          ))}
        </div>

        {/* faux preview */}
        <div className="card" style={{ position: "relative", overflow: "hidden", padding: 0 }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "13px 18px", borderBottom: "1px solid var(--border)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <Icon name={f.icon} size={16} style={{ color: "var(--text-muted)" }} />
              <span style={{ fontSize: 13.5, fontWeight: 600 }}>Preview</span>
            </div>
            <span className="badge">Illustrative</span>
          </div>
          <div style={{ position: "relative", padding: 22, minHeight: 220 }}>
            <TeaserMock id={id} onOpenRecord={onOpenRecord} />
            <div style={{ position: "absolute", inset: 0, background: "linear-gradient(180deg, transparent 30%, color-mix(in srgb, var(--surface) 86%, transparent))", display: "grid", placeItems: "end center", paddingBottom: 24, pointerEvents: "none" }}>
              <span className="badge" style={{ background: "var(--surface)", boxShadow: "var(--shadow)", borderColor: "var(--border)", fontSize: 12, padding: "7px 12px" }}>
                <Icon name="spark" size={13} style={{ color: "var(--accent)" }} /> Full module arriving soon
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* lightweight, real-data-flavoured mock per feature */
function TeaserMock({ id, onOpenRecord }) {
  const D = window.DATA;
  const bar = (label, val, max, color) => (
    <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 11 }}>
      <div style={{ width: 130, flex: "none", fontSize: 12.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{label}</div>
      <div style={{ flex: 1, height: 11, borderRadius: 6, background: "var(--surface-3)", overflow: "hidden" }}>
        <div style={{ width: (val / max * 100) + "%", height: "100%", background: color, borderRadius: 6 }} />
      </div>
      <div className="mono" style={{ width: 54, textAlign: "right", fontSize: 12, color: "var(--text-muted)" }}>{D.fmtMoney(val)}</div>
    </div>
  );
  if (id === "reports" || id === "impact" || id === "forecast") {
    const doms = D.domains.map((dm) => ({ dm, total: D.orgs.filter((o) => o.domain === dm.id).reduce((s, o) => s + (o.funding ? o.funding.awarded : 0), 0) }));
    const max = Math.max(...doms.map((d) => d.total)) || 1;
    return <div>{doms.map((d) => bar(d.dm.label, d.total, max, domainColor(d.dm.id)))}</div>;
  }
  if (id === "pipeline") {
    const cols = [["Prospect", "Prospect", "var(--warn)"], ["In review", "In review", "var(--info)"], ["Approved", "Approved", "var(--good)"], ["Active", "Active", "var(--accent)"]];
    return (
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 10 }}>
        {cols.map(([label, , c]) => {
          const items = (label === "Prospect" ? D.orgs.filter((o) => o.relationship === "Prospect") : D.projects.filter((p) => p.status === label)).slice(0, 3);
          return (
            <div key={label} style={{ background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 10, padding: 10 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 11.5, fontWeight: 600, marginBottom: 9 }}><span style={{ width: 7, height: 7, borderRadius: 999, background: c }} />{label}</div>
              <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
                {items.map((it, i) => <div key={i} style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 7, padding: "7px 8px", fontSize: 11.5, fontWeight: 550, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{it.name}</div>)}
              </div>
            </div>
          );
        })}
      </div>
    );
  }
  if (id === "tasks" || id === "alerts" || id === "applications") {
    const rows = [
      ["Report due - Lighthouse Learning Trust", "Due in 3 days", "warn"],
      ["Milestone slipping - Haven Therapy Network", "Flagged today", "rose"],
      ["Renewal - The Dispatch Collective", "Next month", "info"],
      ["New application - ReadWell Foundation", "Awaiting review", "good"],
    ];
    const cm = { warn: "var(--warn)", rose: "var(--rose)", info: "var(--info)", good: "var(--good)" };
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 9 }}>
        {rows.map((r, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 10 }}>
            <span style={{ width: 9, height: 9, borderRadius: 999, background: cm[r[2]], flex: "none" }} />
            <span style={{ flex: 1, fontSize: 13, fontWeight: 550 }}>{r[0]}</span>
            <span className="badge">{r[1]}</span>
          </div>
        ))}
      </div>
    );
  }
  if (id === "workflows" || id === "integrations") {
    const steps = id === "workflows"
      ? [["bolt", "When grant approved"], ["receipt", "Create payment schedule"], ["bell", "Notify handler"], ["calendar", "Schedule check-in"]]
      : [["building", "Your CRM"], ["receipt", "Accounting"], ["mail", "Email"], ["calendar", "Calendar"]];
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
        {steps.map(([ic, label], i) => (
          <React.Fragment key={i}>
            <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "11px 14px", background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 11 }}>
              <div style={{ width: 30, height: 30, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name={ic} size={15} /></div>
              <span style={{ fontSize: 12.5, fontWeight: 600 }}>{label}</span>
            </div>
            {i < steps.length - 1 && <Icon name="arrowRight" size={16} style={{ color: "var(--text-faint)" }} />}
          </React.Fragment>
        ))}
      </div>
    );
  }
  if (id === "documents" || id === "audit" || id === "billing") {
    const rows = id === "billing"
      ? [["Pro plan - 12 seats", "Active"], ["Invoice #2026-04", "Paid"], ["Invoice #2026-03", "Paid"]]
      : [["Maya Chen edited Beacon Research Lab", "2h ago"], ["David Okafor approved Data Commons Extension", "Yesterday"], ["Sarah Lindqvist linked Dispatch → Clearview", "2 days ago"]];
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {rows.map((r, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 10 }}>
            <Icon name={id === "billing" ? "receipt" : "history"} size={15} style={{ color: "var(--text-muted)" }} />
            <span style={{ flex: 1, fontSize: 13 }}>{r[0]}</span>
            <span className="badge">{r[1]}</span>
          </div>
        ))}
      </div>
    );
  }
  // funding default
  const top = D.needsFunding().slice(0, 5);
  const max = Math.max(...top.map((o) => D.orgGap(o))) || 1;
  return <div>{top.map((o) => bar(o.name, D.orgGap(o), max, "var(--accent)"))}</div>;
}

/* ---- accent helpers ---- */
function applyAccent(hex) {
  const r = document.documentElement;
  r.style.setProperty("--accent", hex);
  r.style.setProperty("--accent-press", `color-mix(in srgb, ${hex} 82%, #000)`);
  r.style.setProperty("--accent-contrast", "#ffffff");
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2456cc",
  "theme": "light",
  "density": "regular",
  "mapLayout": "organic",
  "projectsDefault": true,
  "peopleDefault": true,
  "eventsDefault": true
}/*EDITMODE-END*/;

const THEME_ORDER = ["light", "dim", "dark"];
const THEME_META = { light: { icon: "sun", label: "Light" }, dim: { icon: "dim", label: "Dim" }, dark: { icon: "moon", label: "Dark" } };

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [loggedIn, setLoggedIn] = React.useState(false);
  const [route, setRoute] = React.useState("dashboard");
  const [selectedId, setSelectedId] = React.useState(null);
  const [egoFocus, setEgoFocus] = React.useState(null);
  const [layout, setLayout] = React.useState(t.mapLayout);
  const [showProjects, setShowProjects] = React.useState(t.projectsDefault);
  const [showPeople, setShowPeople] = React.useState(t.peopleDefault);
  const [showEvents, setShowEvents] = React.useState(t.eventsDefault);
  const [recents, setRecents] = React.useState(() => {
    try { return JSON.parse(localStorage.getItem("an_recents") || "[]"); } catch (e) { return []; }
  });
  const [collapsed, setCollapsed] = React.useState(false);
  const [dirQuery, setDirQuery] = React.useState(null);
  const [intelSubject, setIntelSubject] = React.useState("o-beacon");
  const [crmProject, setCrmProject] = React.useState(null);
  const [assistantOpen, setAssistantOpen] = React.useState(false);
  const [, force] = React.useReducer((x) => x + 1, 0);

  const theme = THEME_ORDER.includes(t.theme) ? t.theme : "light";
  const userName = "Cristina Koppel";
  const cycleTheme = () => setTweak("theme", THEME_ORDER[(THEME_ORDER.indexOf(theme) + 1) % THEME_ORDER.length]);

  // apply theme + accent + density to document
  React.useEffect(() => { document.documentElement.setAttribute("data-theme", theme); }, [theme]);
  React.useEffect(() => { applyAccent(t.accent); }, [t.accent]);
  React.useEffect(() => {
    const r = document.documentElement.style;
    const map = { compact: ["16px", "12px"], regular: ["26px", "22px"], comfy: ["34px", "28px"] };
    const [pad, gap] = map[t.density] || map.regular;
    r.setProperty("--pad", pad); r.setProperty("--gap", gap);
  }, [t.density]);
  React.useEffect(() => { setLayout(t.mapLayout); }, [t.mapLayout]);
  React.useEffect(() => { setShowProjects(t.projectsDefault); }, [t.projectsDefault]);
  React.useEffect(() => { setShowPeople(t.peopleDefault); }, [t.peopleDefault]);
  React.useEffect(() => { setShowEvents(t.eventsDefault); }, [t.eventsDefault]);

  const pushRecent = (id) => {
    if (!id || id === "funder") return;
    setRecents((prev) => {
      const next = [id, ...prev.filter((x) => x !== id)].slice(0, 12);
      try { localStorage.setItem("an_recents", JSON.stringify(next)); } catch (e) {}
      return next;
    });
  };
  const openRecord = (id) => { setEgoFocus(null); setSelectedId(id); pushRecent(id); };
  const navigate = (r) => { setEgoFocus(null); setRoute(r); if (r !== "directory") setDirQuery(null); };
  const onMutate = () => force();
  const viewConnections = (id) => { setSelectedId(null); setEgoFocus(id); setRoute("map"); };
  const openIntel = (id) => { setSelectedId(null); setEgoFocus(null); if (id) setIntelSubject(id); setRoute("intel"); };
  const openInCRM = (id) => { setSelectedId(null); setCrmProject(id); setRoute("projects"); };

  if (!loggedIn) {
    return (
      <React.Fragment>
        <Login onLogin={() => setLoggedIn(true)} />
        <AppTweaks t={t} theme={theme} setTweak={setTweak} />
      </React.Fragment>
    );
  }

  const navW = collapsed ? 76 : 300;

  return (
    <div style={{ display: "flex", height: "100%", background: "var(--bg)" }}>
      {/* SIDEBAR */}
      <aside style={{ width: navW, flex: "none", display: "flex", flexDirection: "column", borderRight: "1px solid var(--border)", background: "var(--surface)", transition: "width .18s ease" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 11, padding: collapsed ? "18px 0" : "18px 20px", justifyContent: collapsed ? "center" : "flex-start", borderBottom: "1px solid var(--border)", height: 72, flex: "none" }}>
          <Logo size={28} />
          {!collapsed && <div className="display" style={{ fontSize: 19, whiteSpace: "nowrap" }}>Applied Neuroscience</div>}
        </div>

        <nav style={{ flex: 1, overflow: "auto", padding: collapsed ? "14px 12px" : "14px" }}>
          {NAV_SECTIONS.map((sec, si) => (
            <div key={si} style={{ marginBottom: si < NAV_SECTIONS.length - 1 ? 14 : 6 }}>
              {sec.label && (collapsed
                ? <div style={{ height: 1, background: "var(--border)", margin: "12px 4px 10px" }} />
                : <div className="t-eyebrow" style={{ padding: "10px 12px 6px" }}>{sec.label}</div>)}
              {sec.items.map((n) => {
                const isActive = n.action ? false : (route === n.id && !egoFocus);
                return <NavItem key={n.id + (isActive ? "-a" : "-i")} n={n} active={isActive} collapsed={collapsed}
                  onClick={() => { if (n.action === "assistant") setAssistantOpen(true); else navigate(n.id); }} />;
              })}
            </div>
          ))}
          <div style={{ height: 1, background: "var(--border)", margin: "10px 8px 12px" }} />
          {!collapsed && <div className="t-eyebrow" style={{ padding: "0 12px 6px" }}>Admin</div>}
          {NAV_ADMIN.map((n) => <NavItem key={n.id + (route === n.id ? "-a" : "-i")} n={n} active={route === n.id} collapsed={collapsed} onClick={() => navigate(n.id)} />)}
        </nav>

        {/* user */}
        <div style={{ borderTop: "1px solid var(--border)", padding: collapsed ? "14px 0" : "14px", display: "flex", alignItems: "center", gap: 11, justifyContent: collapsed ? "center" : "flex-start" }}>
          <button onClick={() => navigate("settings")} className="focusable" style={{ display: "flex", alignItems: "center", gap: 11, flex: 1, minWidth: 0, border: "none", background: "none", cursor: "pointer", padding: collapsed ? 0 : "5px", borderRadius: 12, justifyContent: collapsed ? "center" : "flex-start" }}>
            <Avatar name={userName} size={38} accent />
            {!collapsed && <div style={{ minWidth: 0, textAlign: "left" }}>
              <div style={{ fontSize: 14, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", color: "var(--text)" }}>{userName}</div>
              <div style={{ fontSize: 12.5, color: "var(--text-muted)" }}>Admin</div>
            </div>}
          </button>
          {!collapsed && <button className="btn btn-icon btn-ghost" title="Log out" onClick={() => setLoggedIn(false)}><Icon name="logout" size={18} /></button>}
        </div>
      </aside>

      {/* MAIN */}
      <div style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }}>
        {/* topbar */}
        <header style={{ display: "flex", alignItems: "center", gap: 16, padding: "0 26px", height: 72, flex: "none", borderBottom: "1px solid var(--border)", background: "var(--surface)", zIndex: 5 }}>
          <button className="btn btn-icon btn-ghost" onClick={() => setCollapsed(!collapsed)} title="Toggle sidebar">
            <Icon name={collapsed ? "chevronRight" : "chevronLeft"} size={20} />
          </button>
          <TopSearch onOpen={openRecord} onSeeAll={(q) => { setDirQuery(q); navigate("directory"); }} />
          <div style={{ flex: 1 }} />
          <button className="btn btn-sm" onClick={() => setAssistantOpen((v) => !v)} title="Ask NeuroAI"
            style={assistantOpen ? { background: "var(--accent-soft)", borderColor: "var(--accent)", color: "var(--accent)" } : {}}>
            <Icon name="spark" size={16} /> Ask AI
          </button>
          <button className="btn btn-icon btn-ghost" onClick={cycleTheme} title={`Theme: ${THEME_META[theme].label} - click to cycle`}>
            <Icon name={THEME_META[theme].icon} size={19} />
          </button>
          <button className="btn btn-icon btn-ghost" title="Notifications"><Icon name="bell" size={19} /></button>
          <div style={{ width: 1, height: 28, background: "var(--border)" }} />
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <Avatar name={userName} size={36} accent />
            <div style={{ lineHeight: 1.15 }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{userName}</div>
              <div style={{ fontSize: 12, color: "var(--text-muted)" }}>test@test.com</div>
            </div>
          </div>
        </header>

        {/* content */}
        <main style={{ position: "relative", flex: 1, minHeight: 0 }}>
          {route === "dashboard" && <Dashboard onOpen={openRecord} onNavigate={navigate} userName={userName} recents={recents} />}
          {route === "map" && !egoFocus && <OrgMap theme={theme} onSelect={openRecord} selectedId={selectedId} showProjects={showProjects} setShowProjects={setShowProjects} showPeople={showPeople} setShowPeople={setShowPeople} showEvents={showEvents} setShowEvents={setShowEvents} layout={layout} setLayout={setLayout} onOpenIntel={openIntel} />}
          {route === "initiatives" && <Initiatives onOpen={openRecord} onNavigate={navigate} />}
          {route === "map" && egoFocus && <PersonalChart focusId={egoFocus} onSelect={openRecord} onClose={() => setEgoFocus(null)} />}
          {route === "intel" && <IntelView subjectId={intelSubject} setSubjectId={setIntelSubject} onExit={() => navigate("map")} onOpenRecord={openRecord} />}
          {route === "directory" && <PeopleCRM onOpen={openRecord} onMutate={onMutate} onViewConnections={viewConnections} onOpenIntel={openIntel} />}
          {route === "orgs" && <OrgsCRM onOpen={openRecord} onMutate={onMutate} onViewConnections={viewConnections} onOpenIntel={openIntel} />}
          {route === "projects" && <ProjectsCRM initialId={crmProject} onOpen={openRecord} onMutate={onMutate} onViewConnections={viewConnections} onOpenIntel={openIntel} />}
          {route === "linkfinder" && <LinkFinder onOpen={openRecord} />}
          {route === "prioritise" && <Prioritisation onOpen={openRecord} onOpenIntel={openIntel} />}
          {route === "reports" && <Reports onOpen={openRecord} onNavigate={navigate} />}
          {route === "events" && <EventsCRM onOpen={openRecord} onViewConnections={viewConnections} onOpenIntel={openIntel} />}
          {route === "booking" && <RoomBooking userName={userName} />}
          {route === "funding" && <FundingHub onOpen={openRecord} />}
          {route === "pipeline" && <GrantPipeline onOpen={openRecord} />}
          {route === "applications" && <ApplicationsView onOpen={openRecord} />}
          {route === "tasks" && <TasksView onOpen={openRecord} userName={userName} />}
          {route === "documents" && <DocumentsView onOpen={openRecord} />}
          {route === "impact" && <ImpactTracker onOpen={openRecord} />}
          {route === "forecast" && <Forecasting onOpen={openRecord} />}
          {route === "workflows" && <WorkflowsView />}
          {route === "alerts" && <AlertsView onOpen={openRecord} />}
          {FEATURES[route] && <FeatureTeaser id={route} title={(NAV_SECTIONS.flatMap((s) => s.items).concat(NAV_ADMIN).find((n) => n.id === route) || {}).label || "Coming soon"} onOpenRecord={openRecord} />}
          {route === "settings" && <Settings theme={theme} onSetTheme={(v) => setTweak("theme", v)} userName={userName} />}
          {route === "admin" && <Admin />}

          {/* GLOBAL RECORD SIDE PANEL */}
          {selectedId && (
            <React.Fragment>
              <div onClick={() => setSelectedId(null)} className="fade-in" style={{ position: "absolute", inset: 0, background: "rgba(10,12,18,0.32)", zIndex: 40 }} />
              <div className="fade-panel" style={{ position: "absolute", top: 0, right: 0, bottom: 0, width: 520, maxWidth: "94vw", zIndex: 41, borderLeft: "1px solid var(--border)", boxShadow: "var(--shadow-lg)" }}>
                <RecordDetail id={selectedId} onOpen={openRecord} onClose={() => setSelectedId(null)} onMutate={onMutate} onViewConnections={viewConnections} onOpenIntel={openIntel} onExpand={openInCRM} />
              </div>
            </React.Fragment>
          )}

          {/* AI ASSISTANT SIDEBAR */}
          <AssistantPanel open={assistantOpen} onClose={() => setAssistantOpen(false)} onOpenRecord={openRecord} />
        </main>
      </div>

      <AppTweaks t={t} theme={theme} setTweak={setTweak} />
    </div>
  );
}

function NavItem({ n, active, collapsed, onClick }) {
  const [hover, setHover] = React.useState(false);
  const bg = active ? "var(--accent-soft)" : (hover ? "var(--surface-2)" : "transparent");
  const col = active ? "var(--accent)" : (n.soon ? "var(--text-faint)" : "var(--text-muted)");
  return (
    <button onClick={onClick} className="navitem focusable" title={collapsed ? n.label : undefined}
      data-active={active ? "true" : "false"}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        display: "flex", alignItems: "center", gap: 12, width: "100%",
        padding: collapsed ? "13px" : "13px 15px", marginBottom: 6, borderRadius: 14,
        border: "none", cursor: "pointer", font: "inherit", fontSize: 15, fontWeight: 570,
        justifyContent: collapsed ? "center" : "flex-start",
        position: "relative",
        background: bg,
        color: col,
      }}>
      <Icon name={n.icon} size={20} stroke={active ? 2 : 1.8} />
      {!collapsed && <span style={{ whiteSpace: "nowrap" }}>{n.label}</span>}
      {!collapsed && n.action && <span className="badge" style={{ marginLeft: "auto", fontSize: 10.5, padding: "3px 8px", background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent" }}>AI</span>}
      {!collapsed && n.soon && <span className="badge" style={{ marginLeft: "auto", fontSize: 10.5, padding: "3px 8px" }}>Soon</span>}
      {active && !collapsed && <span style={{ position: "absolute", left: -14, top: "50%", transform: "translateY(-50%)", width: 3, height: 20, borderRadius: 3, background: "var(--accent)" }} />}
    </button>
  );
}

function AppTweaks({ t, theme, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection label="Brand" />
      <TweakColor label="Accent" value={t.accent}
        options={["#2456cc", "#1f4e79", "#0d6e57", "#9a3412", "#5b3fb5"]}
        onChange={(v) => setTweak("accent", v)} />
      <TweakRadio label="Theme" value={theme} options={["light", "dim", "dark"]} onChange={(v) => setTweak("theme", v)} />
      <TweakSection label="Layout" />
      <TweakSelect label="Map layout" value={t.mapLayout}
        options={["clustered", "radial", "organic"]}
        onChange={(v) => setTweak("mapLayout", v)} />
      <TweakToggle label="Projects on map by default" value={t.projectsDefault} onChange={(v) => setTweak("projectsDefault", v)} />
      <TweakRadio label="Density" value={t.density} options={["compact", "regular", "comfy"]} onChange={(v) => setTweak("density", v)} />
    </TweaksPanel>
  );
}

window.App = App;
