/* Projects CRM - standard master-detail view.
   Left: searchable / filterable list of projects. Right: the full record
   rendered inline (reuses RecordDetail). Exports: ProjectsCRM.          */

function ProjectsCRM({ onOpen, onMutate, onViewConnections, onOpenIntel, initialId }) {
  const D = window.DATA;
  const [q, setQ] = React.useState("");
  const [type, setType] = React.useState("all");
  const [status, setStatus] = React.useState("all");
  const [sel, setSel] = React.useState(initialId || (D.projects[0] ? D.projects[0].id : null));
  const [, force] = React.useReducer((x) => x + 1, 0);
  React.useEffect(() => { if (initialId) setSel(initialId); }, [initialId]);

  const types = ["all", "Grant", "Proposal", "Sponsorship", "Beneficiary", "Conference"];
  const statuses = ["all", "In review", "Approved", "Active", "Planned", "Closed"];
  const rows = D.projects.filter((p) =>
    (type === "all" || p.type === type) &&
    (status === "all" || p.status === status) &&
    (!q || p.name.toLowerCase().includes(q.toLowerCase()) || D.byId[p.org].name.toLowerCase().includes(q.toLowerCase()))
  );

  const handleMutate = () => { force(); onMutate && onMutate(); };
  // clicking a related entity: stay in CRM if it's a project, else open the global slide-over
  const handleOpen = (id) => { if (D.kindOf(id) === "project") setSel(id); else onOpen && onOpen(id); };

  const statusColor = (s) => ({ "Active": "var(--good)", "Approved": "var(--info)", "In review": "var(--warn)", "Planned": "var(--accent)", "Closed": "var(--text-faint)" }[s] || "var(--text-muted)");

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex" }}>
      {/* MASTER LIST */}
      <div style={{ width: 420, flex: "none", display: "flex", flexDirection: "column", borderRight: "1px solid var(--border)", background: "var(--surface)" }}>
        <div style={{ padding: "18px 18px 12px", borderBottom: "1px solid var(--border)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 12 }}>
            <div style={{ width: 28, height: 28, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name="folder" size={16} /></div>
            <div style={{ fontSize: 16, fontWeight: 700, letterSpacing: "-0.01em" }}>Projects</div>
            <span className="badge mono" style={{ marginLeft: "auto" }}>{rows.length}</span>
          </div>
          <div style={{ position: "relative", marginBottom: 10 }}>
            <Icon name="search" size={15} style={{ position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--text-faint)", pointerEvents: "none" }} />
            <input className="input focusable" placeholder="Search projects…" value={q} onChange={(e) => setQ(e.target.value)} style={{ paddingLeft: 32, height: 36, fontSize: 13 }} />
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
            {types.map((t) => {
              const on = type === t;
              return <button key={t} className="tap focusable" onClick={() => setType(t)}
                style={{ font: "inherit", fontSize: 11.5, fontWeight: 550, cursor: "pointer", padding: "4px 9px", borderRadius: 999, border: "1px solid " + (on ? "transparent" : "var(--border)"), background: on ? "var(--accent)" : "var(--surface-2)", color: on ? "var(--accent-contrast)" : "var(--text-muted)" }}>
                {t === "all" ? "All types" : t}
              </button>;
            })}
          </div>
        </div>
        <div style={{ flex: 1, overflow: "auto", padding: 8 }}>
          {rows.map((p) => {
            const org = D.byId[p.org];
            const active = sel === p.id;
            return (
              <button key={p.id} className="focusable" onClick={() => setSel(p.id)}
                style={{ display: "flex", gap: 11, width: "100%", textAlign: "left", padding: "11px 11px", marginBottom: 3, borderRadius: 10, border: "1px solid " + (active ? "var(--accent)" : "transparent"), background: active ? "var(--accent-soft)" : "transparent", cursor: "pointer" }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--surface-2)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}>
                <span style={{ width: 30, height: 30, flex: "none", borderRadius: 8, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--text-muted)" }}><Icon name="folder" size={15} /></span>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: active ? "var(--accent)" : "var(--text)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{p.name}</div>
                  <div style={{ fontSize: 11.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", marginTop: 1 }}>{org.name}</div>
                  <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 5 }}>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 4, fontSize: 10.5, fontWeight: 600, color: statusColor(p.status) }}><span className="statdot" style={{ background: "currentColor" }} />{p.status}</span>
                    <span style={{ fontSize: 10.5, color: "var(--text-faint)" }}>· {p.type} · <span className="mono">{p.year}</span></span>
                  </div>
                </div>
              </button>
            );
          })}
          {rows.length === 0 && <div style={{ padding: 24, textAlign: "center", fontSize: 13, color: "var(--text-faint)" }}>No projects match.</div>}
        </div>
      </div>

      {/* DETAIL */}
      <div style={{ flex: 1, minWidth: 0, position: "relative", background: "var(--bg)" }}>
        {sel ? (
          <ProjectPage key={sel} id={sel} onOpen={handleOpen} onMutate={handleMutate} onViewConnections={onViewConnections} onOpenIntel={onOpenIntel} />
        ) : (
          <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", padding: 40 }}>
            <EmptyState icon="folder" title="Select a project" body="Choose a project from the list to see its full record here." />
          </div>
        )}
      </div>
    </div>
  );
}

/* ---- full-page tabbed project record ---- */
function ProjectPage({ id, onOpen, onMutate, onViewConnections, onOpenIntel, onClose }) {
  const D = window.DATA;
  const e = D.byId[id];
  const [tab, setTab] = React.useState("overview");
  React.useEffect(() => { setTab("overview"); }, [id]);
  if (!e) return null;
  const org = D.byId[e.org];
  const contact = e.contact ? D.byId[e.contact] : null;
  const ev = e.event ? D.byId[e.event] : null;
  const accent = org ? domainColor(org.domain) : "var(--accent)";

  const team = [...new Set([...(e.raci.responsible || []), ...(e.raci.accountable || []), ...(e.raci.consulted || []), ...(e.raci.informed || []), e.contact].filter(Boolean))];
  const docCount = (e.support || []).length + 2;
  const linkCount = 1 + (ev ? 1 : 0) + (org ? (org.linked || []).length : 0);

  const TABS = [
    { id: "overview", label: "Overview", icon: "folder" },
    { id: "members", label: "Members", icon: "users", n: team.length },
    { id: "documents", label: "Documents", icon: "document", n: docCount },
    { id: "links", label: "Links", icon: "link", n: linkCount },
    { id: "activity", label: "Activity", icon: "history" },
  ];

  const Card = ({ title, children, right }) => (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <div className="t-eyebrow">{title}</div>{right}
      </div>
      {children}
    </div>
  );
  const statusColor = ({ "Active": "var(--good)", "Approved": "var(--info)", "In review": "var(--warn)", "Planned": "var(--accent)", "Closed": "var(--text-faint)" }[e.status]) || "var(--text-muted)";
  const fmtD = (d) => new Date(d).toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", background: "var(--bg)" }}>
      {/* header */}
      <div style={{ flex: "none", padding: "20px 26px 0", borderBottom: "1px solid var(--border)", background: "linear-gradient(180deg, var(--surface-2), var(--surface) 70%)" }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 14 }}>
          <div style={{ width: 46, height: 46, flex: "none", borderRadius: 13, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)", border: "1px solid var(--border)" }}><Icon name="folder" size={22} /></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 5, flexWrap: "wrap" }}>
              <span className="badge"><Icon name="folder" size={13} /> Project</span>
              <span className="badge" style={{ color: statusColor, background: "var(--surface-2)" }}><span className="statdot" style={{ background: statusColor }} /> {e.status}</span>
              {e.granteeBadge && <span className="badge" style={{ background: "var(--warn-bg)", color: "var(--warn)", borderColor: "transparent" }}>★ {e.granteeBadge}</span>}
            </div>
            <div className="display" style={{ fontSize: 27, lineHeight: 1.06 }}>{e.name}</div>
            <div style={{ fontSize: 13.5, color: "var(--text-muted)", marginTop: 4 }}>{e.type} · {e.year} · <span style={{ color: "var(--accent)", cursor: "pointer" }} onClick={() => onOpen(org.id)}>{org.name}</span></div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-sm" onClick={() => onViewConnections && onViewConnections(id)}><Icon name="link" size={15} /> Connections</button>
            <button className="btn btn-sm" onClick={() => onOpenIntel && onOpenIntel(id)}><Icon name="target" size={15} /> Intel</button>
          </div>
        </div>
        {/* tabs */}
        <div style={{ display: "flex", gap: 4, marginTop: 16 }}>
          {TABS.map((t) => {
            const on = tab === t.id;
            return (
              <button key={t.id + (on ? "1" : "0")} className="focusable" onClick={() => setTab(t.id)}
                style={{ display: "inline-flex", alignItems: "center", gap: 7, font: "inherit", fontSize: 13.5, fontWeight: 550, cursor: "pointer", padding: "9px 14px", border: "none", borderBottom: "2px solid " + (on ? "var(--accent)" : "transparent"), background: "none", color: on ? "var(--text)" : "var(--text-muted)", marginBottom: -1 }}>
                <Icon name={t.icon} size={15} /> {t.label}
                {t.n != null && <span className="badge mono" style={{ fontSize: 10.5, padding: "1px 6px" }}>{t.n}</span>}
              </button>
            );
          })}
        </div>
      </div>

      {/* body */}
      <div style={{ flex: 1, overflow: "auto", padding: 26 }}>
        <div style={{ maxWidth: 1000, margin: "0 auto" }}>
          {tab === "overview" && (
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }}>
              <Card title="Details">
                <FieldRow label="Parent org" icon="building"><EntityChip id={org.id} onOpen={onOpen} /></FieldRow>
                <FieldRow label="Type" icon="folder">{e.type}</FieldRow>
                <FieldRow label="Dates" icon="calendar"><span className="mono">{fmtD(e.startDate)}</span> → <span className="mono">{fmtD(e.endDate)}</span></FieldRow>
                <FieldRow label="Importance" icon="target"><Meter value={e.importance} invert words={["High: would miss out", "Significant", "Useful", "Nice to have", "Marginal"]} /></FieldRow>
                <FieldRow label="Intensity" icon="bolt"><Meter value={e.intensity} words={["Dormant", "Light", "Steady", "Active", "Intensive"]} color="var(--info)" /></FieldRow>
                <FieldRow label="Reach" icon="map">{e.geoReach}</FieldRow>
                <FieldRow label="Pillar" icon="search"><span className="badge" style={{ background: "var(--surface-2)" }}>{e.pillar}</span></FieldRow>
                <FieldRow label="Subcategory" icon="grid"><span className="badge">{e.subcategory}</span></FieldRow>
                <FieldRow label="Credit" icon="receipt"><span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent" }}>{e.credit}</span></FieldRow>
              </Card>
              <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                <Card title="Grant application">
                  <FieldRow label="Cycle stage" icon="pipeline"><span className="badge" style={{ background: "var(--good-bg)", color: "var(--good)", borderColor: "transparent" }}>{e.cycleStage}</span></FieldRow>
                  <FieldRow label="Applied" icon="calendar"><span className="mono">{fmtD(e.applicationDate)}</span></FieldRow>
                  <FieldRow label="Co-funders" icon="users">
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
                      <span style={{ width: 16, height: 16, borderRadius: 4, display: "grid", placeItems: "center", background: e.coFunders ? "var(--accent)" : "var(--surface-3)", color: "#fff" }}>{e.coFunders ? <Icon name="check" size={11} /> : null}</span>
                      {e.coFunders ? "Yes - shared funding" : "None"}
                    </span>
                  </FieldRow>
                </Card>
                <Card title="Support provided">
                  {(e.support || []).length ? (
                    <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
                      {e.support.map((s) => (
                        <div key={s} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 11px", background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 9 }}>
                          <span style={{ width: 18, height: 18, flex: "none", borderRadius: 5, display: "grid", placeItems: "center", background: "var(--good)", color: "#fff" }}><Icon name="check" size={12} /></span>
                          <span style={{ fontSize: 13, fontWeight: 550 }}>{s}</span>
                        </div>
                      ))}
                    </div>
                  ) : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>No in-kind support recorded.</div>}
                </Card>
                <Card title="Notes"><div style={{ fontSize: 13.5, lineHeight: 1.6, color: "var(--text-muted)" }}>{e.notes}</div></Card>
              </div>
            </div>
          )}

          {tab === "members" && (
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <Card title="Main contact">
                {contact ? <PersonPill id={contact.id} onOpen={onOpen} sub /> : <span style={{ fontSize: 13, color: "var(--text-faint)" }}>-</span>}
              </Card>
              <Card title="RACI">
                <div style={{ borderTop: "1px solid var(--border)" }}>
                  <RaciRow label="Responsible" ids={e.raci.responsible} onOpen={onOpen} color="var(--good)" />
                  <RaciRow label="Accountable" ids={e.raci.accountable} onOpen={onOpen} color="var(--accent)" />
                  <RaciRow label="Consulted" ids={e.raci.consulted} onOpen={onOpen} color="var(--info)" />
                  <RaciRow label="Informed" ids={e.raci.informed} onOpen={onOpen} color="var(--warn)" />
                </div>
              </Card>
            </div>
          )}

          {tab === "documents" && (
            <Card title="Filing cabinet" right={<button className="btn btn-sm"><Icon name="plus" size={14} /> Upload</button>}>
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {[
                  [`${e.year} Grant agreement.pdf`, "PDF · 248 KB", "document"],
                  [`Application - ${org.name}.docx`, "DOCX · 86 KB", "document"],
                  ...(e.support || []).map((s) => [`${s} - terms.pdf`, "PDF · 64 KB", "document"]),
                  ["Project brief & budget.xlsx", "XLSX · 132 KB", "document"],
                ].map(([name, meta, ic], i) => (
                  <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 13px", background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 10 }}>
                    <span style={{ width: 34, height: 34, flex: "none", borderRadius: 8, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--accent)" }}><Icon name={ic} size={17} /></span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 550, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{name}</div>
                      <div style={{ fontSize: 11.5, color: "var(--text-faint)" }}>{meta}</div>
                    </div>
                    <button className="btn btn-icon btn-ghost"><Icon name="external" size={15} /></button>
                  </div>
                ))}
              </div>
              <div style={{ marginTop: 14 }}>
                <div className="t-eyebrow" style={{ marginBottom: 8 }}>Links (URL)</div>
                <a href="#" onClick={(ev2) => ev2.preventDefault()} style={{ display: "inline-flex", alignItems: "center", gap: 7, fontSize: 13, color: "var(--accent)", textDecoration: "none" }}><Icon name="link" size={14} /> {org.name.toLowerCase().replace(/[^a-z]/g, "")}.org/{e.year}-report</a>
              </div>
            </Card>
          )}

          {tab === "links" && (
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              <Card title="Related initiative"><ChipWrap><EntityChip id={org.id} onOpen={onOpen} /></ChipWrap></Card>
              {ev && <Card title="Related event"><ChipWrap><EntityChip id={ev.id} onOpen={onOpen} /></ChipWrap></Card>}
              {org && (org.linked || []).length > 0 && (
                <Card title="Linked organisations"><ChipWrap>{org.linked.map((l) => <EntityChip key={l} id={l} onOpen={onOpen} />)}</ChipWrap></Card>
              )}
              <Card title="People"><ChipWrap>{team.map((pid) => <PersonPill key={pid} id={pid} onOpen={onOpen} />)}</ChipWrap></Card>
            </div>
          )}

          {tab === "activity" && (
            <Card title="Activity">
              <div style={{ display: "flex", flexDirection: "column" }}>
                {[
                  ["check", "Status set to " + e.status, "Today"],
                  ["receipt", "Cycle stage: " + e.cycleStage, "2 weeks ago"],
                  ["document", "Grant agreement uploaded", "1 month ago"],
                  ["user", (contact ? contact.name : "Contact") + " added as main contact", "2 months ago"],
                  ["folder", "Project created", fmtD(e.applicationDate)],
                ].map((a, i, arr) => (
                  <div key={i} style={{ display: "flex", gap: 12, paddingBottom: 16 }}>
                    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", flex: "none" }}>
                      <div style={{ width: 30, height: 30, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--text-muted)", zIndex: 1 }}><Icon name={a[0]} size={14} /></div>
                      {i < arr.length - 1 && <div style={{ width: 1.5, flex: 1, background: "var(--border)", marginTop: 2 }} />}
                    </div>
                    <div style={{ paddingTop: 5 }}>
                      <div style={{ fontSize: 13.5 }}>{a[1]}</div>
                      <div style={{ fontSize: 11.5, color: "var(--text-faint)", marginTop: 1 }}>{a[2]}</div>
                    </div>
                  </div>
                ))}
              </div>
            </Card>
          )}
        </div>
      </div>
    </div>
  );
}

window.ProjectsCRM = ProjectsCRM;
window.ProjectPage = ProjectPage;

/* ================= EVENTS CRM (mirrors Projects exactly) ================= */
function EventsCRM({ onOpen, onMutate, onViewConnections, onOpenIntel, initialId }) {
  const D = window.DATA;
  const [q, setQ] = React.useState("");
  const [when, setWhen] = React.useState("all");
  const sorted = [...D.events].sort((a, b) => new Date(b.date) - new Date(a.date));
  const [sel, setSel] = React.useState(initialId || (sorted[0] ? sorted[0].id : null));
  React.useEffect(() => { if (initialId) setSel(initialId); }, [initialId]);
  const now = new Date();
  const whenOpts = ["all", "upcoming", "past"];
  const rows = sorted.filter((ev) => {
    const isUp = new Date(ev.date) >= now;
    return (when === "all" || (when === "upcoming" ? isUp : !isUp)) &&
      (!q || ev.name.toLowerCase().includes(q.toLowerCase()));
  });
  const handleOpen = (id) => { if (D.kindOf(id) === "event") setSel(id); else onOpen && onOpen(id); };

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex" }}>
      {/* MASTER LIST */}
      <div style={{ width: 420, flex: "none", display: "flex", flexDirection: "column", borderRight: "1px solid var(--border)", background: "var(--surface)" }}>
        <div style={{ padding: "18px 18px 12px", borderBottom: "1px solid var(--border)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 12 }}>
            <div style={{ width: 28, height: 28, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name="calendar" size={16} /></div>
            <div style={{ fontSize: 16, fontWeight: 700, letterSpacing: "-0.01em" }}>Events</div>
            <span className="badge mono" style={{ marginLeft: "auto" }}>{rows.length}</span>
          </div>
          <div style={{ position: "relative", marginBottom: 10 }}>
            <Icon name="search" size={15} style={{ position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--text-faint)", pointerEvents: "none" }} />
            <input className="input focusable" placeholder="Search events…" value={q} onChange={(e) => setQ(e.target.value)} style={{ paddingLeft: 32, height: 36, fontSize: 13 }} />
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
            {whenOpts.map((t) => {
              const on = when === t;
              return <button key={t} className="tap focusable" onClick={() => setWhen(t)}
                style={{ font: "inherit", fontSize: 11.5, fontWeight: 550, cursor: "pointer", padding: "4px 9px", borderRadius: 999, border: "1px solid " + (on ? "transparent" : "var(--border)"), background: on ? "var(--accent)" : "var(--surface-2)", color: on ? "var(--accent-contrast)" : "var(--text-muted)" }}>
                {t === "all" ? "All" : t === "upcoming" ? "Upcoming" : "Past"}
              </button>;
            })}
          </div>
        </div>
        <div style={{ flex: 1, overflow: "auto", padding: 8 }}>
          {rows.map((ev) => {
            const active = sel === ev.id;
            const d = new Date(ev.date);
            const isUp = d >= now;
            return (
              <button key={ev.id} className="focusable" onClick={() => setSel(ev.id)}
                style={{ display: "flex", gap: 11, width: "100%", textAlign: "left", padding: "11px 11px", marginBottom: 3, borderRadius: 10, border: "1px solid " + (active ? "var(--accent)" : "transparent"), background: active ? "var(--accent-soft)" : "transparent", cursor: "pointer" }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--surface-2)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}>
                <span style={{ width: 38, flex: "none", textAlign: "center", padding: "5px 0", borderRadius: 8, background: "var(--surface-3)", color: "var(--text-muted)" }}>
                  <span className="mono" style={{ display: "block", fontSize: 14, fontWeight: 600, lineHeight: 1 }}>{d.getDate()}</span>
                  <span style={{ fontSize: 9, textTransform: "uppercase" }}>{d.toLocaleDateString("en-GB", { month: "short" })}</span>
                </span>
                <div style={{ minWidth: 0, flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: active ? "var(--accent)" : "var(--text)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{ev.name}</div>
                  <div style={{ fontSize: 11.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", marginTop: 1 }}>{(ev.orgs || []).length} orgs · {(ev.attendees || []).length} attendees</div>
                  <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 5 }}>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 4, fontSize: 10.5, fontWeight: 600, color: isUp ? "var(--accent)" : "var(--text-faint)" }}><span className="statdot" style={{ background: "currentColor" }} />{isUp ? "Upcoming" : "Past"}</span>
                    <span style={{ fontSize: 10.5, color: "var(--text-faint)" }}>· <span className="mono">{d.getFullYear()}</span></span>
                  </div>
                </div>
              </button>
            );
          })}
          {rows.length === 0 && <div style={{ padding: 24, textAlign: "center", fontSize: 13, color: "var(--text-faint)" }}>No events match.</div>}
        </div>
      </div>

      {/* DETAIL */}
      <div style={{ flex: 1, minWidth: 0, position: "relative", background: "var(--bg)" }}>
        {sel ? (
          <EventPage key={sel} id={sel} onOpen={handleOpen} onViewConnections={onViewConnections} onOpenIntel={onOpenIntel} />
        ) : (
          <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", padding: 40 }}>
            <EmptyState icon="calendar" title="Select an event" body="Choose an event from the list to see its full record here." />
          </div>
        )}
      </div>
    </div>
  );
}

/* ---- full-page tabbed event record (mirrors ProjectPage) ---- */
function EventPage({ id, onOpen, onViewConnections, onOpenIntel }) {
  const D = window.DATA;
  const e = D.byId[id];
  const [tab, setTab] = React.useState("overview");
  React.useEffect(() => { setTab("overview"); }, [id]);
  if (!e) return null;
  const d = new Date(e.date);
  const isUp = d >= new Date();
  const orgs = (e.orgs || []).map((o) => D.byId[o]).filter(Boolean);
  const attendees = (e.attendees || []).map((p) => D.byId[p]).filter(Boolean);
  const relProjects = D.projects.filter((p) => p.event === id);
  const fmtD = (x) => new Date(x).toLocaleDateString("en-GB", { weekday: "short", day: "2-digit", month: "short", year: "numeric" });

  const rsvpMeta = {
    Attended: { c: "var(--good)", bg: "var(--good-bg)", icon: "check" },
    Yes: { c: "var(--info)", bg: "var(--info-bg)", icon: "check" },
    Regrets: { c: "var(--text-muted)", bg: "var(--surface-2)", icon: "x" },
    Invited: { c: "var(--warn)", bg: "var(--warn-bg)", icon: "clock" },
  };

  const TABS = [
    { id: "overview", label: "Overview", icon: "calendar" },
    { id: "attendees", label: "Attendees", icon: "users", n: attendees.length },
    { id: "orgs", label: "Organisations", icon: "building", n: orgs.length },
    { id: "links", label: "Links", icon: "link", n: relProjects.length },
    { id: "activity", label: "Activity", icon: "history" },
  ];
  const Card = ({ title, children, right }) => (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}><div className="t-eyebrow">{title}</div>{right}</div>
      {children}
    </div>
  );
  const statusColor = isUp ? "var(--accent)" : "var(--text-faint)";

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", background: "var(--bg)" }}>
      {/* header */}
      <div style={{ flex: "none", padding: "20px 26px 0", borderBottom: "1px solid var(--border)", background: "linear-gradient(180deg, var(--surface-2), var(--surface) 70%)" }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 14 }}>
          <div style={{ width: 46, height: 46, flex: "none", borderRadius: 13, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)", border: "1px solid var(--border)" }}><Icon name="calendar" size={22} /></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 5, flexWrap: "wrap" }}>
              <span className="badge"><Icon name="calendar" size={13} /> Event</span>
              <span className="badge" style={{ color: statusColor, background: "var(--surface-2)" }}><span className="statdot" style={{ background: statusColor }} /> {isUp ? "Upcoming" : "Past"}</span>
            </div>
            <div className="display" style={{ fontSize: 27, lineHeight: 1.06 }}>{e.name}</div>
            <div style={{ fontSize: 13.5, color: "var(--text-muted)", marginTop: 4 }}>{fmtD(e.date)} · {attendees.length} attendees · {orgs.length} organisations</div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-sm" onClick={() => onViewConnections && onViewConnections(id)}><Icon name="link" size={15} /> Connections</button>
            <button className="btn btn-sm" onClick={() => onOpenIntel && onOpenIntel(id)}><Icon name="target" size={15} /> Intel</button>
          </div>
        </div>
        {/* tabs */}
        <div style={{ display: "flex", gap: 4, marginTop: 16 }}>
          {TABS.map((t) => {
            const on = tab === t.id;
            return (
              <button key={t.id + (on ? "1" : "0")} className="focusable" onClick={() => setTab(t.id)}
                style={{ display: "inline-flex", alignItems: "center", gap: 7, font: "inherit", fontSize: 13.5, fontWeight: 550, cursor: "pointer", padding: "9px 14px", border: "none", borderBottom: "2px solid " + (on ? "var(--accent)" : "transparent"), background: "none", color: on ? "var(--text)" : "var(--text-muted)", marginBottom: -1 }}>
                <Icon name={t.icon} size={15} /> {t.label}
                {t.n != null && <span className="badge mono" style={{ fontSize: 10.5, padding: "1px 6px" }}>{t.n}</span>}
              </button>
            );
          })}
        </div>
      </div>

      {/* body */}
      <div style={{ flex: 1, overflow: "auto", padding: 26 }}>
        <div style={{ maxWidth: 1000, margin: "0 auto" }}>
          {tab === "overview" && (
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }}>
              <Card title="Details">
                <FieldRow label="Date" icon="calendar"><span className="mono">{fmtD(e.date)}</span></FieldRow>
                <FieldRow label="Status" icon="bolt"><span className="badge" style={{ color: statusColor, background: "var(--surface-2)" }}>{isUp ? "Upcoming" : "Past"}</span></FieldRow>
                <FieldRow label="Attendees" icon="users">{attendees.length}</FieldRow>
                <FieldRow label="Organisations" icon="building">{orgs.length}</FieldRow>
              </Card>
              <Card title="About"><div style={{ fontSize: 13.5, lineHeight: 1.6, color: "var(--text-muted)" }}>{e.notes || "-"}</div></Card>
              <Card title="Attendees" right={<span className="badge mono">{attendees.length}</span>}>
                {attendees.length ? <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                  {attendees.slice(0, 8).map((p) => (
                    <button key={p.id} className="focusable" onClick={() => onOpen(p.id)} style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "6px 11px 6px 6px", border: "1px solid var(--border)", borderRadius: 999, background: "var(--surface-2)", cursor: "pointer", font: "inherit" }}>
                      {p.photo ? <Portrait p={p} w={24} h={24} radius={999} /> : <Avatar name={p.name} size={24} accent={p.team} />}
                      <span style={{ fontSize: 12.5, fontWeight: 550 }}>{p.name}</span>
                    </button>
                  ))}
                  {attendees.length > 8 && <span style={{ display: "inline-flex", alignItems: "center", padding: "0 6px", fontSize: 12.5, color: "var(--text-muted)" }}>+{attendees.length - 8} more</span>}
                </div> : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>No attendees recorded.</div>}
              </Card>
              <Card title="Organisations" right={<span className="badge mono">{orgs.length}</span>}>
                {orgs.length ? <ChipWrap>{orgs.map((o) => <EntityChip key={o.id} id={o.id} onOpen={onOpen} />)}</ChipWrap> : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>None.</div>}
              </Card>
            </div>
          )}

          {tab === "attendees" && (
            <Card title={`Attendees (${attendees.length})`}>
              {attendees.length ? <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {attendees.map((p) => {
                  const org = p.org ? D.byId[p.org] : null;
                  const st = (p.rsvp && p.rsvp[id]) || "Attended"; const sm = rsvpMeta[st] || rsvpMeta.Invited;
                  return (
                    <button key={p.id} className="focusable" onClick={() => onOpen(p.id)} style={{ display: "flex", alignItems: "center", gap: 11, padding: "9px 11px", border: "1px solid var(--border)", borderRadius: 10, background: "var(--surface-2)", cursor: "pointer", textAlign: "left" }}>
                      {p.photo ? <Portrait p={p} w={34} h={34} radius={999} /> : <Avatar name={p.name} size={34} accent={p.team} />}
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 13.5, fontWeight: 600 }}>{p.name}</div>
                        <div style={{ fontSize: 11.5, color: "var(--text-muted)" }}>{p.title}{org ? " · " + org.name : p.team ? " · Wellspring Fund" : ""}</div>
                      </div>
                      <span className="badge" style={{ flex: "none", background: sm.bg, color: sm.c, borderColor: "transparent" }}><Icon name={sm.icon} size={11} /> {st}</span>
                    </button>
                  );
                })}
              </div> : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>No attendees recorded.</div>}
            </Card>
          )}

          {tab === "orgs" && (
            <Card title={`Organisations (${orgs.length})`}>
              {orgs.length ? <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {orgs.map((o) => (
                  <button key={o.id} className="focusable" onClick={() => onOpen(o.id)} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", border: "1px solid var(--border)", borderRadius: 10, background: "var(--surface-2)", cursor: "pointer", textAlign: "left" }}>
                    <span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(o.domain), flex: "none" }} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 600 }}>{o.name}</div>
                      <div style={{ fontSize: 12, color: "var(--text-muted)" }}>{o.relationship} · {o.geography}</div>
                    </div>
                    <Icon name="chevronRight" size={16} style={{ color: "var(--text-faint)" }} />
                  </button>
                ))}
              </div> : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>None.</div>}
            </Card>
          )}

          {tab === "links" && (
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              {relProjects.length > 0 && <Card title="Related projects"><ChipWrap>{relProjects.map((p) => <EntityChip key={p.id} id={p.id} onOpen={onOpen} />)}</ChipWrap></Card>}
              <Card title="Organisations"><ChipWrap>{orgs.map((o) => <EntityChip key={o.id} id={o.id} onOpen={onOpen} />)}</ChipWrap></Card>
              <Card title="People"><ChipWrap>{attendees.map((p) => <PersonPill key={p.id} id={p.id} onOpen={onOpen} />)}</ChipWrap></Card>
            </div>
          )}

          {tab === "activity" && (
            <Card title="Activity">
              <div style={{ display: "flex", flexDirection: "column" }}>
                {[
                  [isUp ? "clock" : "check", isUp ? "Event scheduled" : "Event took place", fmtD(e.date)],
                  ["users", attendees.length + " attendees confirmed", "2 weeks before"],
                  ["building", orgs.length + " organisations involved", "1 month before"],
                  ["calendar", "Event created", "Earlier"],
                ].map((a, i, arr) => (
                  <div key={i} style={{ display: "flex", gap: 12, paddingBottom: 16 }}>
                    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", flex: "none" }}>
                      <div style={{ width: 30, height: 30, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--surface-3)", color: "var(--text-muted)", zIndex: 1 }}><Icon name={a[0]} size={14} /></div>
                      {i < arr.length - 1 && <div style={{ width: 1.5, flex: 1, background: "var(--border)", marginTop: 2 }} />}
                    </div>
                    <div style={{ paddingTop: 5 }}>
                      <div style={{ fontSize: 13.5 }}>{a[1]}</div>
                      <div style={{ fontSize: 11.5, color: "var(--text-faint)", marginTop: 1 }}>{a[2]}</div>
                    </div>
                  </div>
                ))}
              </div>
            </Card>
          )}
        </div>
      </div>
    </div>
  );
}

window.EventsCRM = EventsCRM;
window.EventPage = EventPage;
