/* ===========================================================================
   launch-app.jsx — ARGT Launch Command Center (LCC) shell + Today page.
   Simplified IA: 7 destinations, each a hub with internal tabs that absorb the
   34 reconciled pages. Reuses argt-ds.css tokens + lib.jsx components +
   mock-db.jsx fold seam. Hubs register into window.LCC_PAGES from sibling files.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   IA — the seven destinations. Each accent paints --role-accent for its hub,
   giving the per-section rhythm without inventing colors.
   --------------------------------------------------------------------------- */
const LCC_ACCENTS = {
  magenta: { hex: "#B5006A", bright: "#D8288C" },
  teal:    { hex: "#007A8A", bright: "#10B5C7" },
  purple:  { hex: "#4C1285", bright: "#7A4FBF" },
  amber:   { hex: "#C49800", bright: "#E0B638" },
};
const LCC_NAV = [
  { id: "today",     label: "Today",     icon: "home",      accent: "magenta", desc: "This week" },
  { id: "pipelines", label: "Pipelines", icon: "users",     accent: "teal",    desc: "People & partners" },
  { id: "marketing", label: "Marketing", icon: "megaphone", accent: "purple",  desc: "Comms & content" },
  { id: "finance",   label: "Finance",   icon: "wallet",    accent: "amber",   desc: "Budget & cashflow" },
  { id: "onsite",    label: "On-Site",   icon: "shield",    accent: "magenta", desc: "Festival weekend" },
  { id: "workspace", label: "Workspace", icon: "list",      accent: "teal",    desc: "Team & files" },
  { id: "settings",  label: "Settings",  icon: "gear",      accent: "purple",  desc: "Configuration" },
];
const LCC_TABS = {
  today:     [],
  pipelines: [ { id: "board", label: "Stage board" }, { id: "talent", label: "Talent advance" }, { id: "analytics", label: "Analytics" } ],
  marketing: [ { id: "comms", label: "Comms calendar" }, { id: "studio", label: "Content studio" }, { id: "planners", label: "Planners" }, { id: "public", label: "Public surfaces" } ],
  finance:   [ { id: "overview", label: "Overview" }, { id: "receivables", label: "Money in" }, { id: "payables", label: "Money out" } ],
  onsite:    [ { id: "command", label: "Day-of" }, { id: "crew", label: "Crew call" }, { id: "map", label: "Venue map" }, { id: "incidents", label: "Incidents" }, { id: "weather", label: "Weather" }, { id: "phases", label: "Ticket phases" }, { id: "recap", label: "Recap" } ],
  workspace: [ { id: "team", label: "Team" }, { id: "checklists", label: "Checklists" }, { id: "files", label: "Files" }, { id: "timeline", label: "Timeline" } ],
  settings:  [ { id: "festival", label: "Festival" }, { id: "timeline", label: "Timeline & phases" }, { id: "engines", label: "Engines" }, { id: "roles", label: "Team & roles" }, { id: "integrations", label: "Integrations" }, { id: "alerts", label: "Alerts" }, { id: "branding", label: "Branding" }, { id: "data", label: "Data" } ],
};

/* ---------------------------------------------------------------------------
   Shared helpers — exported to window so hub files reuse them.
   --------------------------------------------------------------------------- */
const ENGINE_COLORS = { social: "#D8288C", digital: "#7A4FBF", sponsors: "#E0B638", tickets: "#10B5C7", content: "#F25BA7", "day-of": "#00A8BC" };
const ENGINE_LABELS = { social: "Social", digital: "Digital", sponsors: "Sponsors", tickets: "Tickets", content: "Content", "day-of": "Day-Of" };
const money = (cents) => "$" + Math.round(cents / 100).toLocaleString();
const moneyK = (cents) => { const neg = cents < 0; const d = Math.abs(cents) / 100; const s = d >= 1000 ? "$" + (d / 1000).toFixed(d >= 10000 ? 0 : 1) + "k" : "$" + Math.round(d); return (neg ? "-" : "") + s; };
const FEST = new Date("2026-09-18T18:00:00-04:00");
const daysToGates = () => Math.max(0, Math.ceil((FEST.getTime() - Date.now()) / 86400000));
const weeksToGates = () => Math.max(0, Math.ceil((FEST.getTime() - Date.now()) / (86400000 * 7)));

const Avatar = ({ name, color, size = 26 }) => (
  <span style={{ width: size, height: size, borderRadius: "50%", flexShrink: 0, display: "grid", placeItems: "center",
    fontFamily: "var(--pvt-font-display)", fontSize: size * 0.42, fontWeight: 700, color: "#0c0a18",
    background: color ? `linear-gradient(135deg, ${color}, var(--accent-purple))` : "linear-gradient(135deg, var(--role-accent), var(--accent-purple))" }}>
    {(name || "?").split(" ").map((w) => w[0]).slice(0, 2).join("")}
  </span>
);

const Bar = ({ pct, color }) => (
  <div style={{ height: 6, borderRadius: 99, background: "var(--pvt-surface-light)", overflow: "hidden" }}>
    <div style={{ height: "100%", width: Math.min(100, pct) + "%", borderRadius: 99, background: color || "var(--role-accent)" }} />
  </div>
);

const EngineChip = ({ ek }) => (
  <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 11, fontWeight: 700, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--pvt-muted)" }}>
    <span style={{ width: 8, height: 8, borderRadius: "50%", background: ENGINE_COLORS[ek] || "var(--pvt-muted)" }} />
    {ENGINE_LABELS[ek] || ek}
  </span>
);

/* Section card with a display heading + optional right action. */
const Section = ({ title, action, children, pad = true, style }) => (
  <div className="card" style={{ padding: pad ? "var(--pad)" : 0, ...style }}>
    {title && (
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, marginBottom: 16, padding: pad ? 0 : "18px 20px 0" }}>
        <h3 style={{ fontFamily: "var(--pvt-font-display)", fontSize: 17, margin: 0, letterSpacing: "-0.01em", whiteSpace: "nowrap" }}>{title}</h3>
        {action}
      </div>
    )}
    {children}
  </div>
);

/* Page scaffold: eyebrow + title + lede + actions, then body. */
const LccPage = ({ eyebrow, title, lede, actions, kpis, children }) => (
  <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 24, flexWrap: "wrap" }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 8, maxWidth: 680 }}>
        {eyebrow && <span className="eyebrow">{eyebrow}</span>}
        <h1 style={{ fontFamily: "var(--pvt-font-display)", fontSize: 32, lineHeight: 1.02, letterSpacing: "-0.02em", margin: 0 }}>{title}</h1>
        {lede && <p style={{ color: "var(--pvt-muted)", fontSize: 14.5, lineHeight: 1.55, margin: 0, textWrap: "pretty" }}>{lede}</p>}
      </div>
      {actions && <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>{actions}</div>}
    </div>
    {kpis && <div className="grid-cols-4">{kpis.map((k, i) => <Kpi key={i} {...k} />)}</div>}
    {children}
  </div>
);

const LccTabs = ({ tabs, active, onChange }) => (
  <div style={{ display: "flex", gap: 6, flexWrap: "wrap", borderBottom: "1px solid var(--pvt-border-light)", paddingBottom: 14 }}>
    {tabs.map((t) => (
      <button key={t.id} onClick={() => onChange(t.id)} className={"pill" + (t.id === active ? " active" : "")}>{t.label}</button>
    ))}
  </div>
);

const act = (msg) => () => { if (window.argtPing) window.argtPing(msg); };
/* Small square action button (edit/delete/etc) — stops row-click propagation. */
const SmallBtn = ({ title, onClick, children, danger, disabled }) => (
  <button title={title} disabled={disabled} onClick={(e) => { e.stopPropagation(); if (!disabled && onClick) onClick(e); }}
    style={{ width: 28, height: 28, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--pvt-surface-light)", border: "1px solid var(--pvt-border-light)", color: danger ? "#F25BA7" : "var(--pvt-text-dim)", cursor: disabled ? "default" : "pointer", fontSize: 14, lineHeight: 1, flexShrink: 0, opacity: disabled ? 0.4 : 1, fontFamily: "var(--pvt-font-body)" }}>{children}</button>
);
const lccInput = () => ({ background: "var(--pvt-surface-mid)", border: "1px solid var(--pvt-border-light)", borderRadius: "var(--r-md)", color: "var(--pvt-text)", padding: "11px 13px", fontSize: 13, fontFamily: "var(--pvt-font-body)", outline: "none", width: "100%" });
const LccField = ({ label, children }) => (
  <label style={{ display: "flex", flexDirection: "column", gap: 6 }}>
    <span style={{ fontSize: 11, color: "var(--pvt-text-dim)", textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 700 }}>{label}</span>
    {children}
  </label>
);
function LccModal({ open, title, onClose, onSubmit, submitLabel = "Save", children }) {
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 520, background: "rgba(8,6,18,0.62)", backdropFilter: "blur(4px)", display: "grid", placeItems: "center", padding: 20 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "min(520px, 96vw)", background: "var(--pvt-surface-raised)", border: "1px solid var(--pvt-border-light)", borderRadius: "var(--r-lg)", boxShadow: "0 32px 80px rgba(0,0,0,0.6)", overflow: "hidden" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 20px", borderBottom: "1px solid var(--pvt-border-light)" }}>
          <h3 style={{ fontFamily: "var(--pvt-font-display)", fontSize: 17, margin: 0 }}>{title}</h3>
          <button onClick={onClose} style={{ background: "none", border: 0, color: "var(--pvt-text-dim)", fontSize: 22, cursor: "pointer", lineHeight: 1 }}>×</button>
        </div>
        <div style={{ padding: 20, display: "flex", flexDirection: "column", gap: 14 }}>{children}</div>
        <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, padding: "0 20px 20px" }}>
          <button className="pill" onClick={onClose}>Cancel</button>
          <button className="pill active" onClick={onSubmit}>{submitLabel}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { LCC_ACCENTS, LCC_NAV, LCC_TABS, ENGINE_COLORS, ENGINE_LABELS, money, moneyK, FEST, daysToGates, weeksToGates, Avatar, Bar, EngineChip, Section, LccPage, LccTabs, act, lccInput, LccField, LccModal, SmallBtn });

/* ===========================================================================
   TODAY  — the daily-driver. Absorbs This Week + Inbox + Engines + Digest.
   =========================================================================== */
function StatusBadge({ status }) {
  const map = { blocked: ["rejected", "Blocked"], doing: ["review", "In progress"], todo: ["draft", "To do"], done: ["approved", "Done"] };
  const [k, l] = map[status] || ["draft", status];
  return <Badge kind={k}>{l}</Badge>;
}

function TaskRow({ task, onCycle, onEdit, onDelete }) {
  const team = window.ARGT_DB.get("launchTeam") || [];
  const owner = team.find((m) => m.name.split(" ")[0] === task.owner) || { name: task.owner };
  return (
    <div className="stat-row" style={{ display: "grid", gridTemplateColumns: "auto 1fr auto auto auto auto", gap: 14, alignItems: "center", cursor: "pointer" }}
         onClick={() => onEdit(task)} title="Click to edit · tap the status to advance it">
      <Avatar name={owner.name} color={owner.color} size={28} />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontFamily: "var(--pvt-font-display)", fontSize: 13.5, lineHeight: 1.25 }}>{task.title}</div>
        <div style={{ display: "flex", gap: 12, marginTop: 3, alignItems: "center" }}><EngineChip ek={task.engine} /><span style={{ fontSize: 11, color: "var(--pvt-text-dim)" }}>{task.kpi}</span></div>
      </div>
      {task.risk === "high" && <span style={{ fontSize: 10, fontWeight: 800, color: "#F25BA7", letterSpacing: "0.06em" }}>HIGH RISK</span>}
      <span style={{ fontSize: 12, color: "var(--pvt-text-dim)", fontFamily: "var(--pvt-font-display)" }}>{task.due}</span>
      <button onClick={(e) => { e.stopPropagation(); onCycle(task.id); }} title="Advance status" style={{ background: "none", border: 0, padding: 0, cursor: "pointer" }}><StatusBadge status={task.status} /></button>
      <SmallBtn title="Delete task" danger onClick={() => onDelete(task.id)}>×</SmallBtn>
    </div>
  );
}

/* Derive an engine's LIVE state from the task list — progress, status, and
   counts are computed, not seeded, so the board never drifts from reality.
   progress = weighted completion (done = 1, in-progress = 0.5) over the
   engine's tasks; status escalates objectively: paused if disabled, attention
   if any task is blocked, else healthy. */
function engineLive(engine, tasks) {
  const list = (tasks || []).filter((t) => t.engine === engine.key);
  const total = list.length;
  const done = list.filter((t) => t.status === "done").length;
  const doing = list.filter((t) => t.status === "doing").length;
  const blocked = list.filter((t) => t.status === "blocked").length;
  const openCount = list.filter((t) => t.status !== "done").length;
  const pct = total ? Math.round((done + doing * 0.5) / total * 100) : 0;
  const status = engine.enabled === false ? "paused" : (blocked > 0 ? "attention" : "healthy");
  return { list, total, done, doing, blocked, openCount, pct, status };
}

function EngineDrawer({ engine, tasks, onClose, onCycle, onEdit, onDelete, onAdd }) {
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, []);
  if (!engine) return null;
  const { list, openCount, blocked, done, total, pct, status } = engineLive(engine, tasks);
  const tone = status === "healthy" ? "#10B5C7" : status === "attention" ? "#E0B638" : "var(--pvt-text-dim)";
  const color = ENGINE_COLORS[engine.key] || "var(--role-accent)";
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 510, background: "rgba(8,6,18,0.55)", backdropFilter: "blur(4px)", display: "flex", justifyContent: "flex-end" }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "min(460px, 96vw)", height: "100%", background: "var(--pvt-surface-raised)", borderLeft: "1px solid var(--pvt-border-light)", boxShadow: "-32px 0 80px rgba(0,0,0,0.5)", display: "flex", flexDirection: "column", animation: "lccDrawerIn 220ms ease" }}>
        <div style={{ padding: "20px 22px 16px", borderBottom: "1px solid var(--pvt-border-light)" }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
            <span style={{ display: "inline-flex", alignItems: "center", gap: 9, fontFamily: "var(--pvt-font-display)", fontSize: 20 }}>
              <span style={{ width: 11, height: 11, borderRadius: "50%", background: color }} />{engine.label} engine
            </span>
            <button onClick={onClose} title="Close" style={{ background: "none", border: 0, color: "var(--pvt-text-dim)", fontSize: 24, cursor: "pointer", lineHeight: 1 }}>×</button>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 12, flexWrap: "wrap" }}>
            <span style={{ fontSize: 10.5, fontWeight: 800, textTransform: "uppercase", letterSpacing: "0.06em", color: tone }}>{status}</span>
            <span style={{ fontSize: 12, color: "var(--pvt-text-dim)" }}>·</span>
            <span style={{ fontSize: 12.5, color: "var(--pvt-muted)" }}>{engine.owner}</span>
            {engine.target && (<><span style={{ fontSize: 12, color: "var(--pvt-text-dim)" }}>·</span><span style={{ fontSize: 12.5, color: "var(--pvt-muted)" }}>{engine.target}</span></>)}
          </div>
          <div style={{ marginTop: 14, display: "flex", alignItems: "center", justifyContent: "space-between", fontSize: 11, color: "var(--pvt-text-dim)", marginBottom: 6 }}>
            <span style={{ textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 700 }}>Task completion</span>
            <span><span style={{ fontFamily: "var(--pvt-font-display)", fontSize: 13, color: "var(--pvt-text)" }}>{pct}%</span> · {done}/{total} done</span>
          </div>
          <Bar pct={pct} color={color} />
          <p style={{ margin: "12px 0 0", fontSize: 12.5, color: "var(--pvt-muted)", lineHeight: 1.5 }}>{engine.note}</p>
          <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
            {[["Open", openCount], ["Blocked", blocked], ["Done", done]].map(([l, n]) => (
              <div key={l} style={{ flex: 1, background: "var(--pvt-surface-mid)", borderRadius: "var(--r-md)", padding: "10px 12px" }}>
                <div style={{ fontFamily: "var(--pvt-font-display)", fontSize: 22, lineHeight: 1, color: l === "Blocked" && n > 0 ? "#F25BA7" : "var(--pvt-text)" }}>{n}</div>
                <div style={{ fontSize: 10.5, color: "var(--pvt-text-dim)", textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 700, marginTop: 4 }}>{l}</div>
              </div>
            ))}
          </div>
        </div>
        <div style={{ flex: 1, overflowY: "auto", padding: "16px 22px" }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
            <span style={{ fontFamily: "var(--pvt-font-display)", fontSize: 15 }}>Tasks</span>
            <button className="pill active" onClick={() => onAdd(engine.key)}>Add task</button>
          </div>
          <div className="stat-rows">
            {list.map((t) => <TaskRow key={t.id} task={t} onCycle={onCycle} onEdit={onEdit} onDelete={onDelete} />)}
            {list.length === 0 && <div style={{ padding: 18, textAlign: "center", fontSize: 12.5, color: "var(--pvt-text-dim)" }}>No tasks on this engine yet. Add the first one above.</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

function TodayPage({ go }) {
  const [tasks, setTasks] = window.useDB("launchTasks");
  const [engines] = window.useDB("launchEngines");
  const [inbox, setInbox] = window.useDB("launchInbox");
  const [phases] = window.useDB("ticketPhases");
  const [cats] = window.useDB("budgetCategories");
  const [showAdd, setShowAdd] = React.useState(false);
  const [mine, setMine] = React.useState(false);
  const [drawerEngine, setDrawerEngine] = React.useState(null);
  const [blockersOnly, setBlockersOnly] = React.useState(false);
  const [editTask, setEditTask] = React.useState(null);
  const [draft, setDraft] = React.useState({ title: "", engine: "social", due: "" });
  const team = window.ARGT_DB.get("launchTeam") || [];

  const order = { blocked: 0, doing: 1, todo: 2, done: 3 };
  const sorted = [...tasks].sort((a, b) => order[a.status] - order[b.status]);
  const blockers = tasks.filter((t) => t.status === "blocked").length;
  const founders = phases.find((p) => p.phase === "Founders") || { sold: 0 };
  const revIn = cats.filter((c) => c.kind === "revenue").reduce((s, c) => s + c.currentCents, 0);
  const revTgt = cats.filter((c) => c.kind === "revenue").reduce((s, c) => s + c.targetCents, 0);

  const cycle = (id) => setTasks((ts) => ts.map((t) => t.id === id ? { ...t, status: ({ blocked: "doing", doing: "done", done: "todo", todo: "blocked" })[t.status] } : t));
  const delTask = (id) => setTasks((ts) => ts.filter((t) => t.id !== id));
  const saveTask = () => { setTasks((ts) => ts.map((t) => t.id === editTask.id ? { ...editTask } : t)); if (window.argtPing) window.argtPing("Task updated"); setEditTask(null); };
  const markRead = (id) => setInbox((xs) => xs.map((x) => x.id === id ? { ...x, readAt: "seen" } : x));
  const addTask = () => {
    if (!draft.title.trim()) return;
    setTasks((ts) => [{ id: "t" + Date.now(), title: draft.title.trim(), engine: draft.engine, owner: "Kam", tMinusWeek: weeksToGates(), due: draft.due || "TBD", status: "todo", kpi: "New", risk: "low" }, ...ts]);
    if (window.argtPing) window.argtPing("Task added");
    setShowAdd(false); setDraft({ title: "", engine: "social", due: "" });
  };
  const openAddForEngine = (key) => { setDraft({ title: "", engine: key, due: "" }); setShowAdd(true); };
  let shown = mine ? sorted.filter((t) => t.owner === "Kam") : sorted;
  if (blockersOnly) shown = shown.filter((t) => t.status === "blocked");

  const kpis = [
    { label: "Days to gates", num: String(daysToGates()), delta: "Sep 18-20, 2026", glyph: "calendar", onClick: () => go && go("onsite", "command") },
    { label: "Open blockers", num: String(blockers), delta: blockersOnly ? "Showing blockers · clear" : (blockers ? "Show blockers" : "All clear"), deltaDir: blockers ? "down" : "up", glyph: "shield", onClick: () => setBlockersOnly((b) => !b) },
    { label: "Founders sold", num: founders.sold + "%", delta: "Open ticket phases", deltaDir: "up", glyph: "ticket", onClick: () => go && go("onsite", "phases") },
    { label: "Revenue in", num: moneyK(revIn), delta: "of " + moneyK(revTgt) + " target", deltaDir: "up", glyph: "wallet", onClick: () => go && go("finance", "overview") },
  ];

  return (
    <LccPage
      eyebrow={"MISSION CONTROL · T-" + weeksToGates() + " WEEKS"}
      title="This week"
      lede="What needs attention now. Blockers float to the top, every engine reports its status, and the change feed catches anything that moved across the platform."
      actions={<><button className={"pill" + (mine ? " active" : "")} onClick={() => setMine((m) => !m)}>Assigned to me</button><button className="pill active" onClick={() => setShowAdd(true)}>Add task</button></>}
      kpis={kpis}
    >
      <div style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) 340px", gap: 20, alignItems: "start" }}>
        {/* main */}
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <Section title="Today's tasks" action={blockersOnly ? <button className="pill" onClick={() => setBlockersOnly(false)}>Clear filter</button> : <span className="micro">{tasks.filter((t) => t.status !== "done").length} OPEN</span>}>
            <div className="stat-rows">{shown.map((t) => <TaskRow key={t.id} task={t} onCycle={cycle} onEdit={setEditTask} onDelete={delTask} />)}{shown.length === 0 && <div style={{ padding: 18, textAlign: "center", fontSize: 12.5, color: "var(--pvt-text-dim)" }}>No tasks match this filter.</div>}</div>
          </Section>

          <Section title="Engines" action={<span className="micro">{engines.filter((e) => engineLive(e, tasks).status === "healthy").length + "/" + engines.length + " HEALTHY"}</span>}>
            <div className="grid-cols-3">
              {engines.map((e) => {
                const L = engineLive(e, tasks);
                const tone = L.status === "healthy" ? "#10B5C7" : L.status === "attention" ? "#E0B638" : "var(--pvt-text-dim)";
                return (
                  <div key={e.key} onClick={() => setDrawerEngine(e.key)} title={"Open the " + e.label + " engine"} style={{ background: "var(--pvt-surface-mid)", borderRadius: "var(--r-md)", padding: 14, display: "flex", flexDirection: "column", gap: 10, border: "1px solid var(--pvt-border-light)", cursor: "pointer", transition: "border-color 140ms, transform 140ms" }}
                       onMouseEnter={(ev) => { ev.currentTarget.style.borderColor = "var(--role-accent)"; ev.currentTarget.style.transform = "translateY(-2px)"; }}
                       onMouseLeave={(ev) => { ev.currentTarget.style.borderColor = "var(--pvt-border-light)"; ev.currentTarget.style.transform = "none"; }}>
                    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                      <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontFamily: "var(--pvt-font-display)", fontSize: 14 }}>
                        <span style={{ width: 9, height: 9, borderRadius: "50%", background: ENGINE_COLORS[e.key] }} />{e.label}
                      </span>
                      <span style={{ fontSize: 10, fontWeight: 800, textTransform: "uppercase", letterSpacing: "0.06em", color: tone }}>{L.status}</span>
                    </div>
                    <Bar pct={L.pct} color={ENGINE_COLORS[e.key]} />
                    <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--pvt-text-dim)" }}>
                      <span>{L.openCount} open</span><span>{e.owner}</span>
                    </div>
                    <p style={{ margin: 0, fontSize: 11.5, color: "var(--pvt-muted)", lineHeight: 1.4 }}>{e.note}</p>
                  </div>
                );
              })}
            </div>
          </Section>
        </div>

        {/* right rail */}
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div className="card" style={{ background: "linear-gradient(135deg, color-mix(in srgb, var(--role-accent) 24%, var(--pvt-surface)), var(--pvt-surface))", borderColor: "var(--role-accent)" }}>
            <span className="eyebrow">COUNTDOWN</span>
            <div style={{ fontFamily: "var(--pvt-font-display)", fontSize: 52, lineHeight: 1, letterSpacing: "-0.03em", margin: "6px 0 2px" }}>{daysToGates()}<span style={{ fontSize: 18, color: "var(--pvt-text-dim)", marginLeft: 8 }}>days</span></div>
            <div style={{ fontSize: 12.5, color: "var(--pvt-muted)" }}>to gates · Harbour Pointe, Fort Pierce</div>
          </div>

          <Section title="What changed" action={<span className="micro">{inbox.filter((i) => !i.readAt).length} NEW</span>}>
            <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
              {inbox.map((n) => (
                <div key={n.id} onClick={() => markRead(n.id)} style={{ display: "flex", gap: 10, padding: "10px 6px", cursor: "pointer", borderRadius: 10, background: n.readAt ? "transparent" : "var(--pvt-surface-mid)" }}>
                  <span style={{ width: 7, height: 7, borderRadius: "50%", marginTop: 6, flexShrink: 0, background: n.priority === "high" ? "#F25BA7" : n.readAt ? "var(--pvt-text-dim)" : "var(--role-accent-bright)" }} />
                  <div style={{ minWidth: 0, flex: 1 }}>
                    <div style={{ fontSize: 12.5, lineHeight: 1.35, color: "var(--pvt-text)" }}>{n.summary}</div>
                    <div style={{ fontSize: 10.5, color: "var(--pvt-text-dim)", marginTop: 2, textTransform: "uppercase", letterSpacing: "0.05em" }}>{n.kind} · {n.at}</div>
                  </div>
                </div>
              ))}
            </div>
          </Section>

          <Section title="Weekly digest">
            <p style={{ margin: "0 0 12px", fontSize: 12.5, color: "var(--pvt-muted)", lineHeight: 1.5 }}>
              {blockers} blocker{blockers === 1 ? "" : "s"} this week, {tasks.filter((t) => t.status === "done").length} task{tasks.filter((t) => t.status === "done").length === 1 ? "" : "s"} closed.
              Founders phase at {founders.sold}%. {(() => {
                const atRisk = engines.filter((e) => engineLive(e, tasks).status === "attention").map((e) => e.label);
                if (!atRisk.length) return "No engines are blocked right now.";
                const names = atRisk.length > 2 ? atRisk.slice(0, 2).join(", ") + " and " + (atRisk.length - 2) + " more" : atRisk.join(" and ");
                return names + (atRisk.length === 1 ? " needs" : " need") + " the most attention.";
              })()}
            </p>
            <button className="pill" style={{ width: "100%", justifyContent: "center" }} onClick={act("Weekly digest sent to the team")}>Send digest to team</button>
          </Section>
        </div>
      </div>
      <LccModal open={showAdd} title="Add task" onClose={() => setShowAdd(false)} onSubmit={addTask} submitLabel="Add task">
        <LccField label="Task"><input style={lccInput()} placeholder="What needs to happen?" value={draft.title} onChange={(e) => setDraft({ ...draft, title: e.target.value })} /></LccField>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <LccField label="Engine"><select style={lccInput()} value={draft.engine} onChange={(e) => setDraft({ ...draft, engine: e.target.value })}>{Object.keys(ENGINE_LABELS).map((k) => <option key={k} value={k}>{ENGINE_LABELS[k]}</option>)}</select></LccField>
          <LccField label="Due"><input style={lccInput()} placeholder="Jun 12" value={draft.due} onChange={(e) => setDraft({ ...draft, due: e.target.value })} /></LccField>
        </div>
      </LccModal>
      <LccModal open={!!editTask} title="Edit task" onClose={() => setEditTask(null)} onSubmit={saveTask} submitLabel="Save">
        {editTask && (<>
          <LccField label="Task"><input style={lccInput()} value={editTask.title} onChange={(e) => setEditTask({ ...editTask, title: e.target.value })} /></LccField>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
            <LccField label="Owner"><select style={lccInput()} value={editTask.owner} onChange={(e) => setEditTask({ ...editTask, owner: e.target.value })}>{team.map((m) => <option key={m.id} value={m.name.split(" ")[0]}>{m.name.split(" ")[0]}</option>)}</select></LccField>
            <LccField label="Engine"><select style={lccInput()} value={editTask.engine} onChange={(e) => setEditTask({ ...editTask, engine: e.target.value })}>{Object.keys(ENGINE_LABELS).map((k) => <option key={k} value={k}>{ENGINE_LABELS[k]}</option>)}</select></LccField>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
            <LccField label="Status"><select style={lccInput()} value={editTask.status} onChange={(e) => setEditTask({ ...editTask, status: e.target.value })}><option value="todo">To do</option><option value="doing">In progress</option><option value="blocked">Blocked</option><option value="done">Done</option></select></LccField>
            <LccField label="Risk"><select style={lccInput()} value={editTask.risk} onChange={(e) => setEditTask({ ...editTask, risk: e.target.value })}><option value="low">Low</option><option value="med">Medium</option><option value="high">High</option></select></LccField>
            <LccField label="Due"><input style={lccInput()} value={editTask.due} onChange={(e) => setEditTask({ ...editTask, due: e.target.value })} /></LccField>
          </div>
          {window.TaskSyncControl ? <window.TaskSyncControl task={editTask} setTask={setEditTask} /> : null}
          <button className="pill" onClick={() => { delTask(editTask.id); setEditTask(null); }} style={{ alignSelf: "flex-start", color: "#F25BA7", borderColor: "rgba(216,40,132,0.4)" }}>Delete task</button>
        </>)}
      </LccModal>
      <EngineDrawer engine={drawerEngine ? engines.find((e) => e.key === drawerEngine) : null} tasks={tasks} onClose={() => setDrawerEngine(null)} onCycle={cycle} onEdit={setEditTask} onDelete={delTask} onAdd={openAddForEngine} />
    </LccPage>
  );
}
window.LCC_PAGES = Object.assign(window.LCC_PAGES || {}, { today: (tab, go) => <TodayPage go={go} /> });

/* ===========================================================================
   COMMAND PALETTE (⌘K) — jump to any destination or tab. The simplifier:
   you never have to hunt the sidebar.
   =========================================================================== */
function CommandPalette({ open, onClose, onGo, allow: props_allow }) {
  const [q, setQ] = React.useState("");
  const inputRef = React.useRef(null);
  React.useEffect(() => { if (open) { setQ(""); setTimeout(() => inputRef.current && inputRef.current.focus(), 30); } }, [open]);

  const allow = props_allow || LCC_NAV.map((n) => n.id);
  const items = [];
  LCC_NAV.filter((n) => allow.includes(n.id)).forEach((n) => {
    items.push({ page: n.id, tab: null, label: n.label, hint: n.desc, icon: n.icon });
    (LCC_TABS[n.id] || []).forEach((t) => items.push({ page: n.id, tab: t.id, label: n.label + " · " + t.label, hint: "Tab", icon: n.icon }));
  });
  const filtered = q ? items.filter((i) => i.label.toLowerCase().includes(q.toLowerCase())) : items;

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open]);
  if (!open) return null;

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 500, background: "rgba(8,6,18,0.62)", backdropFilter: "blur(4px)", display: "grid", placeItems: "start center", paddingTop: "12vh" }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "min(620px, 92vw)", background: "var(--pvt-surface-raised)", border: "1px solid var(--pvt-border-light)", borderRadius: "var(--r-lg)", boxShadow: "0 32px 80px rgba(0,0,0,0.6)", overflow: "hidden" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "16px 18px", borderBottom: "1px solid var(--pvt-border-light)" }}>
          <Icon name="search" size={18} />
          <input ref={inputRef} value={q} onChange={(e) => setQ(e.target.value)} placeholder="Jump to anything in the command center…"
            style={{ flex: 1, background: "transparent", border: 0, outline: 0, color: "var(--pvt-text)", fontSize: 15, fontFamily: "var(--pvt-font-body)" }} />
          <span style={{ fontSize: 11, color: "var(--pvt-text-dim)", border: "1px solid var(--pvt-border-light)", borderRadius: 6, padding: "2px 6px" }}>ESC</span>
        </div>
        <div style={{ maxHeight: 420, overflowY: "auto", padding: 8 }}>
          {filtered.length === 0 && <div style={{ padding: 24, textAlign: "center", color: "var(--pvt-text-dim)", fontSize: 13 }}>Nothing matches “{q}”.</div>}
          {filtered.map((it, i) => (
            <div key={i} onClick={() => { onGo(it.page, it.tab); onClose(); }}
              style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", borderRadius: "var(--r-md)", cursor: "pointer" }}
              onMouseEnter={(e) => e.currentTarget.style.background = "var(--pvt-surface-mid)"}
              onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}>
              <span style={{ width: 30, height: 30, borderRadius: 9, background: "var(--pvt-surface-mid)", display: "grid", placeItems: "center", color: "var(--pvt-muted)" }}><Icon name={it.icon} size={16} /></span>
              <span style={{ flex: 1, fontSize: 13.5 }}>{it.label}</span>
              <span style={{ fontSize: 11, color: "var(--pvt-text-dim)" }}>{it.hint}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ===========================================================================
   SHELL — labeled sidebar + topbar + hub/tab routing.
   =========================================================================== */
function LaunchApp() {
  const initial = (() => {
    const h = (location.hash || "").replace(/^#/, "").split("/");
    const page = LCC_NAV.find((n) => n.id === h[0]) ? h[0] : "today";
    return { page, tab: h[1] || (LCC_TABS[page][0] && LCC_TABS[page][0].id) || null };
  })();
  const [page, setPage] = React.useState(initial.page);
  const [tab, setTab] = React.useState(initial.tab);
  const [palette, setPalette] = React.useState(false);
  const [collapsed, setCollapsed] = React.useState(false);
  const [access] = window.useDB("launchAccess");
  const [inbox, setInbox] = window.useDB("launchInbox");
  const [menu, setMenu] = React.useState(null); // null | "role" | "notif" | "acct"
  const allow = (access.access && access.access[access.currentRole]) || LCC_NAV.map((n) => n.id);
  const setRole = (r) => { window.ARGT_DB.set("launchAccess", (a) => ({ ...a, currentRole: r })); setMenu(null); };
  const unread = inbox.filter((n) => !n.readAt).length;
  const markRead = (id) => setInbox((xs) => xs.map((x) => x.id === id ? { ...x, readAt: "seen" } : x));
  const markAllRead = () => setInbox((xs) => xs.map((x) => ({ ...x, readAt: x.readAt || "seen" })));
  const signOut = () => { try { localStorage.removeItem("argt-mock-user"); } catch (e) {} window.location.href = "../login.html"; };

  const go = (p, t) => {
    const nt = t || (LCC_TABS[p][0] && LCC_TABS[p][0].id) || null;
    setPage(p); setTab(nt);
    location.hash = p + (nt ? "/" + nt : "");
    window.scrollTo({ top: 0 });
  };

  React.useEffect(() => {
    const onKey = (e) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setPalette((v) => !v); } };
    const onPal = () => setPalette(true);
    document.addEventListener("keydown", onKey);
    window.addEventListener("argt:command-palette", onPal);
    return () => { document.removeEventListener("keydown", onKey); window.removeEventListener("argt:command-palette", onPal); };
  }, []);

  // bounce to Today if the current role can't open this destination
  React.useEffect(() => { if (!allow.includes(page)) go("today"); }, [access.currentRole]);

  // close any open top-bar menu on outside click
  React.useEffect(() => {
    if (!menu) return;
    const onDoc = (e) => { if (!e.target.closest(".lcc-menu")) setMenu(null); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [menu]);

  const nav = LCC_NAV.find((n) => n.id === page) || LCC_NAV[0];
  const accent = LCC_ACCENTS[nav.accent];
  const tabs = LCC_TABS[page] || [];
  const PageComp = (window.LCC_PAGES || {})[page];

  return (
    <div className="lcc" style={{ "--role-accent": accent.hex, "--role-accent-bright": accent.bright }}>
      <CommandPalette open={palette} onClose={() => setPalette(false)} onGo={go} allow={allow} />

      {/* SIDEBAR */}
      <aside className={"lcc-side" + (collapsed ? " collapsed" : "")}>
        <div className="lcc-brand" onClick={() => go("today")}>
          <span className="lcc-mark">ARGT</span>
          {!collapsed && <span className="lcc-sub">Launch Command</span>}
        </div>
        <nav className="lcc-nav">
          {LCC_NAV.filter((n) => allow.includes(n.id)).map((n) => (
            <button key={n.id} className={"lcc-nav-item" + (n.id === page ? " active" : "")} onClick={() => go(n.id)} title={n.label}
              style={n.id === page ? { "--ia": LCC_ACCENTS[n.accent].bright } : {}}>
              <span className="lcc-nav-ico"><Icon name={n.icon} size={20} /></span>
              {!collapsed && <span className="lcc-nav-txt"><span className="l1">{n.label}</span><span className="l2">{n.desc}</span></span>}
            </button>
          ))}
        </nav>
        <div className="lcc-side-foot">
          <button className="lcc-collapse" onClick={() => setCollapsed((c) => !c)} title="Collapse">{collapsed ? "»" : "« Collapse"}</button>
          {!collapsed && <a className="lcc-exit" href="../dashboards/admin.html">Admin console ↗</a>}
        </div>
      </aside>

      {/* MAIN */}
      <div className="lcc-main">
        <header className="lcc-top">
          <div className="lcc-crumb"><span>Launch</span><span className="sep">/</span><span className="cur">{nav.label}</span></div>
          <button className="lcc-search" onClick={() => setPalette(true)}>
            <Icon name="search" size={15} /><span>Search or jump to…</span><kbd>⌘K</kbd>
          </button>
          <div className="lcc-top-actions">
            {/* Role switcher (demo) */}
            <div className="lcc-menu" style={{ position: "relative" }}>
              <button className="lcc-role" onClick={() => setMenu(menu === "role" ? null : "role")} title="Viewing as role (demo)">
                <span className="dot" /><span className="who">{access.currentRole}</span><span className="car">▾</span>
              </button>
              {menu === "role" && (
                <div className="lcc-role-menu">
                  <div className="lcc-role-head">Viewing as</div>
                  {access.roles.map((r) => (
                    <button key={r} className={"lcc-role-opt" + (r === access.currentRole ? " on" : "")} onClick={() => setRole(r)}>
                      <span>{r}</span>
                      <span className="sc">{(access.access[r] || []).includes("settings") ? "Full access" : "No settings"}</span>
                    </button>
                  ))}
                </div>
              )}
            </div>
            {allow.includes("settings") && <button className="btn-icon" title="Settings" onClick={() => go("settings")}><Icon name="gear" size={18} /></button>}
            {/* Notifications */}
            <div className="lcc-menu" style={{ position: "relative" }}>
              <button className="btn-icon" title="Notifications" onClick={() => setMenu(menu === "notif" ? null : "notif")}>
                <Icon name="bell" size={19} />{unread > 0 && <span className="badge-dot" />}
              </button>
              {menu === "notif" && (
                <div className="lcc-notif-menu">
                  <div className="lcc-notif-head">
                    <span className="t">Notifications{unread > 0 && <span className="ct">{unread} new</span>}</span>
                    {unread > 0 && <button onClick={markAllRead}>Mark all read</button>}
                  </div>
                  <div className="lcc-notif-list">
                    {inbox.map((n) => (
                      <button key={n.id} className={"lcc-notif-item" + (n.readAt ? " read" : "")} onClick={() => markRead(n.id)}>
                        <span className="d" style={{ background: n.priority === "high" ? "#F25BA7" : n.readAt ? "var(--pvt-text-dim)" : "var(--role-accent-bright)" }} />
                        <span className="b">
                          <span className="s">{n.summary}</span>
                          <span className="m">{n.kind} · {n.at}</span>
                        </span>
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </div>
            {/* Account */}
            <div className="lcc-menu" style={{ position: "relative" }}>
              <button className="btn-icon primary" title="Account" onClick={() => setMenu(menu === "acct" ? null : "acct")}><Icon name="person" size={19} /></button>
              {menu === "acct" && (
                <div className="lcc-role-menu" style={{ minWidth: 232 }}>
                  <div className="lcc-acct-id">
                    <span className="av">KS</span>
                    <span className="who"><span className="n">Kam Sandberg</span><span className="r">{access.currentRole} · ARGT 2026</span></span>
                  </div>
                  <button className="lcc-role-opt" onClick={() => { setMenu(null); window.argtPing && window.argtPing("Profile opens in the fold"); }}><span>Profile</span></button>
                  {allow.includes("settings") && <button className="lcc-role-opt" onClick={() => { setMenu(null); go("settings"); }}><span>Settings</span></button>}
                  <a className="lcc-role-opt" href="../dashboards/admin.html"><span>Admin console</span><span className="sc">↗</span></a>
                  <a className="lcc-role-opt" href="../homepage.html"><span>Exit to main site</span></a>
                  <button className="lcc-role-opt danger" onClick={signOut}><span>Sign out</span></button>
                </div>
              )}
            </div>
          </div>
        </header>

        <main className="lcc-content">
          {PageComp ? PageComp(tab, go) : <div className="card">Coming soon.</div>}
        </main>
      </div>
    </div>
  );
}
window.LaunchApp = LaunchApp;
