/* ============================================================
   PULSE — Shared components, icons, demo data, API layer
   Globals exposed at end.
   ============================================================ */

const { useState, useEffect, useRef, useMemo } = React;

/* ------------------------------ API layer ------------------------------ */
const api = {
  _token: () => localStorage.getItem("pulse:token") || "",

  async login(email, password) {
    const r = await fetch("/api/auth/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    if (!r.ok) {
      const err = await r.json().catch(() => ({}));
      throw new Error(err.detail || "Login failed");
    }
    return r.json();
  },

  async get(path) {
    const r = await fetch(path, {
      headers: { Authorization: `Bearer ${this._token()}` },
    });
    if (r.status === 401) {
      localStorage.removeItem("pulse:token");
      window.dispatchEvent(new Event("pulse:logout"));
      throw new Error("Unauthorized");
    }
    if (!r.ok) throw new Error(`HTTP ${r.status}`);
    return r.json();
  },

  async put(path, body) {
    const r = await fetch(path, {
      method: "PUT",
      headers: { Authorization: `Bearer ${this._token()}`, "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (!r.ok) throw new Error(`HTTP ${r.status}`);
    return r.json();
  },

  async post(path, body) {
    const r = await fetch(path, {
      method: "POST",
      headers: { Authorization: `Bearer ${this._token()}`, "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (!r.ok) throw new Error(`HTTP ${r.status}`);
    return r.json();
  },

  streamRun(runId, onEvent) {
    const token = this._token();
    const es = new EventSource(`/api/generate/${runId}/stream?token=${encodeURIComponent(token)}`);
    es.onmessage = (e) => {
      try {
        const data = JSON.parse(e.data);
        onEvent(data);
        if (data.done) es.close();
      } catch (_) {}
    };
    es.onerror = () => es.close();
    return es;
  },
};

/* ------------------------------ Timezone (global) ------------------------------ */
let _appTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
function appTz() { return _appTz; }
function setAppTz(tz) { if (tz) _appTz = tz; }

/* ------------------------------ Icons (lucide-style, stroked) ------------------------------ */
const iconProps = { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round" };
const I = {
  Pulse: (p) => <svg {...iconProps} {...p}><path d="M22 12h-4l-3 9L9 3l-3 9H2" /></svg>,
  Home:  (p) => <svg {...iconProps} {...p}><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2h-4v-7h-6v7H5a2 2 0 0 1-2-2z"/></svg>,
  Play:  (p) => <svg {...iconProps} {...p}><polygon points="5 3 19 12 5 21 5 3"/></svg>,
  Archive:(p) => <svg {...iconProps} {...p}><path d="M21 8v13H3V8"/><rect x="1" y="3" width="22" height="5"/><line x1="10" y1="12" x2="14" y2="12"/></svg>,
  Settings:(p)=> <svg {...iconProps} {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09c0 .67.39 1.26 1 1.51a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82c.25.61.84 1 1.51 1H21a2 2 0 1 1 0 4h-.09c-.67 0-1.26.39-1.51 1z"/></svg>,
  Search:(p) => <svg {...iconProps} {...p}><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>,
  Plus:(p) => <svg {...iconProps} {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>,
  Check:(p) => <svg {...iconProps} {...p}><polyline points="20 6 9 17 4 12"/></svg>,
  X:(p) => <svg {...iconProps} {...p}><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>,
  ChevRight:(p) => <svg {...iconProps} {...p}><polyline points="9 18 15 12 9 6"/></svg>,
  ChevDown:(p) => <svg {...iconProps} {...p}><polyline points="6 9 12 15 18 9"/></svg>,
  ArrowRight:(p) => <svg {...iconProps} {...p}><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>,
  ArrowUpRight:(p) => <svg {...iconProps} {...p}><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></svg>,
  Download:(p) => <svg {...iconProps} {...p}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>,
  Share:(p) => <svg {...iconProps} {...p}><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>,
  Calendar:(p) => <svg {...iconProps} {...p}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>,
  Clock:(p) => <svg {...iconProps} {...p}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>,
  Filter:(p) => <svg {...iconProps} {...p}><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>,
  Trend:(p) => <svg {...iconProps} {...p}><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></svg>,
  Alert:(p) => <svg {...iconProps} {...p}><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>,
  Shield:(p) => <svg {...iconProps} {...p}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>,
  History:(p) => <svg {...iconProps} {...p}><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/><polyline points="12 7 12 12 15 14"/></svg>,
  File:(p) => <svg {...iconProps} {...p}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>,
  Moon:(p) => <svg {...iconProps} {...p}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>,
  Sun:(p) => <svg {...iconProps} {...p}><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>,
  Sliders:(p) => <svg {...iconProps} {...p}><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></svg>,
  Dot:(p) => <svg {...iconProps} {...p}><circle cx="12" cy="12" r="2" fill="currentColor"/></svg>,
  Folder:(p) => <svg {...iconProps} {...p}><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>,
  LogOut:(p) => <svg {...iconProps} {...p}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>,
  Zap:(p) => <svg {...iconProps} {...p}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>,
};

/* ------------------------------ RAG helpers ------------------------------ */
const RAG = {
  red: { cls: "red", label: "RED", pillCls: "pill-red", dotCls: "dot-red" },
  amber: { cls: "amber", label: "AMBER", pillCls: "pill-amber", dotCls: "dot-amber" },
  green: { cls: "green", label: "GREEN", pillCls: "pill-green", dotCls: "dot-green" },
};

function RagDot({ status, withLabel }) {
  const r = RAG[status];
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span className={`dot ${r.dotCls}`}></span>
      {withLabel && <span className="mono text-xs fw-500" style={{ color: `var(--${status})` }}>{r.label}</span>}
    </span>
  );
}

function RagPill({ status }) {
  const r = RAG[status];
  return <span className={`pill ${r.pillCls}`}><span className={`dot ${r.dotCls}`} style={{width:6,height:6,boxShadow:"none"}}></span>{r.label}</span>;
}

/* ------------------------------ Report types ------------------------------ */
const REPORT_TYPES = [
  {
    id: "rag",
    name: "RAG Status",
    shortName: "RAG",
    icon: I.Shield,
    tagline: "Weekly stakeholder-ready narrative with RAG across all workstreams.",
    desc: "Aggregates Jira data into a narrative status report with RAG indicators per workstream. Claude generates executive summary, risks and next-week priorities.",
    runtime: "~55s",
    color: "var(--text)",
  },
  {
    id: "velocity",
    name: "Velocity Anomaly",
    shortName: "Velocity",
    icon: I.Trend,
    tagline: "Time-overrun and burn-rate analysis against estimates.",
    desc: "Detects tasks where logged time exceeds estimate by >15%. Computes per-workstream velocity and flags systemic drift.",
    runtime: "~22s",
    color: "var(--amber)",
  },
  {
    id: "raid",
    name: "RAID Log",
    shortName: "RAID",
    icon: I.Alert,
    tagline: "Risks, Assumptions, Issues, Dependencies — scored & prioritised.",
    desc: "Classifies every open issue into R/A/I/D, scores probability × impact (P1-P3) and outputs a sortable log with owners.",
    runtime: "~34s",
    color: "var(--red)",
  },
  {
    id: "pattern",
    name: "Historical Pattern",
    shortName: "Pattern",
    icon: I.History,
    tagline: "Match current sprint fingerprint to past sprint outcomes.",
    desc: "Compares current velocity/completion/overdue/blocker/bug ratios against historical sprints to detect failed-sprint patterns before they happen.",
    runtime: "~41s",
    color: "var(--blue)",
  },
];

/* ------------------------------ Demo generated reports ------------------------------ */
function mkReport(date, overall, metrics = {}) {
  return {
    date,
    overall,
    generatedAt: `${date} 09:12`,
    author: "maks@pulse.app",
    project: "BuildLog (BL)",
    metrics: {
      totalIssues: 58, done: 16, inProgress: 20, todo: 22,
      overdue: 21, blockers: 3, bugs: 10,
      velocityPct: 23, velocitySp: "84 / 368",
      ...metrics,
    },
    workstreams: [
      { name: "Backend",  rag: overall, velocity: 22, completion: 29, done: "6/21", overdue: 7, blockers: 1, bugs: 3, sp: "34 / 156" },
      { name: "Frontend", rag: overall === "red" ? "red" : "amber", velocity: 31, completion: 30, done: "6/20", overdue: 7, blockers: 0, bugs: 4, sp: "31 / 100" },
      { name: "QA",       rag: overall, velocity: 22, completion: 29, done: "4/14", overdue: 4, blockers: 2, bugs: 1, sp: "19 / 88" },
    ],
  };
}

const DEMO_REPORTS = [
  { id: "r-2026-04-18", type: "rag", ...mkReport("2026-04-18", "red") },
  { id: "v-2026-04-18", type: "velocity", ...mkReport("2026-04-18", "red") },
  { id: "d-2026-04-18", type: "raid", ...mkReport("2026-04-18", "red") },
  { id: "p-2026-04-18", type: "pattern", ...mkReport("2026-04-18", "red") },
  { id: "r-2026-04-11", type: "rag", ...mkReport("2026-04-11", "amber", { velocityPct: 42 }) },
  { id: "v-2026-04-11", type: "velocity", ...mkReport("2026-04-11", "amber", { velocityPct: 42 }) },
  { id: "d-2026-04-11", type: "raid", ...mkReport("2026-04-11", "amber") },
  { id: "p-2026-04-11", type: "pattern", ...mkReport("2026-04-11", "amber") },
  { id: "r-2026-04-04", type: "rag", ...mkReport("2026-04-04", "amber", { velocityPct: 58 }) },
  { id: "v-2026-04-04", type: "velocity", ...mkReport("2026-04-04", "amber", { velocityPct: 58 }) },
  { id: "d-2026-04-04", type: "raid", ...mkReport("2026-04-04", "amber") },
  { id: "p-2026-04-04", type: "pattern", ...mkReport("2026-04-04", "amber") },
  { id: "r-2026-03-28", type: "rag", ...mkReport("2026-03-28", "green", { velocityPct: 82 }) },
  { id: "v-2026-03-28", type: "velocity", ...mkReport("2026-03-28", "green", { velocityPct: 82 }) },
  { id: "d-2026-03-28", type: "raid", ...mkReport("2026-03-28", "green") },
  { id: "p-2026-03-28", type: "pattern", ...mkReport("2026-03-28", "green") },
  { id: "r-2026-03-21", type: "rag", ...mkReport("2026-03-21", "green", { velocityPct: 79 }) },
  { id: "v-2026-03-21", type: "velocity", ...mkReport("2026-03-21", "green", { velocityPct: 79 }) },
];

function reportTypeMeta(typeId) {
  return REPORT_TYPES.find(r => r.id === typeId);
}

/* ------------------------------ Common UI pieces ------------------------------ */

function Logo({ size = 22 }) {
  return (
    <div className="nav-logo" style={{ width: size, height: size, borderRadius: size * 0.27 }}>
      <svg width={size * 0.6} height={size * 0.6} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
        <path d="M22 12h-4l-3 9L9 3l-3 9H2" />
      </svg>
    </div>
  );
}

function Sidebar({ page, onNav, onLogout, unread = 3 }) {
  const items = [
    { id: "dashboard", label: "Dashboard", icon: I.Home },
    { id: "generate", label: "Generate", icon: I.Zap },
    { id: "archive", label: "Archive", icon: I.Archive, count: 42 },
  ];
  const items2 = [
    { id: "settings", label: "Settings", icon: I.Settings },
  ];
  return (
    <div className="nav">
      <div className="nav-brand" style={{ cursor: "pointer" }} onClick={() => onNav("dashboard")}>
        <Logo size={22} />
        <div className="nav-title">Pulse</div>
        <div style={{ marginLeft: "auto", fontSize: 10, color: "var(--text-3)" }} className="mono">v1.0</div>
      </div>
      <div className="nav-project" style={{ cursor: "pointer" }} onClick={() => onNav("dashboard")}>
        <div className="sq"></div>
        <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.2 }}>
          <span style={{ color: "var(--text)", fontWeight: 500 }}>BuildLog</span>
          <span className="mono" style={{ fontSize: 10, color: "var(--text-3)" }}>buildlog001.atlassian.net</span>
        </div>
        <I.ChevDown style={{ marginLeft: "auto", color: "var(--text-3)" }} />
      </div>
      <div className="nav-sections">
        <div className="nav-section">Workspace</div>
        {items.map(it => {
          const Icon = it.icon;
          return (
            <div key={it.id} className={`nav-item ${page === it.id ? "active" : ""}`} onClick={() => onNav(it.id)}>
              <Icon /> {it.label}
              {it.count != null && <span className="count">{it.count}</span>}
            </div>
          );
        })}
        <div className="nav-section" style={{ marginTop: 16 }}>Reports</div>
        {REPORT_TYPES.map(t => {
          const Icon = t.icon;
          return (
            <div key={t.id} className="nav-item" onClick={() => onNav("archive", { type: t.id })}>
              <Icon /> {t.shortName}
            </div>
          );
        })}
        <div className="nav-section" style={{ marginTop: 16 }}>Account</div>
        {items2.map(it => {
          const Icon = it.icon;
          return (
            <div key={it.id} className={`nav-item ${page === it.id ? "active" : ""}`} onClick={() => onNav(it.id)}>
              <Icon /> {it.label}
            </div>
          );
        })}
      </div>
      <div className="nav-footer">
        <div className="avatar" style={{ cursor: "pointer" }} onClick={() => onNav("settings")}>MK</div>
        <div className="who" style={{ cursor: "pointer" }} onClick={() => onNav("settings")}>
          <strong>Maks K.</strong>
          <span>Delivery Manager</span>
        </div>
        <I.LogOut style={{ marginLeft: "auto", color: "var(--text-3)", cursor: "pointer" }} onClick={() => onLogout ? onLogout() : onNav("login")} />
      </div>
    </div>
  );
}

function Topbar({ crumbs, onNav, onOpenCmd, right }) {
  return (
    <div className="topbar">
      <div className="crumbs">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="sep">/</span>}
            <span
              className={i === crumbs.length - 1 ? "current" : ""}
              style={{ cursor: c.to ? "pointer" : "default" }}
              onClick={() => c.to && onNav(c.to)}
            >
              {c.label}
            </span>
          </React.Fragment>
        ))}
      </div>
      <button className="btn btn-ghost btn-sm" onClick={onOpenCmd}>
        <I.Search style={{ width: 14, height: 14 }} />
        <span>Search</span>
        <span className="kbd" style={{ marginLeft: 6 }}>⌘K</span>
      </button>
      {right}
    </div>
  );
}

/* ------------------------------ Sparkline ------------------------------ */
function Sparkline({ values, color = "var(--text)", height = 32, width = 140, showArea = true }) {
  const max = Math.max(...values);
  const min = Math.min(...values);
  const range = max - min || 1;
  const step = width / (values.length - 1);
  const points = values.map((v, i) => `${i * step},${height - ((v - min) / range) * (height - 4) - 2}`).join(" ");
  const areaPath = `0,${height} ${points} ${width},${height}`;
  return (
    <svg width={width} height={height} style={{ display: "block" }}>
      {showArea && <polyline points={areaPath} fill={color} opacity="0.08" stroke="none" />}
      <polyline points={points} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={(values.length - 1) * step} cy={height - ((values[values.length-1] - min) / range) * (height - 4) - 2} r="2.5" fill={color}/>
    </svg>
  );
}

/* ------------------------------ Tweaks panel ------------------------------ */
function TweaksPanel({ open, onClose, theme, setTheme, direction, setDirection, density, setDensity }) {
  if (!open) return null;
  return (
    <div style={{
      position: "fixed", bottom: 20, right: 20, zIndex: 100,
      width: 320, background: "var(--surface)", border: "1px solid var(--border)",
      borderRadius: "var(--r-lg)", boxShadow: "var(--sh-lg)",
      padding: 16, display: "flex", flexDirection: "column", gap: 12
    }}>
      <div className="row">
        <I.Sliders />
        <div className="fw-600">Tweaks</div>
        <div className="spacer"></div>
        <button className="btn btn-ghost btn-sm" onClick={onClose}><I.X style={{ width: 14, height: 14 }} /></button>
      </div>
      <div className="col gap-2">
        <div className="label-xs">Direction</div>
        <div className="row gap-1" style={{ background: "var(--surface-2)", padding: 3, borderRadius: 6 }}>
          {[
            { id: "classic", label: "Classic" },
            { id: "command", label: "Command" },
            { id: "editorial", label: "Editorial" },
          ].map(d => (
            <button key={d.id} onClick={() => setDirection(d.id)} style={{
              flex: 1, padding: "6px 10px", border: "none", borderRadius: 4,
              background: direction === d.id ? "var(--surface)" : "transparent",
              color: direction === d.id ? "var(--text)" : "var(--text-2)",
              fontWeight: direction === d.id ? 500 : 400,
              fontSize: 12, cursor: "pointer",
              boxShadow: direction === d.id ? "var(--sh-sm)" : "none",
            }}>{d.label}</button>
          ))}
        </div>
      </div>
      <div className="col gap-2">
        <div className="label-xs">Theme</div>
        <div className="row gap-1" style={{ background: "var(--surface-2)", padding: 3, borderRadius: 6 }}>
          {[{ id: "light", label: "Light", Icon: I.Sun }, { id: "dark", label: "Dark", Icon: I.Moon }].map(t => (
            <button key={t.id} onClick={() => setTheme(t.id)} style={{
              flex: 1, padding: "6px 10px", border: "none", borderRadius: 4,
              background: theme === t.id ? "var(--surface)" : "transparent",
              color: theme === t.id ? "var(--text)" : "var(--text-2)",
              fontWeight: theme === t.id ? 500 : 400,
              fontSize: 12, cursor: "pointer",
              boxShadow: theme === t.id ? "var(--sh-sm)" : "none",
              display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
            }}><t.Icon style={{ width: 13, height: 13 }} />{t.label}</button>
          ))}
        </div>
      </div>
      <div className="col gap-2">
        <div className="label-xs">Density</div>
        <div className="row gap-1" style={{ background: "var(--surface-2)", padding: 3, borderRadius: 6 }}>
          {[{ id: "comfortable", label: "Comfortable" }, { id: "compact", label: "Compact" }].map(d => (
            <button key={d.id} onClick={() => setDensity(d.id)} style={{
              flex: 1, padding: "6px 10px", border: "none", borderRadius: 4,
              background: density === d.id ? "var(--surface)" : "transparent",
              color: density === d.id ? "var(--text)" : "var(--text-2)",
              fontWeight: density === d.id ? 500 : 400,
              fontSize: 12, cursor: "pointer",
              boxShadow: density === d.id ? "var(--sh-sm)" : "none",
            }}>{d.label}</button>
          ))}
        </div>
      </div>
      <div className="text-xs text-3" style={{ paddingTop: 6, borderTop: "1px solid var(--border)" }}>
        Try each direction — Classic is Linear-like, Command is terminal-dense, Editorial is calm + serif.
      </div>
    </div>
  );
}

/* ------------------------------ Command palette ------------------------------ */
function CommandPalette({ open, onClose, onNav }) {
  const [q, setQ] = useState("");
  const inputRef = useRef(null);
  useEffect(() => { if (open) setTimeout(() => inputRef.current?.focus(), 50); }, [open]);
  if (!open) return null;
  const items = [
    { label: "Go to Dashboard", action: () => onNav("dashboard"), kind: "Navigate", Icon: I.Home },
    { label: "Generate reports", action: () => onNav("generate"), kind: "Action", Icon: I.Zap },
    { label: "Browse archive", action: () => onNav("archive"), kind: "Navigate", Icon: I.Archive },
    { label: "Open settings", action: () => onNav("settings"), kind: "Navigate", Icon: I.Settings },
    ...REPORT_TYPES.map(r => ({ label: `Run ${r.name} report`, action: () => onNav("generate", { preselect: [r.id] }), kind: "Run", Icon: r.icon })),
    ...DEMO_REPORTS.slice(0, 6).map(r => ({
      label: `${reportTypeMeta(r.type).name} — ${r.date}`,
      action: () => onNav("report", { reportId: r.id }),
      kind: "Open",
      Icon: reportTypeMeta(r.type).icon,
    })),
  ];
  const filtered = items.filter(it => it.label.toLowerCase().includes(q.toLowerCase()));
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "var(--overlay)", zIndex: 200,
      display: "flex", alignItems: "flex-start", justifyContent: "center", paddingTop: "12vh"
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: 560, background: "var(--surface)", border: "1px solid var(--border)",
        borderRadius: "var(--r-lg)", boxShadow: "var(--sh-lg)", overflow: "hidden"
      }}>
        <div className="row" style={{ padding: "12px 16px", borderBottom: "1px solid var(--border)" }}>
          <I.Search style={{ color: "var(--text-3)" }} />
          <input ref={inputRef} value={q} onChange={(e) => setQ(e.target.value)}
            placeholder="Search or run a command…"
            style={{ flex: 1, border: "none", outline: "none", background: "transparent", fontSize: 15, color: "var(--text)", fontFamily: "inherit" }} />
          <span className="kbd">ESC</span>
        </div>
        <div style={{ maxHeight: 360, overflowY: "auto", padding: 8 }}>
          {filtered.length === 0 && <div className="text-sm text-3" style={{ padding: 20, textAlign: "center" }}>No matches for "{q}"</div>}
          {filtered.map((it, i) => (
            <div key={i} onClick={() => { it.action(); onClose(); }} style={{
              display: "flex", alignItems: "center", gap: 10,
              padding: "8px 10px", borderRadius: 6, cursor: "pointer", fontSize: 13
            }}
              onMouseEnter={e => e.currentTarget.style.background = "var(--surface-2)"}
              onMouseLeave={e => e.currentTarget.style.background = "transparent"}
            >
              <it.Icon style={{ color: "var(--text-2)" }} />
              <span>{it.label}</span>
              <span className="spacer"></span>
              <span className="label-xs" style={{ letterSpacing: ".04em" }}>{it.kind}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ------------------------------ Export globals ------------------------------ */
Object.assign(window, {
  api,
  I, RAG, RagDot, RagPill,
  REPORT_TYPES, DEMO_REPORTS, reportTypeMeta, mkReport,
  Logo, Sidebar, Topbar, Sparkline, TweaksPanel, CommandPalette,
  useState, useEffect, useRef, useMemo,
});
