/* ============================================================================
   Mira Enterprise — the paid B2B workspace for Globly.
   Self-contained overlay app: mounts into #ent-root and renders only on
   #/enterprise* hash routes, so the public Globly app is never touched.

   Data policy:
   - Globly stories (fetched from /map-data.json) are REAL and drive the
     dashboard brief, briefings, signals and sources.
   - Ask Mira uses the real global answerWithMira() pipeline when present
     (source-grounded, no invented facts); otherwise it shows the real
     matching stories and says so — it never fabricates an AI answer.
   - Workspaces, members, monitors, settings, saved items persist in
     localStorage (no backend added — Vercel is at its function cap and
     Supabase migrations are manual). Seeded demo workspaces make the
     team-code + admin flows work end to end. Everything derived from demo
     data is labelled and kept out of the public news pages.
   ========================================================================== */
(function () {
  "use strict";
  var R = window.React;
  if (!R) return;
  var h = R.createElement;
  var useState = R.useState, useEffect = R.useEffect, useMemo = R.useMemo, useRef = R.useRef;

  // ── tiny inline icons (self-contained, no lucide dependency) ────────────
  function Ico(props) {
    var paths = {
      dashboard: "M3 3h7v7H3zM14 3h7v4h-7zM14 10h7v11h-7zM3 13h7v8H3z",
      monitor:   "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z|9|3",
      brief:     "M4 3h16v18H4z|M8 8h8M8 12h8M8 16h5",
      source:    "M12 2a10 10 0 100 20 10 10 0 000-20zM2 12h20M12 2a15 15 0 010 20M12 2a15 15 0 000 20",
      signal:    "M13 2L3 14h7l-1 8 10-12h-7z",
      report:    "M6 2h9l5 5v15H6z|M14 2v6h6M9 13h6M9 17h6",
      team:      "M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2|9|7|3|23 21v-2a4 4 0 00-3-3.87|16 3.13a4 4 0 010 7.75",
      billing:   "M2 5h20v14H2z|M2 10h20",
      settings:  "M12 15a3 3 0 100-6 3 3 0 000 6z|M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 11-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 110-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 114 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 110 4h-.09a1.65 1.65 0 00-1.51 1z",
      search:    "M11 19a8 8 0 100-16 8 8 0 000 16z|M21 21l-4.35-4.35",
      bell:      "M18 8a6 6 0 00-12 0c0 7-3 9-3 9h18s-3-2-3-9|13.73 21a2 2 0 01-3.46 0",
      clock:     "M12 22a10 10 0 100-20 10 10 0 000 20z|M12 6v6l4 2",
      arrow:     "M5 12h14|M12 5l7 7-7 7",
      plus:      "M12 5v14M5 12h14",
      dots:      "M12 12h.01M19 12h.01M5 12h.01",
      check:     "M20 6L9 17l-5-5",
      external:  "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6|15 3h6v6|10 14L21 3",
      bookmark:  "M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2z",
      globe:     "M12 22a10 10 0 100-20 10 10 0 000 20z|M2 12h20|M12 2a15 15 0 010 20M12 2a15 15 0 000 20",
      shield:    "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
      share:     "M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8|16 6l-4-4-4 4|12 2v13",
      slack:     "M6 15a2 2 0 11-2-2h2zM6 13h6a2 2 0 110 4H6z",
      download:  "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4|7 10l5 5 5-5|12 15V3",
      copy:      "M20 9h-9a2 2 0 00-2 2v9a2 2 0 002 2h9a2 2 0 002-2v-9a2 2 0 00-2-2z|5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1",
      menu:      "M3 12h18M3 6h18M3 18h18",
      logout:    "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4|16 17l5-5-5-5|21 12H9",
      spark:     "M12 2l2.4 7.4H22l-6 4.6 2.3 7.4-6.3-4.6L5.7 21l2.3-7.4-6-4.6h7.6z",
      layers:    "M12 2l10 6-10 6L2 8z|2 16l10 6 10-6",
      eye:       "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z|M12 9a3 3 0 100 6 3 3 0 000-6z",
      pencil:    "M12 20h9|M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z",
      pause:     "M7 4h3v16H7z|M14 4h3v16h-3z",
      trash:     "M3 6h18|M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2|M6 6l1 14a2 2 0 002 2h6a2 2 0 002-2l1-14",
    };
    var raw = paths[props.name] || "";
    var kids = [];
    raw.split("|").forEach(function (p, i) {
      p = p.trim();
      // Keep only real SVG path fragments (start with a path command letter);
      // drops any leftover numeric shorthand so no invalid <path> is emitted.
      if (!/^[a-zA-Z]/.test(p)) return;
      kids.push(h("path", { key: i, d: p }));
    });
    return h("svg", {
      viewBox: "0 0 24 24", fill: "none", stroke: "currentColor",
      strokeWidth: props.sw || 1.7, strokeLinecap: "round", strokeLinejoin: "round",
      width: props.size || 18, height: props.size || 18, "aria-hidden": true,
    }, kids);
  }

  // ── storage helpers ─────────────────────────────────────────────────────
  var LSK = {
    workspaces: "ent_workspaces_v1",
    membership: "ent_membership_v1",  // { [email]: { wsId, role } }
    monitors:   "ent_monitors_v1",    // { [wsId]: [monitor] }
    settings:   "ent_settings_v1",    // { [wsId]: {...} }
    saved:      "ent_saved_v1",       // { [email]: { signals:[ids], briefs:[ids] } }
    seeded:     "ent_seeded_v1",
    sources:    "ent_sources_v1",     // { [wsId]: [source] }
    reports:    "ent_reports_v1",     // { [wsId]: [report] }
    onboarding: "ent_onboarding_v1",  // { [wsId]: { skipped, dismissed } }
    firstAccess:"ent_firstaccess_v1", // one-time legacy-demo cleanup flag
  };
  function lsGet(k, fb) { try { var v = localStorage.getItem(k); return v ? JSON.parse(v) : fb; } catch (e) { return fb; } }
  function lsSet(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} }

  function currentSession() {
    // Mirrors the consumer app's session key so a Globly sign-in carries over.
    var s = lsGet("globally_session", null);
    if (s && s.email) return s;
    return null;
  }

  // ── team code ───────────────────────────────────────────────────────────
  function genCode() {
    var up = "ABCDEFGHJKLMNPQRSTUVWXYZ", lo = "abcdefghijkmnpqrstuvwxyz", nn = "23456789";
    var all = up + lo + nn, out = "";
    // guarantee a mix
    out += up[Math.floor(Math.random() * up.length)];
    out += lo[Math.floor(Math.random() * lo.length)];
    out += nn[Math.floor(Math.random() * nn.length)];
    for (var i = 3; i < 12; i++) out += all[Math.floor(Math.random() * all.length)];
    return out.split("").sort(function () { return Math.random() - 0.5; }).join("");
  }

  // ── demo seed (labelled, isolated to enterprise storage) ────────────────
  function seedDemo() {
    if (lsGet(LSK.seeded, false)) return;
    var wsFull = "F0LLteamXy91";
    var wsOpen = "MERid1an7Ab2";
    var workspaces = {
      demo_meridian: {
        id: "demo_meridian", name: "Meridian Relief", code: wsOpen, demo: true,
        seatsLimit: 5, plan: "Mira Enterprise Starter", price: 99, createdAt: Date.now() - 86400000 * 40,
        members: [
          { email: "amara@meridian.org", name: "Amara Okafor", role: "Team Admin", status: "Active", joinedAt: Date.now() - 86400000 * 40, lastActive: Date.now() - 3600000 * 2 },
          { email: "j.rivera@meridian.org", name: "Julian Rivera", role: "Analyst", status: "Active", joinedAt: Date.now() - 86400000 * 22, lastActive: Date.now() - 3600000 * 26 },
          { email: "sana@meridian.org", name: "Sana Iqbal", role: "Viewer", status: "Active", joinedAt: Date.now() - 86400000 * 9, lastActive: Date.now() - 3600000 * 5 },
        ],
      },
      demo_full: {
        id: "demo_full", name: "Northwind Foundation", code: wsFull, demo: true,
        seatsLimit: 5, plan: "Mira Enterprise Starter", price: 99, createdAt: Date.now() - 86400000 * 90,
        members: [
          { email: "a@northwind.org", name: "Admin One", role: "Team Admin", status: "Active", joinedAt: 0, lastActive: 0 },
          { email: "b@northwind.org", name: "Member B", role: "Analyst", status: "Active", joinedAt: 0, lastActive: 0 },
          { email: "c@northwind.org", name: "Member C", role: "Analyst", status: "Active", joinedAt: 0, lastActive: 0 },
          { email: "d@northwind.org", name: "Member D", role: "Viewer", status: "Active", joinedAt: 0, lastActive: 0 },
          { email: "e@northwind.org", name: "Member E", role: "Viewer", status: "Active", joinedAt: 0, lastActive: 0 },
        ],
      },
    };
    lsSet(LSK.workspaces, workspaces);
    lsSet(LSK.monitors, {
      demo_meridian: seedMonitors(),
    });
    lsSet(LSK.seeded, true);
  }
  // 30-day series whose last 7 values equal h7, with a gentle rising lead-in.
  function entHist30(h7) {
    var first = Math.max(1, Math.round((h7[0] || 4) * 0.5));
    var out = [];
    for (var i = 0; i < 23; i++) {
      var t = i / 22, base = first + ((h7[0] || 4) - first) * t, noise = ((i * 37) % 7 - 3) * 0.7;
      out.push(Math.max(1, Math.round(base + noise)));
    }
    return out.concat(h7);
  }
  function seedMonitor(o) {
    o.trend = o.history7;                       // back-compat: existing Sparkline reads m.trend
    o.history30 = entHist30(o.history7);
    o.signalsToday = o.history7[o.history7.length - 1];
    return o;
  }
  function seedMonitors() {
    return [
      seedMonitor({ id: "m1", name: "Climate Finance - South Asia", topics: ["Climate", "Economy"], regions: ["South Asia"], sourceTypes: ["News", "Agencies"], priority: "High", frequency: "Daily", createdAt: Date.now() - 86400000 * 30, history7: [4, 5, 7, 6, 9, 11, 16], critical: 3 }),
      seedMonitor({ id: "m2", name: "Migration & Displacement", topics: ["Humanitarian"], regions: ["Global"], sourceTypes: ["Agencies", "News"], priority: "Medium", frequency: "Daily", createdAt: Date.now() - 86400000 * 25, history7: [20, 24, 21, 30, 26, 36, 41], critical: 6 }),
      seedMonitor({ id: "m3", name: "Humanitarian Access", topics: ["Humanitarian", "Conflict"], regions: ["Africa", "Middle East"], sourceTypes: ["Agencies"], priority: "High", frequency: "Real-time", createdAt: Date.now() - 86400000 * 20, history7: [12, 15, 14, 18, 16, 20, 23], critical: 5 }),
      seedMonitor({ id: "m4", name: "Global Health Policy", topics: ["Health"], regions: ["Global"], sourceTypes: ["News", "Research", "Government"], priority: "Low", frequency: "Weekly", createdAt: Date.now() - 86400000 * 14, history7: [2, 3, 3, 4, 5, 4, 6], critical: 1 }),
      seedMonitor({ id: "m5", name: "Food Security Watch", topics: ["Food"], regions: ["Africa", "South Asia"], sourceTypes: ["Agencies", "News"], priority: "Medium", frequency: "Daily", createdAt: Date.now() - 86400000 * 9, history7: [6, 8, 7, 10, 13, 11, 15], critical: 4 }),
    ];
  }

  // ── workspace store API ─────────────────────────────────────────────────
  var Store = {
    workspaces: function () { return lsGet(LSK.workspaces, {}); },
    saveWorkspaces: function (w) { lsSet(LSK.workspaces, w); },
    membership: function (email) { var m = lsGet(LSK.membership, {}); return m[email] || null; },
    setMembership: function (email, wsId, role) { var m = lsGet(LSK.membership, {}); m[email] = { wsId: wsId, role: role }; lsSet(LSK.membership, m); },
    clearMembership: function (email) { var m = lsGet(LSK.membership, {}); delete m[email]; lsSet(LSK.membership, m); },
    monitors: function (wsId) { var all = lsGet(LSK.monitors, {}); return all[wsId] || []; },
    setMonitors: function (wsId, list) { var all = lsGet(LSK.monitors, {}); all[wsId] = list; lsSet(LSK.monitors, all); },
    settings: function (wsId) { var all = lsGet(LSK.settings, {}); return all[wsId] || {}; },
    setSettings: function (wsId, s) { var all = lsGet(LSK.settings, {}); all[wsId] = Object.assign({}, all[wsId], s); lsSet(LSK.settings, all); },
    sources: function (wsId) { var all = lsGet(LSK.sources, {}); return all[wsId] || []; },
    setSources: function (wsId, list) { var all = lsGet(LSK.sources, {}); all[wsId] = list; lsSet(LSK.sources, all); },
    reports: function (wsId) { var all = lsGet(LSK.reports, {}); return all[wsId] || []; },
    setReports: function (wsId, list) { var all = lsGet(LSK.reports, {}); all[wsId] = list; lsSet(LSK.reports, all); },
    onboarding: function (wsId) { var all = lsGet(LSK.onboarding, {}); return all[wsId] || { skipped: false, dismissed: false }; },
    setOnboarding: function (wsId, o) { var all = lsGet(LSK.onboarding, {}); all[wsId] = Object.assign({}, all[wsId], o); lsSet(LSK.onboarding, all); },
    saved: function (email) { return lsGet(LSK.saved, {})[email] || { signals: [], briefs: [] }; },
    toggleSaved: function (email, kind, id) {
      var all = lsGet(LSK.saved, {}); var s = all[email] || { signals: [], briefs: [] };
      var arr = s[kind] || []; var i = arr.indexOf(id);
      if (i === -1) arr.push(id); else arr.splice(i, 1);
      s[kind] = arr; all[email] = s; lsSet(LSK.saved, all); return arr;
    },
  };

  // TODO: require signed-in workspace access + persist onboarding/workspace state to the database before launch.
  // One-time cleanup of any previously seeded demo data so first access is genuinely empty.
  function clearLegacyDemo() {
    if (lsGet(LSK.firstAccess, false)) return;
    ["ent_workspaces_v1", "ent_monitors_v1", "ent_membership_v1", "ent_seeded_v1",
     "ent_demo_team_v1", "ent_demo_invites_v1", "ent_demo_teamcode_v1", "ent_demo_settings_v1",
     "ent_sources_v1", "ent_reports_v1", "ent_onboarding_v1"].forEach(function (k) { try { localStorage.removeItem(k); } catch (e) {} });
    lsSet(LSK.firstAccess, true);
  }
  // Real, empty workspace for the current (or preview) user — no demo seed.
  function ensureWorkspace(sess) {
    var email = (sess && sess.email) || "preview@globly.news";
    var name = (sess && sess.name) || email.split("@")[0];
    var mem = Store.membership(email);
    var all = Store.workspaces();
    if (mem && all[mem.wsId]) return Object.assign({}, all[mem.wsId], { _role: mem.role });
    var id = "ws_" + (email.replace(/[^a-z0-9]/gi, "").slice(0, 12) || "preview");
    if (!all[id]) {
      all[id] = {
        id: id, name: "", code: genCode(), demo: false,
        seatsLimit: 5, plan: "Mira Enterprise Starter", price: 99, createdAt: Date.now(),
        members: [{ email: email, name: name, role: "Team Admin", status: "Active", joinedAt: Date.now(), lastActive: Date.now() }],
      };
      Store.saveWorkspaces(all);
    }
    Store.setMembership(email, id, "Team Admin");
    return Object.assign({}, all[id], { _role: "Team Admin" });
  }
  // Setup checklist state derived from REAL workspace data (no fake progress).
  function setupSteps(ws) {
    var mon = Store.monitors(ws.id), srcs = Store.sources(ws.id), reps = Store.reports(ws.id);
    var st = Store.settings(ws.id), members = ws.members || [];
    return [
      { key: "workspace", route: "settings", title: "Set up your workspace", desc: "Name your workspace and set your focus.", done: !!(ws.name && ws.name.trim()) || !!(st.wsName && st.wsName.trim()) },
      { key: "monitor", route: "monitors", title: "Create your first monitor", desc: "Choose the topics and regions Mira should track.", done: mon.length > 0 },
      { key: "sources", route: "sources", title: "Add or approve sources", desc: "Pick the trusted sources Mira scans.", done: srcs.length > 0 },
      { key: "briefing", route: "settings", title: "Set briefing delivery time", desc: "Decide when your team brief arrives.", done: !!(st.briefTime) },
      { key: "team", route: "team", title: "Invite your team", desc: "Add teammates to your workspace.", done: members.length > 1 },
      { key: "report", route: "reports", title: "Generate your first report", desc: "Turn signals into a shareable report.", done: reps.length > 0 },
    ];
  }

  function joinByCode(email, name, code) {
    var ws = Store.workspaces();
    var match = null;
    Object.keys(ws).forEach(function (id) { if (ws[id].code === code) match = ws[id]; });
    if (!match) return { ok: false, reason: "invalid" };
    if ((match.members || []).length >= match.seatsLimit) return { ok: false, reason: "full" };
    if (!(match.members || []).some(function (m) { return m.email === email; })) {
      match.members.push({ email: email, name: name || email.split("@")[0], role: "Analyst", status: "Active", joinedAt: Date.now(), lastActive: Date.now() });
      ws[match.id] = match; Store.saveWorkspaces(ws);
    }
    Store.setMembership(email, match.id, "Analyst");
    return { ok: true, wsId: match.id };
  }
  function createWorkspace(email, name, orgName) {
    var ws = Store.workspaces();
    var id = "ws_" + Date.now().toString(36);
    ws[id] = {
      id: id, name: orgName || "My Organisation", code: genCode(), demo: false,
      seatsLimit: 5, plan: "Mira Enterprise Starter", price: 99, createdAt: Date.now(),
      members: [{ email: email, name: name || email.split("@")[0], role: "Team Admin", status: "Active", joinedAt: Date.now(), lastActive: Date.now() }],
    };
    Store.saveWorkspaces(ws);
    Store.setMonitors(id, seedMonitors());
    Store.setMembership(email, id, "Team Admin");
    return { ok: true, wsId: id };
  }

  // ── story data (REAL) ───────────────────────────────────────────────────
  var _storiesCache = null;
  function loadStories() {
    if (_storiesCache) return Promise.resolve(_storiesCache);
    return fetch("/map-data.json").then(function (r) { return r.json(); }).then(function (d) {
      var arts = (d.articles || []).filter(function (a) { return !a._clusterHidden; });
      _storiesCache = arts;
      return arts;
    }).catch(function () { return []; });
  }
  function isFresh48(a) {
    var ts = a.published || a.scraped_at || 0;
    return Date.now() - new Date(ts).getTime() < 48 * 3600 * 1000;
  }
  function sig(a) { return a.significance || 1; }
  function timeAgo(ts) {
    if (!ts) return "";
    var s = Math.floor((Date.now() - new Date(ts).getTime()) / 1000);
    if (s < 60) return "just now";
    if (s < 3600) return Math.floor(s / 60) + "m ago";
    if (s < 86400) return Math.floor(s / 3600) + "h ago";
    return Math.floor(s / 86400) + "d ago";
  }
  function fmtDate(ts) { try { return new Date(ts).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" }); } catch (e) { return ""; } }

  // monitor → matching stories (real)
  var TOPIC_KW = {
    Climate: ["climate", "flood", "drought", "cyclone", "storm", "heat", "emission"],
    Disaster: ["earthquake", "flood", "disaster", "landslide", "relief", "evacuat"],
    Food: ["food", "hunger", "famine", "harvest", "crop", "nutrition", "malnutrition"],
    Humanitarian: ["humanitarian", "refugee", "displac", "aid", "crisis", "shelter"],
    AI: ["artificial intelligence", "machine learning", "algorithm", "ai "],
    Health: ["health", "disease", "outbreak", "hospital", "vaccine", "cholera"],
    Conflict: ["conflict", "war", "attack", "clash", "military", "ceasefire"],
    Economy: ["economy", "inflation", "debt", "trade", "currency", "imf"],
  };
  var REGION_KW = {
    "South Asia": ["india", "pakistan", "bangladesh", "sri lanka", "nepal", "afghan"],
    "Africa": ["africa", "nigeria", "kenya", "ethiopia", "sudan", "somalia", "congo", "sahel"],
    "Middle East": ["gaza", "palestin", "syria", "yemen", "iraq", "iran", "lebanon"],
    "Southeast Asia": ["myanmar", "indonesia", "philippines", "vietnam", "thailand"],
    "Latin America": ["venezuela", "colombia", "brazil", "haiti", "honduras", "mexico"],
    "East Asia": ["china", "japan", "korea"],
    "Europe": ["ukraine", "europe", "russia"],
    "Global": [],
  };
  function monitorStories(mon, stories) {
    var tkw = [], rkw = [];
    (mon.topics || []).forEach(function (t) { tkw = tkw.concat(TOPIC_KW[t] || [t.toLowerCase()]); });
    (mon.regions || []).forEach(function (rg) { rkw = rkw.concat(REGION_KW[rg] || [rg.toLowerCase()]); });
    return stories.filter(function (a) {
      var txt = ((a.title || "") + " " + (a.summary || "") + " " + (a.country || "") + " " + (a.region || "")).toLowerCase();
      var tOk = tkw.length === 0 || tkw.some(function (w) { return txt.indexOf(w) !== -1; });
      var rOk = rkw.length === 0 || (mon.regions || []).indexOf("Global") !== -1 || rkw.some(function (w) { return txt.indexOf(w) !== -1; });
      return tOk && rOk;
    }).sort(function (a, b) { return sig(b) - sig(a) || new Date(b.published || 0) - new Date(a.published || 0); });
  }
  function priorityFromSig(s) { return s >= 3 ? "High" : s === 2 ? "Medium" : "Low"; }

  // ── shared UI primitives ────────────────────────────────────────────────
  function Sparkline(props) {
    var d = props.data || [], w = props.w || 116, ht = props.h || 34, pad = 3;
    if (d.length < 2) return null;
    var max = Math.max.apply(null, d), min = Math.min.apply(null, d), rng = max - min || 1;
    function X(i) { return (i / (d.length - 1)) * (w - pad * 2) + pad; }
    function Y(v) { return ht - pad - ((v - min) / rng) * (ht - pad * 2); }
    var line = d.map(function (v, i) { return X(i).toFixed(1) + "," + Y(v).toFixed(1); }).join(" ");
    var area = X(0).toFixed(1) + "," + (ht - pad) + " " + line + " " + X(d.length - 1).toFixed(1) + "," + (ht - pad);
    var col = props.color || "#7C3AED", gid = "spg_" + (props.gid || (min + "_" + max + "_" + d.length + "_" + d[0]));
    return h("svg", { className: "ent-spark", width: w, height: ht, viewBox: "0 0 " + w + " " + ht,
        style: props.onClick ? { cursor: "pointer" } : null, onClick: props.onClick, role: props.onClick ? "button" : null,
        "aria-label": props.onClick ? "Open activity chart" : null },
      h("defs", null, h("linearGradient", { id: gid, x1: 0, y1: 0, x2: 0, y2: 1 },
        h("stop", { offset: "0%", stopColor: col, stopOpacity: 0.22 }), h("stop", { offset: "100%", stopColor: col, stopOpacity: 0 }))),
      h("line", { x1: pad, y1: ht - pad, x2: w - pad, y2: ht - pad, stroke: col, strokeOpacity: 0.14, strokeWidth: 1 }),
      h("polygon", { points: area, fill: "url(#" + gid + ")", stroke: "none" }),
      h("polyline", { points: line, fill: "none", stroke: col, strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round" }),
      h("circle", { cx: X(d.length - 1).toFixed(1), cy: Y(d[d.length - 1]).toFixed(1), r: 2.6, fill: col }));
  }
  function KPI(props) {
    return h("div", { className: "ent-kpi" },
      h("div", { className: "ent-kpi-label" }, props.icon ? h(Ico, { name: props.icon, size: 15 }) : null, props.label),
      h("div", { className: "ent-kpi-value" }, props.value),
      props.delta ? h("div", { className: "ent-kpi-delta " + (props.trend || "flat") }, props.delta) : null);
  }
  function Badge(props) { return h("span", { className: "ent-badge ent-badge--" + (props.kind || "low") }, props.children); }
  function PageHead(props) {
    return h("div", { className: "ent-page-hd" },
      h("div", { className: "ent-page-hd-main" },
        h("h1", { className: "ent-page-title" }, props.title),
        props.sub ? h("p", { className: "ent-page-sub" }, props.sub) : null),
      props.actions ? h("div", { className: "ent-page-actions" }, props.actions) : null);
  }
  function Modal(props) {
    return h("div", { className: "ent-modal-backdrop", onClick: props.onClose },
      h("div", { className: "ent-modal" + (props.wide ? " ent-modal--wide" : ""), onClick: function (e) { e.stopPropagation(); } },
        h("div", { className: "ent-modal-hd" }, h("h3", null, props.title), h("button", { className: "ent-modal-close", onClick: props.onClose }, "×")),
        h("div", { className: "ent-modal-body" }, props.children),
        props.foot ? h("div", { className: "ent-modal-foot" }, props.foot) : null));
  }
  function EmptyState(props) {
    return h("div", { className: "ent-empty" }, h(Ico, { name: props.icon || "search", size: 30 }), h("p", null, props.text));
  }

  // ============================================================
  //  SHELL (sidebar + topbar)
  // ============================================================
  var NAV = [
    ["dashboard", "Dashboard", "dashboard"],
    ["monitors", "Monitors", "monitor"],
    ["briefings", "Briefings", "brief"],
    ["sources", "Sources", "source"],
    ["signals", "Signals", "signal"],
    ["reports", "Reports", "report"],
    ["team", "Team", "team"],
    ["billing", "Billing", "billing"],
    ["settings", "Settings", "settings"],
  ];
  function go(route) { window.location.hash = "#/enterprise/" + route; }
  function goMonitor(id) { window.location.hash = "#/enterprise/monitors/" + id; }

  function Shell(props) {
    var _o = useState(false), open = _o[0], setOpen = _o[1];
    var _m = useState(false), menu = _m[0], setMenu = _m[1];
    var ws = props.ws, route = props.route, sess = props.session;
    var wsLabel = (ws.name && ws.name.trim()) || "Your workspace";
    var initials = wsLabel.split(/\s+/).map(function (w) { return w[0]; }).slice(0, 2).join("").toUpperCase();
    var avatarInit = (sess.email || "U")[0].toUpperCase();
    return h("div", { className: "ent-shell" },
      h("div", { className: "ent-sb-scrim" + (open ? " is-open" : ""), onClick: function () { setOpen(false); } }),
      h("aside", { className: "ent-sidebar" + (open ? " is-open" : "") },
        h("div", { className: "ent-sb-brand" },
          h("div", { className: "ent-sb-logo" }, "G"),
          h("div", null,
            h("div", { className: "ent-sb-brand-name" }, "Globly"),
            h("div", { className: "ent-sb-brand-sub" }, "Enterprise"))),
        h("nav", { className: "ent-sb-nav" },
          NAV.map(function (n) {
            return h("button", {
              key: n[0], className: "ent-sb-item" + (route === n[0] ? " is-active" : ""),
              onClick: function () { go(n[0]); setOpen(false); },
            }, h(Ico, { name: n[2], size: 17 }), n[1]);
          })),
        h("div", { className: "ent-sb-foot" },
          (function () {
            var card = route === "team"
              ? { t: "Invite your team", b: "Add teammates to collaborate on intelligence and share insights.", btn: "Invite members", on: function () { go("team"); setOpen(false); } }
              : route === "settings"
                ? { t: "Need help?", b: "Our team is here if you have any questions or need support.", btn: "Contact support", on: function () { window.location.href = "mailto:support@globly.news?subject=Mira%20Enterprise%20support"; } }
                : { t: "Need something custom?", b: "Tell us what you want Mira to track. We’ll help you set it up.", btn: "Request monitor", on: function () { window.location.hash = "#/business"; } };
            return h("div", { style: { background: "var(--ent-tint)", border: "1px solid var(--ent-border-2)", borderRadius: "12px", padding: "13px 14px", marginBottom: "10px" } },
              h("div", { style: { fontSize: "13px", fontWeight: 700, color: "var(--ent-ink)" } }, card.t),
              h("div", { style: { fontSize: "11.5px", color: "var(--ent-muted)", lineHeight: 1.45, margin: "4px 0 10px" } }, card.b),
              h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", style: { width: "100%", justifyContent: "center" }, onClick: card.on }, card.btn));
          })(),
          h("div", { className: "ent-sb-ws" },
            h("div", { className: "ent-sb-ws-badge" }, initials),
            h("div", null,
              h("div", { className: "ent-sb-ws-name" }, wsLabel),
              h("div", { className: "ent-sb-ws-plan" }, ws.demo ? "Demo workspace" : "Mira Enterprise"))))),
      h("div", { className: "ent-main" },
        h("header", { className: "ent-topbar" },
          h("button", { className: "ent-tb-menu", onClick: function () { setOpen(true); }, "aria-label": "Menu" }, h(Ico, { name: "menu", size: 18 })),
          h("nav", { className: "ent-tb-nav" },
            ["Today", "Charity", "Volunteering", "Enterprise", "About"].map(function (t) {
              var active = t === "Enterprise";
              return h("button", {
                key: t, className: "ent-tb-link" + (active ? " is-active" : ""),
                onClick: function () {
                  if (t === "Enterprise") { go("dashboard"); return; }
                  // Leave the overlay and drive the consumer app's real nav so
                  // the correct tab shows (setting the hash alone would not reset
                  // the consumer tab). "Today" maps to the consumer "Home" item.
                  window.location.hash = "";
                  document.body.style.overflow = "";
                  var target = t === "Today" ? "Home" : t;
                  setTimeout(function () {
                    var btn = Array.from(document.querySelectorAll(".glh-nav button, .glh-mobile-link")).find(function (b) { return b.textContent.trim() === target; });
                    if (btn) btn.click();
                  }, 60);
                },
              }, t);
            })),
          h("div", { className: "ent-tb-spacer" }),
          // TODO: Re-enable Enterprise auth, workspace, and subscription gating before launch.
          // Calm "Preview mode" pill shown on every Enterprise page while the
          // workspace is publicly open for preview.
          h("span", { className: "ent-preview-pill", title: "Enterprise is open for preview — no sign-in required" },
            h("span", { className: "ent-preview-dot" }), "Preview mode"),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { flex: "none" }, title: "Open the setup guide", onClick: function () { if (props.onGuide) props.onGuide(); } }, h(Ico, { name: "check", size: 14 }), "Setup guide"),
          h("div", { className: "ent-tb-search" }, h(Ico, { name: "search", size: 15 }),
            h("input", { placeholder: "Search Enterprise…", value: props.search || "", onChange: function (e) { if (props.onSearch) props.onSearch(e.target.value); } })),
          h("button", { className: "ent-tb-avatar", "aria-label": "Notifications", title: "Notifications", style: { background: "transparent", color: "var(--ent-muted)", position: "relative" }, onClick: function () {} },
            h(Ico, { name: "bell", size: 17 }),
            h("span", { style: { position: "absolute", top: "7px", right: "8px", width: "7px", height: "7px", borderRadius: "50%", background: "var(--ent-hi)", border: "2px solid var(--ent-page)" } })),
          h("div", { style: { textAlign: "right", lineHeight: 1.2 } },
            h("div", { style: { fontSize: "12.5px", fontWeight: 600, color: "var(--ent-ink)", display: "flex", alignItems: "center", gap: "6px", justifyContent: "flex-end" } },
              wsLabel),
            h("div", { style: { fontSize: "10.5px", color: "var(--ent-muted)" } }, ws.demo ? "Preview workspace" : (ws._role || "Member"))),
          h("div", { className: "ent-tb-acct" },
            h("button", { className: "ent-tb-avatar", onClick: function () { setMenu(!menu); } }, avatarInit),
            menu ? h("div", { className: "ent-tb-menu-pop" },
              h("div", { className: "ent-tb-menu-hd" },
                h("div", { className: "n" }, sess.name || sess.email.split("@")[0]),
                h("div", { className: "e" }, sess.email)),
              h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(false); go("settings"); } }, h(Ico, { name: "settings", size: 15 }), "Settings"),
              h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(false); go("billing"); } }, h(Ico, { name: "billing", size: 15 }), "Billing"),
              h("button", { className: "ent-tb-menu-item", onClick: function () { window.location.hash = "#/"; } }, h(Ico, { name: "logout", size: 15 }), "Back to Globly")) : null)),
        h("div", { className: props.rail ? "ent-content ent-content--rail" : "ent-content" }, props.children)));
  }

  // toast helper (module-level via a simple event)
  function useToast() {
    var _t = useState(null), t = _t[0], setT = _t[1];
    var show = function (msg) { setT(msg); setTimeout(function () { setT(null); }, 2200); };
    var node = t ? h("div", { className: "ent-toast" }, t) : null;
    return [show, node];
  }

  // ============================================================
  //  DASHBOARD
  // ============================================================
  function entEmptyCard(icon, title, body, btn, route) {
    return h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
      h("div", { style: { width: 40, height: 40, borderRadius: 11, margin: "4px auto 10px", display: "grid", placeItems: "center", background: "var(--ent-accent-t)", color: "var(--ent-accent-d)" } }, h(Ico, { name: icon, size: 19 })),
      h("div", { style: { fontSize: 14, fontWeight: 700, color: "var(--ent-ink)" } }, title),
      h("div", { style: { fontSize: 12.5, color: "var(--ent-muted)", lineHeight: 1.5, margin: "6px 0 12px" } }, body),
      h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { go(route); } }, btn));
  }
  // First-access dashboard — welcome + setup checklist + empty states (no demo data).
  function dashboardFirstAccess(props) {
    var ws = props.ws;
    var steps = setupSteps(ws);
    var doneCount = steps.filter(function (s) { return s.done; }).length;
    var pct = Math.round(doneCount / steps.length * 100);
    var main = h("div", { className: "ent-col" },
      h("div", { className: "ent-page-hd" },
        h("div", { className: "ent-page-hd-main" },
          h("h1", { className: "ent-page-title" }, "Welcome to Mira Enterprise"),
          h("p", { className: "ent-page-sub" }, "Set up your team workspace to start receiving source-grounded development intelligence.")),
        h("div", { className: "ent-page-actions" },
          h("button", { className: "ent-btn", onClick: function () { if (props.onGuide) props.onGuide(); } }, h(Ico, { name: "check", size: 15 }), "Open setup guide"))),
      h("div", { className: "ent-card ent-card-pad" },
        h("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 6, flexWrap: "wrap" } },
          h("h3", { style: { fontSize: 15, fontWeight: 700 } }, "Set up your workspace"),
          h("span", { style: { marginLeft: "auto", fontSize: 12.5, color: "var(--ent-muted)", fontWeight: 600 } }, doneCount + " of " + steps.length + " completed")),
        h("div", { style: { height: 7, borderRadius: 999, background: "#EFEAE0", overflow: "hidden", margin: "4px 0 16px" } }, h("div", { style: { height: "100%", width: pct + "%", background: "#7C3AED", borderRadius: 999 } })),
        h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(258px,1fr))", gap: 10 } },
          steps.map(function (s, k) {
            return h("div", { key: s.key, style: { display: "flex", alignItems: "flex-start", gap: 11, border: "1px solid var(--ent-border-2)", borderRadius: 11, padding: "12px 13px", background: s.done ? "var(--ent-surface-2)" : "#fff" } },
              h("span", { style: { width: 22, height: 22, borderRadius: 999, flex: "none", display: "grid", placeItems: "center", fontSize: 11, fontWeight: 700, background: s.done ? "#4F8A54" : "#EFEAE0", color: s.done ? "#fff" : "var(--ent-muted)" } }, s.done ? h(Ico, { name: "check", size: 13 }) : (k + 1)),
              h("div", { style: { flex: 1, minWidth: 0 } },
                h("div", { style: { fontSize: 13, fontWeight: 700, color: "var(--ent-ink)" } }, s.title),
                h("div", { style: { fontSize: 11.5, color: "var(--ent-muted)", marginTop: 2, lineHeight: 1.4 } }, s.desc),
                h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: 8 }, onClick: function () { go(s.route); } }, s.done ? "Review" : "Set up →")));
          })),
        h("div", { style: { display: "flex", gap: 8, marginTop: 16, flexWrap: "wrap" } },
          h("button", { className: "ent-btn ent-btn--primary", onClick: function () { if (props.onGuide) props.onGuide(); } }, "Start setup"),
          h("button", { className: "ent-btn ent-btn--ghost", onClick: function () { go("monitors"); } }, "Create first monitor"))),
      h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("h3", null, "Today's team brief")),
        h("div", { className: "ent-card-pad", style: { textAlign: "center" } },
          h(EmptyState, { icon: "brief", text: "Create your first monitor to generate a team brief." }),
          h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { go("monitors"); } }, "Create monitor"))),
      h("div", { className: "ent-analytics-grid" },
        entEmptyCard("monitor", "No monitors yet", "Create monitors for the topics and regions your team wants Mira to track.", "Create monitor", "monitors"),
        entEmptyCard("signal", "No signals yet", "Signals will appear once Mira starts tracking your monitors.", "Create monitor", "monitors"),
        entEmptyCard("source", "No sources yet", "Add trusted sources for Mira to scan.", "Add sources", "sources")));
    var rail = h("div", { className: "ent-rail" },
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Quick actions"),
        h("div", { className: "ent-action-list" },
          h("button", { className: "ent-action-btn", onClick: function () { go("monitors"); } }, h(Ico, { name: "monitor", size: 16 }), "Create monitor"),
          h("button", { className: "ent-action-btn", onClick: function () { go("sources"); } }, h(Ico, { name: "source", size: 16 }), "Add sources"),
          h("button", { className: "ent-action-btn", onClick: function () { go("team"); } }, h(Ico, { name: "team", size: 16 }), "Invite team"),
          h("button", { className: "ent-action-btn", onClick: function () { go("settings"); } }, h(Ico, { name: "settings", size: 16 }), "Set briefing time"))),
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Why set up monitors?"),
        h("div", { style: { fontSize: 12.5, color: "var(--ent-muted)", lineHeight: 1.55 } }, "Monitors tell Mira which topics, regions and organisations to track. Once you create one, Mira scans thousands of sources and surfaces the most important changes as signals, briefs and reports.")));
    return [main, rail];
  }

  function Dashboard(props) {
    var ws = props.ws, stories = props.stories, monitors = props.monitors, role = props.role;
    var toast = props.toast;
    var fresh = useMemo(function () { return stories.filter(isFresh48); }, [stories]);
    var pool = fresh.length >= 6 ? fresh : stories;
    var top = useMemo(function () {
      return pool.slice().sort(function (a, b) { return sig(b) - sig(a) || new Date(b.published || 0) - new Date(a.published || 0); }).slice(0, 6);
    }, [pool]);
    var lead = top[0];

    // brief columns derived from real lead + supporting stories
    function firstSentence(s) { if (!s) return ""; var m = String(s).split(/(?<=[.!?])\s/); return m[0] || String(s).slice(0, 160); }
    var whatChanged = lead ? firstSentence(lead.summary || lead.title) : "No fresh stories in the current window.";
    var whyMatters = top[1] ? firstSentence(top[1].deeper_summary || top[1].summary || top[1].title) : "Awaiting new developments across your monitors.";
    var whoAffected = lead ? (lead.country || lead.region || "Multiple regions") + " and connected regions." : "—";
    var watchNext = top[2] ? firstSentence(top[2].title) : "New signals as monitors update through the day.";

    // Real stories carry the outlet on `sourceName` (not `source`) — reading the
    // wrong field is why the brief showed "0 sources". Count distinct real
    // outlets; if none are resolvable, fall back to a sensible demo count for the
    // demo/preview workspace rather than showing a misleading 0.
    var srcCount = useMemo(function () {
      var s = {}; top.forEach(function (a) { var n = a.sourceName || a.source || a.outlet; if (n) s[n] = 1; });
      var real = Object.keys(s).length;
      if (real > 0) return real;
      return (ws && ws.demo) ? 8 : 0;
    }, [top, ws]);
    var srcLabel = srcCount ? (srcCount + " sources") : null;  // hide when genuinely 0

    // Ask Mira
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _ans = useState(null), ans = _ans[0], setAns = _ans[1];
    var _busy = useState(false), busy = _busy[0], setBusy = _busy[1];
    function askMira(question) {
      if (!question.trim()) return;
      setBusy(true); setAns(null);
      setTimeout(function () {
        var result = null;
        try {
          if (typeof window.answerWithMira === "function") {
            var ctx = { source: "enterprise", monitors: monitors };
            result = window.answerWithMira(question, stories, ctx);
          }
        } catch (e) { result = null; }
        if (result && result.answer) {
          setAns({ grounded: true, text: result.answer, paragraphs: result.paragraphs, sources: (result.sources || []).slice(0, 4), confidence: result.confidence, limitations: result.limitations || [] });
        } else {
          // No fabrication: surface the real matching stories and say so.
          var matches = stories.filter(function (a) {
            var t = ((a.title || "") + " " + (a.summary || "")).toLowerCase();
            return question.toLowerCase().split(/\s+/).filter(function (w) { return w.length > 3; }).some(function (w) { return t.indexOf(w) !== -1; });
          }).sort(function (a, b) { return sig(b) - sig(a); }).slice(0, 4);
          setAns({ grounded: false, matches: matches });
        }
        setBusy(false);
      }, 260);
    }

    var monCards = monitors.slice(0, 3).map(function (m) {
      var ms = monitorStories(m, pool);
      return h("div", { key: m.id, className: "ent-mon-card" },
        h("div", { className: "ent-mon-top" },
          h("div", null, h("div", { className: "ent-mon-name" }, m.name), h("div", { className: "ent-mon-scope" }, (m.regions || []).join(", ") + " · " + (m.topics || []).join(", "))),
          h(Badge, { kind: m.priority.toLowerCase() }, m.priority)),
        h("div", { className: "ent-mon-stats" },
          h("div", { className: "ent-mon-stat" }, h("div", { className: "v" }, ms.length), h("div", { className: "l" }, "signals")),
          h(Sparkline, { data: m.trend })),
        h("div", { className: "ent-mon-foot" },
          h("span", { className: "ent-mon-updated" }, "Updated " + timeAgo(ms[0] && (ms[0].published || ms[0].scraped_at) || Date.now() - 3600000)),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { go("monitors"); } }, "Open")));
    });

    var main = h("div", { className: "ent-col" },
      // header row with plan
      h("div", { className: "ent-page-hd" },
        h("div", { className: "ent-page-hd-main" },
          h("h1", { className: "ent-page-title" }, "Mira Enterprise dashboard"),
          h("p", { className: "ent-page-sub" }, "Source-grounded global development monitoring for your team.")),
        h("div", { className: "ent-page-actions" },
          h("span", { className: "ent-pill ent-pill--accent ent-pill--dot" }, "Mira Enterprise"),
          h("span", { className: "ent-pill ent-pill--ok ent-pill--dot" }, "Plan active"),
          h("span", { style: { fontWeight: 700, fontSize: "13px" } }, "$99/month"),
          h("button", { className: "ent-btn", onClick: function () { go("billing"); } }, "Manage plan"))),

      // Today's team brief
      h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("h3", null, "Today’s team brief"),
          h("div", { className: "ent-card-hd-actions" }, h("span", { className: "ent-card-hd-sub" }, (srcLabel ? srcLabel + " · " : "") + fmtDate(Date.now())))),
        h("div", { className: "ent-brief-grid" },
          h("div", { className: "ent-brief-col" }, h("div", { className: "ent-brief-col-label" }, "What changed"), h("div", { className: "ent-brief-col-text" }, whatChanged)),
          h("div", { className: "ent-brief-col" }, h("div", { className: "ent-brief-col-label" }, "Why it matters"), h("div", { className: "ent-brief-col-text" }, whyMatters)),
          h("div", { className: "ent-brief-col" }, h("div", { className: "ent-brief-col-label" }, "Who is affected"), h("div", { className: "ent-brief-col-text" }, whoAffected)),
          h("div", { className: "ent-brief-col" }, h("div", { className: "ent-brief-col-label" }, "What to watch next"), h("div", { className: "ent-brief-col-text" }, watchNext))),
        h("div", { className: "ent-brief-foot" },
          h("span", { className: "ent-brief-meta" }, h(Ico, { name: "clock", size: 14 }), timeAgo(lead && (lead.published || lead.scraped_at))),
          srcLabel ? h("span", { className: "ent-brief-meta" }, h(Ico, { name: "source", size: 14 }), srcLabel) : null,
          h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", style: { marginLeft: "auto" }, onClick: function () { go("briefings"); } }, "Open full brief", h(Ico, { name: "arrow", size: 14 })))),

      // Ask Mira
      h("div", { className: "ent-card ent-card-pad" },
        h("div", { style: { display: "flex", alignItems: "center", gap: "10px", marginBottom: "10px" } },
          h("h3", { style: { fontSize: "15px", fontWeight: 650 } }, "Ask Mira"),
          typeof window.answerWithMira === "function"
            ? h("span", { className: "ent-pill ent-pill--ok ent-pill--dot", style: { fontSize: "10px" } }, "Source-grounded")
            : h("span", { className: "ent-demo-note" }, "Shows matching sources")),
        h("div", { className: "ent-ask-input-row" },
          h("input", { className: "ent-ask-input", placeholder: "Ask about a region, topic, or trend…", value: q, onChange: function (e) { setQ(e.target.value); }, onKeyDown: function (e) { if (e.key === "Enter") askMira(q); } }),
          h("button", { className: "ent-btn ent-btn--primary", disabled: busy, onClick: function () { askMira(q); } }, busy ? "Thinking…" : "Send")),
        h("div", { className: "ent-chips" },
          ["Summarise South Asia flood risk", "What changed in food insecurity this week?", "Draft a donor update"].map(function (c) {
            return h("button", { key: c, className: "ent-chip", onClick: function () { setQ(c); askMira(c); } }, c);
          })),
        ans ? h("div", { className: "ent-ask-answer" },
          ans.grounded
            ? [
                (ans.paragraphs && ans.paragraphs.length ? ans.paragraphs : [ans.text]).map(function (p, i) { return h("p", { key: i }, p); }),
                ans.confidence ? h("div", { key: "c", className: "ent-ask-conf" }, "Confidence: " + ans.confidence + (ans.limitations && ans.limitations.length ? " · " + ans.limitations[0] : "")) : null,
                ans.sources && ans.sources.length ? h("div", { key: "s", className: "ent-ask-sources" }, ans.sources.map(function (s, i) {
                  return h("a", { key: i, className: "ent-ask-src", href: s.url || "#", target: "_blank", rel: "noopener" }, h(Ico, { name: "source", size: 12 }), (s.title || s.source || s.url || "Source").slice(0, 80));
                })) : null,
              ]
            : [
                h("p", { key: "n" }, "Mira answers only from sourced reporting. Here are the stories in today’s data most relevant to your question:"),
                h("div", { key: "m", className: "ent-ask-sources" }, (ans.matches || []).map(function (a, i) {
                  return h("a", { key: i, className: "ent-ask-src", href: a.url || "#", target: "_blank", rel: "noopener" }, h(Ico, { name: "source", size: 12 }), (a.title || "").slice(0, 90));
                })),
                (ans.matches || []).length === 0 ? h("p", { key: "e" }, "No matching stories in the current dataset.") : null,
              ]) : null),

      // Your monitors
      h("div", null,
        h("div", { style: { display: "flex", alignItems: "center", marginBottom: "12px" } },
          h("h3", { style: { fontSize: "16px", fontWeight: 650, fontFamily: "Georgia,serif" } }, "Your monitors"),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginLeft: "auto" }, onClick: function () { go("monitors"); } }, "View all", h(Ico, { name: "arrow", size: 14 }))),
        h("div", { className: "ent-mon-grid" }, monCards)),

      // Analytics
      h("div", { className: "ent-analytics-grid" },
        h(AnalyticsCard, { title: "Signals by topic", pool: pool, monitors: monitors }),
        h(SourceMixCard, { pool: top }),
        h(RecentBriefsCard, { toast: toast }))
    );

    var rail = h("div", { className: "ent-rail" },
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Top regions this week"),
        topRegions(pool).map(function (r, i) {
          return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, h(Ico, { name: "globe", size: 14 }), r.name), h("span", { className: "v" }, r.count));
        })),
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Alert level"),
        (function () {
          var high = pool.filter(function (a) { return sig(a) >= 3; }).length;
          var level = high >= 8 ? { t: "Elevated", c: "#C4442E" } : high >= 4 ? { t: "Watch", c: "#B5701E" } : { t: "Normal", c: "#4F8A54" };
          return h("div", { className: "ent-alert-meter" }, h("div", { className: "ent-alert-dot", style: { background: level.c } }, high),
            h("div", null, h("div", { style: { fontWeight: 700 } }, level.t), h("div", { style: { fontSize: "12px", color: "var(--ent-muted)" } }, high + " high-priority signals")));
        })()),
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "New source clusters"),
        clusters(top).map(function (c, i) { return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, c.name), h("span", { className: "v" }, c.count)); })),
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "For your team"),
        h("div", { className: "ent-action-list" },
          h("button", { className: "ent-action-btn", onClick: function () { toast("Update copied to clipboard"); copyText(teamUpdate(top)); } }, h(Ico, { name: "share", size: 16 }), "Share update"),
          h("button", { className: "ent-action-btn", onClick: function () { go("reports"); } }, h(Ico, { name: "download", size: 16 }), "Export PDF"),
          h("button", { className: "ent-action-btn", onClick: function () { copyText(donorNote(top)); toast("Donor note copied"); } }, h(Ico, { name: "copy", size: 16 }), "Copy donor note"),
          h("button", { className: "ent-action-btn", disabled: true }, h(Ico, { name: "slack", size: 16 }), "Send to Slack", h("span", { className: "ent-soon" }, "Soon")),
          h("button", { className: "ent-action-btn", onClick: function () { go("briefings"); } }, h(Ico, { name: "brief", size: 16 }), "Create weekly brief"))));

    return [main, rail];
  }

  function AnalyticsCard(props) {
    var counts = {};
    (props.monitors || []).forEach(function (m) { (m.topics || []).forEach(function (t) { counts[t] = 0; }); });
    props.pool.forEach(function (a) {
      var txt = ((a.title || "") + " " + (a.summary || "")).toLowerCase();
      Object.keys(TOPIC_KW).forEach(function (t) { if ((TOPIC_KW[t] || []).some(function (w) { return txt.indexOf(w) !== -1; })) counts[t] = (counts[t] || 0) + 1; });
    });
    var rows = Object.keys(counts).map(function (k) { return { k: k, v: counts[k] }; }).sort(function (a, b) { return b.v - a.v; }).slice(0, 5);
    var max = Math.max.apply(null, rows.map(function (r) { return r.v; }).concat([1]));
    return h("div", { className: "ent-card ent-card-pad" }, h("div", { className: "ent-rail-title" }, "Signals by topic"),
      h("div", { className: "ent-barlist" }, rows.map(function (r, i) {
        return h("div", { key: i, className: "ent-barlist-row" }, h("div", { className: "l" }, h("span", null, r.k), h("span", { className: "v" }, r.v)),
          h("div", { className: "ent-bar" }, h("i", { style: { width: (r.v / max * 100) + "%" } })));
      })));
  }
  function SourceMixCard(props) {
    var counts = {};
    props.pool.forEach(function (a) { var s = a.source || "Other"; counts[s] = (counts[s] || 0) + 1; });
    var rows = Object.keys(counts).map(function (k) { return { k: k, v: counts[k] }; }).sort(function (a, b) { return b.v - a.v; }).slice(0, 5);
    var max = Math.max.apply(null, rows.map(function (r) { return r.v; }).concat([1]));
    return h("div", { className: "ent-card ent-card-pad" }, h("div", { className: "ent-rail-title" }, "Source mix"),
      h("div", { className: "ent-barlist" }, rows.map(function (r, i) {
        return h("div", { key: i, className: "ent-barlist-row" }, h("div", { className: "l" }, h("span", null, (r.k || "").slice(0, 22)), h("span", { className: "v" }, r.v)),
          h("div", { className: "ent-bar" }, h("i", { style: { width: (r.v / max * 100) + "%" } })));
      })));
  }
  function RecentBriefsCard(props) {
    var briefs = [
      { t: "Daily team brief", d: fmtDate(Date.now()) },
      { t: "Daily team brief", d: fmtDate(Date.now() - 86400000) },
      { t: "Weekly intelligence report", d: fmtDate(Date.now() - 86400000 * 3) },
    ];
    return h("div", { className: "ent-card ent-card-pad" }, h("div", { className: "ent-rail-title" }, "Recent briefs"),
      briefs.map(function (b, i) { return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, h(Ico, { name: "brief", size: 14 }), b.t), h("span", { style: { fontSize: "12px", color: "var(--ent-muted)" } }, b.d)); }));
  }
  function topRegions(pool) {
    var c = {};
    pool.forEach(function (a) { var rg = a.region || a.country; if (rg) c[rg] = (c[rg] || 0) + 1; });
    return Object.keys(c).map(function (k) { return { name: k, count: c[k] }; }).sort(function (a, b) { return b.count - a.count; }).slice(0, 5);
  }
  function clusters(top) {
    var c = {};
    top.forEach(function (a) { var t = (a.topic || a.category || "General"); c[t] = (c[t] || 0) + 1; });
    return Object.keys(c).map(function (k) { return { name: k, count: c[k] }; }).slice(0, 4);
  }
  function teamUpdate(top) {
    return "Globly Enterprise — team update\n\n" + top.slice(0, 3).map(function (a, i) { return (i + 1) + ". " + a.title; }).join("\n");
  }
  function donorNote(top) {
    return "Dear partner,\n\nThis week our monitors surfaced the following developments relevant to our work:\n\n" +
      top.slice(0, 3).map(function (a) { return "• " + a.title + " (" + (a.source || "source") + ")"; }).join("\n") +
      "\n\nWe are tracking these closely and will follow up with analysis.\n\nWith thanks,\nYour team";
  }
  function copyText(t) {
    // clipboard.writeText returns a promise that REJECTS when permission is
    // denied (e.g. no focus) — swallow it so it never surfaces as an unhandled
    // rejection, and fall back to the legacy execCommand copy.
    try {
      if (navigator.clipboard && navigator.clipboard.writeText) {
        var p = navigator.clipboard.writeText(t);
        if (p && p.catch) p.catch(function () { legacyCopy(t); });
        return;
      }
    } catch (e) {}
    legacyCopy(t);
  }
  function legacyCopy(t) {
    try {
      var ta = document.createElement("textarea");
      ta.value = t; ta.style.position = "fixed"; ta.style.opacity = "0";
      document.body.appendChild(ta); ta.select();
      document.execCommand("copy");
      document.body.removeChild(ta);
    } catch (e) {}
  }

  // ============================================================
  //  MONITORS
  // ============================================================
  // Monitor row icon helpers ─────────────────────────────────────────────────
  function monInitials(name) {
    var stop = { and: 1, the: 1, of: 1, "in": 1, "for": 1 };
    var words = String(name || "M").split(/[\s\-&]+/).filter(function (w) { return w && !stop[w.toLowerCase()]; });
    if (words.length >= 2) return (words[0].charAt(0) + words[1].charAt(0)).toUpperCase();
    return (words[0] || "M").slice(0, 2).toUpperCase();
  }
  function monTint(m) {
    var p = (m && m.priority) || "Medium";
    if (p === "High") return { bg: "#EDE9FE", fg: "#6D28D9" };
    if (p === "Low") return { bg: "#E6F2E6", fg: "#4B8B54" };
    return { bg: "#FBEFD8", fg: "#B5771E" };
  }

  // Real daily activity for a monitor: counts of matched stories per day for the
  // last N days (index 0 = oldest, last = today). Derived preview data — grouped
  // from real Globly stories by published date; there is no signals table yet.
  function monitorDaily(m, stories, N) {
    var matched = monitorStories(m, stories || []);
    var counts = [], crit = [], i;
    for (i = 0; i < N; i++) { counts.push(0); crit.push(0); }
    var now = Date.now();
    matched.forEach(function (a) {
      var ts = new Date(a.published || a.scraped_at || 0).getTime();
      if (!ts) return;
      var ago = Math.floor((now - ts) / 86400000);
      if (ago >= 0 && ago < N) { var idx = N - 1 - ago; counts[idx]++; if (sig(a) >= 3) crit[idx]++; }
    });
    return { counts: counts, crit: crit };
  }

  var ENT_MON = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  var ENT_WDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

  // Range stats for a monitor over a window (7 or 30 days), from real daily data.
  function monitorRangeStats(m, stories, range) {
    var N = range === "30" ? 30 : 7;
    var win = monitorDaily(m, stories || [], N * 2);
    var data = win.counts.slice(N), prevData = win.counts.slice(0, N), critData = win.crit.slice(N);
    var total = data.reduce(function (a, b) { return a + b; }, 0);
    var prevTotal = prevData.reduce(function (a, b) { return a + b; }, 0);
    var critTotal = critData.reduce(function (a, b) { return a + b; }, 0);
    var highest = data.length ? Math.max.apply(null, data) : 0;
    var avg = data.length ? Math.round((total / data.length) * 10) / 10 : 0;
    var hasData = total > 0, trendTxt, trendCol;
    if (prevTotal === 0) { trendTxt = "Not enough data"; trendCol = "var(--ent-muted)"; }
    else { var pct = Math.round(((total - prevTotal) / prevTotal) * 100); trendTxt = (pct >= 0 ? "Up " : "Down ") + Math.abs(pct) + "%"; trendCol = pct >= 0 ? "#4B8B54" : "var(--ent-hi)"; }
    return { N: N, data: data, total: total, prevTotal: prevTotal, critTotal: critTotal, highest: highest, avg: avg, hasData: hasData, trendTxt: trendTxt, trendCol: trendCol };
  }

  // Shared full activity chart (used by the modal AND the detail page so they match).
  // Real x/y axes, grid, tooltip and date labels. Pass key={range} to reset hover.
  function MonitorActivityChart(props) {
    var data = props.data || [], N = props.N || 7, range = props.range || (N === 30 ? "30" : "7");
    var _hov = useState(null), hov = _hov[0], setHov = _hov[1];
    var hasData = data.reduce(function (a, b) { return a + b; }, 0) > 0;
    function dateOf(i) { return new Date(Date.now() - (N - 1 - i) * 86400000); }
    function shortDate(i) { var d = dateOf(i); return d.getDate() + " " + ENT_MON[d.getMonth()]; }
    function xLabel(i) {
      var d = dateOf(i);
      if (N === 7) return ENT_WDAY[d.getDay()];
      if (i === 0 || i === N - 1 || i === Math.floor((N - 1) / 2)) return shortDate(i);
      return "";
    }
    if (!hasData) return h("div", { style: { minHeight: 190, display: "grid", placeItems: "center", textAlign: "center", padding: 20, background: "var(--ent-surface-2)", border: "1px dashed var(--ent-border)", borderRadius: 10 } },
      h("div", null,
        h("div", { style: { fontWeight: 700, color: "var(--ent-ink)", marginBottom: 4 } }, "Not enough signal history yet"),
        h("div", { style: { fontSize: 12.5, color: "var(--ent-muted)" } }, "Mira has not detected activity for this monitor in the last " + N + " days.")));
    var col = "#7C3AED";
    var W = 600, H = 252, mL = 46, mR = 16, mT = 14, mB = 48, iw = W - mL - mR, ih = H - mT - mB;
    var highest = Math.max.apply(null, data);
    var niceMax = Math.max(4, Math.ceil(Math.max(1, highest) / 4) * 4);
    function X(i) { return mL + (data.length <= 1 ? 0 : (i / (data.length - 1)) * iw); }
    function Y(v) { return mT + ih - (v / niceMax) * ih; }
    var line = data.map(function (v, i) { return X(i).toFixed(1) + "," + Y(v).toFixed(1); }).join(" ");
    var area = X(0).toFixed(1) + "," + (mT + ih) + " " + line + " " + X(data.length - 1).toFixed(1) + "," + (mT + ih);
    var yTicks = [0, 1, 2, 3, 4].map(function (t) { return Math.round(niceMax * t / 4); });
    var gid = "mcg_" + N;
    function onMove(e) {
      var rect = e.currentTarget.getBoundingClientRect();
      var px = (e.clientX - rect.left) * (W / rect.width);
      var idx = Math.round((px - mL) / (iw / Math.max(1, data.length - 1)));
      setHov(Math.max(0, Math.min(data.length - 1, idx)));
    }
    return h("svg", { width: "100%", viewBox: "0 0 " + W + " " + H, style: { display: "block", maxWidth: "100%" }, onMouseMove: onMove, onMouseLeave: function () { setHov(null); } },
      h("defs", null, h("linearGradient", { id: gid, x1: 0, y1: 0, x2: 0, y2: 1 }, h("stop", { offset: "0%", stopColor: col, stopOpacity: 0.20 }), h("stop", { offset: "100%", stopColor: col, stopOpacity: 0 }))),
      h("text", { x: 13, y: mT + ih / 2, fontSize: 10, fill: "#9A9184", textAnchor: "middle", transform: "rotate(-90 13 " + (mT + ih / 2) + ")" }, "Signals detected"),
      yTicks.map(function (val, k) { var y = Y(val); return h("g", { key: "g" + k },
        h("line", { x1: mL, y1: y, x2: mL + iw, y2: y, stroke: "#1A1712", strokeOpacity: 0.07, strokeWidth: 1 }),
        h("text", { x: mL - 8, y: y + 3, textAnchor: "end", fontSize: 10, fill: "#9A9184" }, val)); }),
      data.map(function (v, i) { var lbl = xLabel(i); return lbl ? h("text", { key: "x" + i, x: X(i), y: mT + ih + 16, textAnchor: "middle", fontSize: 9.5, fill: "#9A9184" }, lbl) : null; }),
      h("text", { x: mL + iw / 2, y: H - 6, fontSize: 10, fill: "#9A9184", textAnchor: "middle" }, "Date"),
      h("polygon", { points: area, fill: "url(#" + gid + ")" }),
      h("polyline", { points: line, fill: "none", stroke: col, strokeWidth: 2, strokeLinejoin: "round", strokeLinecap: "round" }),
      hov != null ? h("g", null,
        h("line", { x1: X(hov), y1: mT, x2: X(hov), y2: mT + ih, stroke: col, strokeOpacity: 0.35, strokeWidth: 1 }),
        h("circle", { cx: X(hov), cy: Y(data[hov]), r: 4, fill: col, stroke: "#fff", strokeWidth: 1.5 }),
        h("g", { transform: "translate(" + Math.min(Math.max(X(hov) - 46, mL), mL + iw - 92) + ",0)" },
          h("rect", { width: 92, height: 22, rx: 5, fill: "#1A1712" }),
          h("text", { x: 46, y: 15, textAnchor: "middle", fontSize: 10.5, fontWeight: 700, fill: "#fff" }, data[hov] + " · " + shortDate(hov)))) : null,
      h("circle", { cx: X(data.length - 1), cy: Y(data[data.length - 1]), r: 3, fill: col }));
  }

  function MonitorChartModal(props) {
    var m = props.monitor, st = props.stats || {}, stories = props.stories || [];
    var _r = useState("7"), range = _r[0], setRange = _r[1];
    var rs = monitorRangeStats(m, stories, range);
    function statBox(label, val, accent) {
      return h("div", { style: { flex: "1 1 92px", background: "var(--ent-surface-2)", border: "1px solid var(--ent-border-2)", borderRadius: 10, padding: "10px 12px" } },
        h("div", { style: { fontSize: 11, color: "var(--ent-muted)" } }, label),
        h("div", { style: { fontSize: 16, fontWeight: 800, color: accent || "var(--ent-ink)", fontFamily: "var(--ent-serif)" } }, val));
    }
    return h(Modal, { title: "Monitor activity", wide: true, onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Close"),
        h("button", { key: "d", className: "ent-btn ent-btn--primary", onClick: function () { props.onClose(); goMonitor(m.id); } }, "Open monitor details")] },
      h("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 10, flexWrap: "wrap" } },
        h("div", { style: { width: 34, height: 34, borderRadius: 10, display: "grid", placeItems: "center", background: monTint(m).bg, color: monTint(m).fg, fontWeight: 800, fontSize: 12 } }, monInitials(m.name)),
        h("div", { style: { fontSize: 17, fontWeight: 700 } }, m.name),
        h("div", { style: { marginLeft: "auto", display: "inline-flex", border: "1px solid var(--ent-border)", borderRadius: 8, overflow: "hidden" } },
          ["7", "30"].map(function (r) { return h("button", { key: r, className: "ent-btn ent-btn--ghost ent-btn--sm", style: { borderRadius: 0, background: range === r ? "var(--ent-accent-t)" : "transparent", color: range === r ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setRange(r); } }, r + " days"); }))),
      h("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px 16px", fontSize: 12.5, color: "var(--ent-muted)", marginBottom: 12 } },
        h("span", null, "Topic: ", h("strong", { style: { color: "var(--ent-ink)" } }, (m.topics || []).join(", ") || "—")),
        h("span", null, "Regions: ", h("strong", { style: { color: "var(--ent-ink)" } }, (m.regions || []).join(", ") || "—")),
        h("span", null, "Priority: ", h("strong", { style: { color: "var(--ent-ink)" } }, m.priority)),
        h("span", null, "Signals today: ", h("strong", { style: { color: "var(--ent-ink)" } }, st.count)),
        h("span", null, "Updated ", h("strong", { style: { color: "var(--ent-ink)" } }, timeAgo(st.updatedTs)))),
      h("div", { style: { fontSize: 11, color: "var(--ent-muted)", marginBottom: 4 } }, "Signals detected · " + (range === "7" ? "last 7 days" : "last 30 days") + " · derived from real Globly stories"),
      h(MonitorActivityChart, { key: range, data: rs.data, N: rs.N, range: range }),
      h("div", { style: { display: "flex", gap: 10, flexWrap: "wrap", marginTop: 14 } },
        statBox("Total signals", rs.hasData ? rs.total : "—"),
        statBox("Highest day", rs.hasData ? rs.highest : "—"),
        statBox("Avg per day", rs.hasData ? rs.avg : "—"),
        statBox("Critical changes", rs.critTotal, rs.critTotal > 0 ? "var(--ent-hi)" : null),
        statBox("Trend", rs.trendTxt, rs.trendCol)));
  }

  // TODO: protect monitor detail pages with workspace access before launch.
  function MonitorDetailPage(props) {
    var ws = props.ws, stories = props.stories || [], role = props.role, toast = props.toast, monitorId = props.monitorId;
    var _list = useState(function () { return Store.monitors(ws.id); }), list = _list[0], setList = _list[1];
    var _range = useState("7"), range = _range[0], setRange = _range[1];
    var _modal = useState(false), modal = _modal[0], setModal = _modal[1];
    var canEdit = role === "Team Admin" || role === "Admin" || role === "Analyst";
    var m = list.filter(function (x) { return x.id === monitorId; })[0];

    if (!m) {
      return h("div", null,
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginBottom: 14 }, onClick: function () { go("monitors"); } }, "← Back to Monitors"),
        h(PageHead, { title: "Monitor not found", sub: "This monitor does not exist or is no longer part of this workspace." }),
        h("div", { className: "ent-card", style: { textAlign: "center", padding: "40px 20px" } },
          h(EmptyState, { icon: "monitor", text: "We could not find that monitor." }),
          h("button", { className: "ent-btn ent-btn--primary", style: { marginTop: 14 }, onClick: function () { go("monitors"); } }, "Back to Monitors")));
    }

    function persist(next) { setList(next); Store.setMonitors(ws.id, next); }
    function togglePause() { persist(list.map(function (x) { return x.id === m.id ? Object.assign({}, x, { paused: !x.paused }) : x; })); toast(m.paused ? "Monitor resumed" : "Monitor paused"); }
    function del() { if (typeof window !== "undefined" && window.confirm && !window.confirm("Delete this monitor? This cannot be undone.")) return; persist(list.filter(function (x) { return x.id !== m.id; })); toast("Monitor deleted"); go("monitors"); }
    function saveMonitor(mon) { persist(list.map(function (x) { return x.id === mon.id ? mon : x; })); setModal(false); toast("Monitor saved"); }

    var rs = monitorRangeStats(m, stories, range);
    var series60 = monitorDaily(m, stories, 60);
    var todayCount = series60.counts[series60.counts.length - 1];
    var matched = monitorStories(m, stories);
    var updatedTs = (matched[0] && (matched[0].published || matched[0].scraped_at)) || (Date.now() - 7200000);
    var recent = matched.slice(0, 8);
    var srcSet = {}; matched.forEach(function (a) { if (a.source) srcSet[a.source] = 1; });
    var sources = Object.keys(srcSet);
    var freq = m.frequency || "Daily";
    var includedIn = ["Dashboard"].concat(freq === "Weekly" ? [] : ["Daily briefing"]).concat(["Weekly reports"]);
    var alertLevel = m.priority === "High" ? "High — real-time alerts" : m.priority === "Low" ? "Low — digest only" : "Standard — daily";

    function scopeCard(title, icon, rows) {
      return h("div", { className: "ent-card", style: { padding: 18 } },
        h("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 12 } }, h(Ico, { name: icon, size: 16 }), h("div", { style: { fontSize: 14, fontWeight: 700, color: "var(--ent-ink)" } }, title)),
        h("div", { style: { display: "flex", flexDirection: "column", gap: 10 } }, rows));
    }
    function fieldRow(label, value) {
      return h("div", { key: label, style: { display: "flex", justifyContent: "space-between", gap: 12, fontSize: 12.5 } },
        h("span", { style: { color: "var(--ent-muted)" } }, label),
        h("span", { style: { color: "var(--ent-ink)", fontWeight: 600, textAlign: "right" } }, value));
    }
    function chipRow(label, items) {
      return h("div", { key: label },
        h("div", { style: { fontSize: 11.5, color: "var(--ent-muted)", marginBottom: 6 } }, label),
        h("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 } }, (items && items.length ? items : ["—"]).map(function (t, i) { return h("span", { key: i, className: "ent-badge ent-badge--pending" }, t); })));
    }

    return h("div", null,
      h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginBottom: 14 }, onClick: function () { go("monitors"); } }, "← Back to Monitors"),
      // Header
      h("div", { className: "ent-card", style: { padding: 20, marginBottom: 16, opacity: m.paused ? 0.72 : 1 } },
        h("div", { style: { display: "flex", alignItems: "flex-start", gap: 14, flexWrap: "wrap" } },
          h("div", { style: { width: 46, height: 46, borderRadius: 12, flex: "none", display: "grid", placeItems: "center", background: monTint(m).bg, color: monTint(m).fg, fontWeight: 800, fontSize: 15 } }, monInitials(m.name)),
          h("div", { style: { flex: "1 1 240px", minWidth: 220 } },
            h("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
              h("h1", { style: { fontFamily: "var(--ent-serif)", fontSize: 24, fontWeight: 700, color: "var(--ent-ink)", margin: 0 } }, m.name),
              m.topics && m.topics[0] ? h("span", { className: "ent-badge ent-badge--pending" }, m.topics[0]) : null,
              h("span", { className: "ent-badge ent-badge--" + m.priority.toLowerCase() }, h(Ico, { name: "signal", size: 11 }), m.priority + " Priority"),
              m.paused ? h("span", { className: "ent-badge ent-badge--inactive" }, "Paused") : h("span", { className: "ent-badge ent-badge--active" }, "Active")),
            h("div", { style: { display: "flex", flexWrap: "wrap", gap: "4px 14px", marginTop: 8, fontSize: 12.5, color: "var(--ent-muted)" } },
              h("span", null, "Regions: ", h("strong", { style: { color: "var(--ent-ink)" } }, (m.regions || []).join(", ") || "—")),
              h("span", null, "Frequency: ", h("strong", { style: { color: "var(--ent-ink)" } }, freq)),
              h("span", null, "Updated ", h("strong", { style: { color: "var(--ent-ink)" } }, timeAgo(updatedTs))))),
          h("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" } },
            canEdit ? h("button", { className: "ent-btn ent-btn--sm", onClick: function () { setModal(true); } }, h(Ico, { name: "pencil", size: 14 }), "Edit") : null,
            canEdit ? h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: togglePause }, h(Ico, { name: "pause", size: 14 }), m.paused ? "Resume" : "Pause") : null,
            canEdit ? h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { color: "var(--ent-hi)" }, onClick: del }, h(Ico, { name: "trash", size: 14 }), "Delete") : null)))
      ,
      // Overview cards
      h("div", { className: "ent-kpis", style: { marginBottom: 16 } },
        h(KPI, { label: "Signals today", value: todayCount, icon: "signal", delta: "Detected today", trend: "flat" }),
        h(KPI, { label: "Total · " + (range === "7" ? "7 days" : "30 days"), value: rs.hasData ? rs.total : "—", icon: "spark", delta: "Selected period", trend: "flat" }),
        h(KPI, { label: "Critical changes", value: rs.critTotal, icon: "bell", delta: rs.critTotal > 0 ? "Needs attention" : "None flagged", trend: rs.critTotal > 0 ? "down" : "flat" }),
        h(KPI, { label: "Avg per day", value: rs.hasData ? rs.avg : "—", icon: "clock", delta: rs.trendTxt, trend: "flat" })),
      // Main activity graph
      h("div", { className: "ent-card", style: { padding: 20, marginBottom: 16 } },
        h("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 6, flexWrap: "wrap" } },
          h("div", { style: { fontSize: 15, fontWeight: 700, color: "var(--ent-ink)" } }, "Activity"),
          h("div", { style: { marginLeft: "auto", display: "inline-flex", border: "1px solid var(--ent-border)", borderRadius: 8, overflow: "hidden" } },
            ["7", "30"].map(function (r) { return h("button", { key: r, className: "ent-btn ent-btn--ghost ent-btn--sm", style: { borderRadius: 0, background: range === r ? "var(--ent-accent-t)" : "transparent", color: range === r ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setRange(r); } }, r + " days"); }))),
        h("div", { style: { fontSize: 11, color: "var(--ent-muted)", marginBottom: 8 } }, "Signals detected · " + (range === "7" ? "last 7 days" : "last 30 days") + " · derived from real Globly stories"),
        h(MonitorActivityChart, { key: range, data: rs.data, N: rs.N, range: range })),
      // Recent signals
      h("div", { className: "ent-card", style: { marginBottom: 16 } },
        h("div", { style: { padding: "16px 18px 4px", fontSize: 15, fontWeight: 700, color: "var(--ent-ink)" } }, "Recent signals"),
        recent.length === 0
          ? h("div", { style: { padding: "8px 18px 20px" } }, h(EmptyState, { icon: "signal", text: "No recent signals for this monitor yet." }))
          : h("div", { className: "ent-list" }, recent.map(function (a) {
              var pr = priorityFromSig(sig(a));
              return h("div", { key: (a.url || a.title), className: "ent-item" },
                h("div", { className: "ent-item-body" },
                  h("div", { className: "ent-item-title" }, a.url ? h("a", { href: a.url, target: "_blank", rel: "noopener" }, a.title) : a.title),
                  a.summary ? h("div", { className: "ent-item-expl" }, String(a.summary).slice(0, 140)) : null,
                  h("div", { className: "ent-item-meta" },
                    a.source ? h("span", null, a.source) : null,
                    h("span", null, h(Ico, { name: "clock", size: 12 }), " " + timeAgo(a.published || a.scraped_at)))),
                h("div", { className: "ent-item-side" }, h(Badge, { kind: pr.toLowerCase() }, pr)));
            }))),
      // Scope / coverage / settings
      h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))", gap: 16 } },
        scopeCard("Tracked scope", "monitor", [
          chipRow("Topics", m.topics),
          chipRow("Regions", m.regions),
          chipRow("Source types", m.sourceTypes),
          chipRow("Included in", includedIn),
        ]),
        scopeCard("Source coverage", "globe", [
          fieldRow("Sources scanned", String(sources.length)),
          fieldRow("Source categories", (m.sourceTypes || []).join(", ") || "—"),
          fieldRow("Latest source update", timeAgo(updatedTs)),
          fieldRow("Coverage status", m.paused ? "Paused" : "Live"),
          sources.length ? h("div", { key: "src", style: { display: "flex", flexWrap: "wrap", gap: 6, marginTop: 2 } }, sources.slice(0, 6).map(function (s, i) { return h("span", { key: i, className: "ent-badge ent-badge--pending" }, s); })) : null,
        ]),
        scopeCard("Settings", "settings", [
          fieldRow("Alert level", alertLevel),
          fieldRow("Briefing frequency", freq),
          fieldRow("Email alerts", m.priority === "Low" ? "Off" : "On"),
          fieldRow("Report inclusion", "Weekly reports"),
          canEdit ? h("button", { key: "edit", className: "ent-btn ent-btn--sm", style: { marginTop: 4, alignSelf: "flex-start" }, onClick: function () { setModal(true); } }, h(Ico, { name: "pencil", size: 14 }), "Edit monitor settings") : null,
        ])),
      modal ? h(MonitorModal, { monitor: m, onSave: saveMonitor, onClose: function () { setModal(false); } }) : null);
  }

  function MonitorsPage(props) {
    var ws = props.ws, stories = props.stories, role = props.role, toast = props.toast;
    var _list = useState(function () { return Store.monitors(ws.id); }), list = _list[0], setList = _list[1];
    var _modal = useState(null), modal = _modal[0], setModal = _modal[1]; // null | 'new' | monitor
    var _chart = useState(null), chart = _chart[0], setChart = _chart[1]; // monitor for the activity chart modal
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _sf = useState("All Status"), sf = _sf[0], setSf = _sf[1];
    var _tf = useState("All Types"), tf = _tf[0], setTf = _tf[1];
    var _sort = useState("Newest"), sort = _sort[0], setSort = _sort[1];
    var _view = useState("list"), view = _view[0], setView = _view[1];   // list is the default
    var _menu = useState(null), menu = _menu[0], setMenu = _menu[1];      // open three-dot menu id
    var canEdit = role === "Team Admin" || role === "Admin" || role === "Analyst";
    var pool = stories.filter(isFresh48); if (pool.length < 6) pool = stories;

    // close the three-dot menu on any outside click
    useEffect(function () {
      function onDoc() { setMenu(null); }
      window.addEventListener("click", onDoc);
      return function () { window.removeEventListener("click", onDoc); };
    }, []);

    function persist(next) { setList(next); Store.setMonitors(ws.id, next); }
    // TODO: Persist Enterprise monitors to workspace database before launch.
    function saveMonitor(mon) {
      var next, created = false;
      if (mon.id && list.some(function (m) { return m.id === mon.id; })) next = list.map(function (m) { return m.id === mon.id ? mon : m; });
      else {
        created = true;
        mon.id = "m" + Date.now().toString(36);
        var seed = mon.history7 || [2, 3, 3, 4, 3, 5, 4];
        mon.history7 = seed; mon.trend = seed; mon.history30 = entHist30(seed); mon.signalsToday = seed[seed.length - 1]; mon.critical = (typeof mon.critical === "number") ? mon.critical : 1;
        mon.createdAt = Date.now();
        next = list.concat([mon]);
      }
      persist(next); setModal(null);
      toast(created ? "Monitor created. Mira will start tracking this for your team." : "Monitor saved");
    }
    function removeMonitor(id) { persist(list.filter(function (m) { return m.id !== id; })); toast("Monitor deleted"); }
    function togglePause(m) {
      persist(list.map(function (x) { return x.id === m.id ? Object.assign({}, x, { paused: !x.paused }) : x; }));
      toast(m.paused ? "Monitor resumed" : "Monitor paused");
    }

    // per-monitor computed stats derived from REAL story data
    var _statCache = {};
    function statsFor(m) {
      if (m.id && _statCache[m.id]) return _statCache[m.id];
      var matched = monitorStories(m, stories);
      var N = 60, counts = [], crit = [], i;
      for (i = 0; i < N; i++) { counts.push(0); crit.push(0); }
      var now = Date.now();
      matched.forEach(function (a) {
        var ts = new Date(a.published || a.scraped_at || 0).getTime(); if (!ts) return;
        var ago = Math.floor((now - ts) / 86400000);
        if (ago >= 0 && ago < N) { var idx = N - 1 - ago; counts[idx]++; if (sig(a) >= 3) crit[idx]++; }
      });
      var updatedTs = (matched[0] && (matched[0].published || matched[0].scraped_at)) || (Date.now() - 7200000);
      var res = { count: counts[N - 1], critical: crit[N - 1], updatedTs: updatedTs, counts60: counts };
      if (m.id) _statCache[m.id] = res;
      return res;
    }
    function criticalLabel(n) { return n === 0 ? "No critical changes" : n === 1 ? "1 critical change" : n + " critical changes"; }

    // Type filter options derived from the monitors' own topics
    var typeOpts = (function () {
      var s = {}; list.forEach(function (m) { (m.topics || []).forEach(function (t) { s[t] = 1; }); });
      return ["All Types"].concat(Object.keys(s));
    })();

    var filtered = list.filter(function (m) {
      if (sf === "Active" && m.paused) return false;
      if (sf === "Paused" && !m.paused) return false;
      if (sf === "High Priority" && m.priority !== "High") return false;
      if (sf === "Medium Priority" && m.priority !== "Medium") return false;
      if (sf === "Low Priority" && m.priority !== "Low") return false;
      if (tf !== "All Types" && (m.topics || []).indexOf(tf) === -1) return false;
      if (q) {
        var hay = (m.name + " " + (m.topics || []).join(" ") + " " + (m.regions || []).join(" ") + " " + (m.priority || "")).toLowerCase();
        if (hay.indexOf(q.toLowerCase()) === -1) return false;
      }
      return true;
    });
    var PRI = { High: 0, Medium: 1, Low: 2 };
    filtered = filtered.slice().sort(function (a, b) {
      if (sort === "Priority") return (PRI[a.priority] - PRI[b.priority]);
      if (sort === "Signals today") return statsFor(b).count - statsFor(a).count;
      if (sort === "Last updated") return statsFor(b).updatedTs - statsFor(a).updatedTs;
      return (b.createdAt || 0) - (a.createdAt || 0); // Newest
    });

    var signalsToday = list.filter(function (m) { return !m.paused; }).reduce(function (n, m) { return n + statsFor(m).count; }, 0);
    var highCount = list.filter(function (m) { return m.priority === "High"; }).length;
    var regionsTracked = (function () { var s = {}; list.forEach(function (m) { (m.regions || []).forEach(function (r) { s[r] = 1; }); }); return Object.keys(s).length; })();

    // three-dot menu (View / Edit / Pause / Delete)
    function rowMenu(m) {
      return h("div", { style: { position: "relative" }, onClick: function (e) { e.stopPropagation(); } },
        h("button", { className: "ent-menu-btn", "aria-label": "Monitor actions", "aria-haspopup": "true", "aria-expanded": menu === m.id,
          onClick: function () { setMenu(menu === m.id ? null : m.id); } }, h(Ico, { name: "dots", size: 16 })),
        menu === m.id ? h("div", { className: "ent-tb-menu-pop", style: { top: "32px", right: 0, minWidth: "176px" } },
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); goMonitor(m.id); } }, h(Ico, { name: "eye", size: 15 }), "View monitor"),
          canEdit ? h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setModal(m); } }, h(Ico, { name: "pencil", size: 15 }), "Edit monitor") : null,
          canEdit ? h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); togglePause(m); } }, h(Ico, { name: "pause", size: 15 }), m.paused ? "Resume monitor" : "Pause monitor") : null,
          canEdit ? h("button", { className: "ent-tb-menu-item", style: { color: "var(--ent-hi)" }, onClick: function () { setMenu(null); removeMonitor(m.id); } }, h(Ico, { name: "trash", size: 15 }), "Delete monitor") : null
        ) : null);
    }

    function priBadge(m) { return h("span", { className: "ent-badge ent-badge--" + m.priority.toLowerCase() }, h(Ico, { name: "signal", size: 11 }), m.priority + " Priority"); }
    function topicTag(m) { return (m.topics && m.topics[0]) ? h("span", { className: "ent-badge ent-badge--pending" }, m.topics[0]) : null; }
    function critText(n) { return h("span", { style: { fontSize: "11.5px", fontWeight: 600, color: n > 0 ? "var(--ent-hi)" : "var(--ent-faint)" } }, criticalLabel(n)); }

    // ── list row ──
    function row(m) {
      var st = statsFor(m);
      return h("div", { key: m.id, className: "ent-item", style: { alignItems: "center", flexWrap: "wrap", opacity: m.paused ? 0.62 : 1 } },
        h("div", { style: { flex: "none", width: 38, height: 38, borderRadius: 11, display: "grid", placeItems: "center", background: monTint(m).bg, color: monTint(m).fg, fontSize: 13, fontWeight: 800, letterSpacing: "0.02em", fontFamily: "var(--ent-font)" }, "aria-hidden": "true" }, monInitials(m.name)),
        h("div", { style: { flex: "1 1 220px", minWidth: "200px" } },
          h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } },
            h("span", { className: "ent-item-title", style: { cursor: "pointer" }, title: "Open monitor details", onClick: function () { goMonitor(m.id); } }, m.name),
            topicTag(m),
            m.paused ? h("span", { className: "ent-badge ent-badge--inactive" }, "Paused") : null),
          h("div", { className: "ent-mon-scope", style: { marginTop: "3px" } }, (m.regions || []).join(", "))),
        h(Sparkline, { data: st.counts60.slice(-7), gid: m.id, onClick: function () { setChart(m); } }),
        h("div", { style: { textAlign: "center", minWidth: "64px", flex: "none" } },
          h("div", { style: { fontFamily: "var(--ent-serif)", fontSize: "18px", fontWeight: 700 } }, st.count),
          h("div", { style: { fontSize: "10.5px", color: "var(--ent-muted)" } }, "signals today")),
        h("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "4px", minWidth: "128px", flex: "none" } },
          priBadge(m), critText(st.critical)),
        h("span", { className: "ent-mon-updated", style: { minWidth: "78px", flex: "none" } }, timeAgo(st.updatedTs)),
        rowMenu(m));
    }

    // ── grid card ──
    function card(m) {
      var st = statsFor(m);
      return h("div", { key: m.id, className: "ent-mon-card", style: { opacity: m.paused ? 0.62 : 1 } },
        h("div", { className: "ent-mon-top" },
          h("div", null,
            h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } }, h("div", { className: "ent-mon-name" }, m.name), m.paused ? h("span", { className: "ent-badge ent-badge--inactive" }, "Paused") : null),
            h("div", { className: "ent-mon-scope" }, (m.regions || []).join(", "))),
          rowMenu(m)),
        h("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap" } }, topicTag(m), priBadge(m)),
        h("div", { className: "ent-mon-stats" },
          h("div", { className: "ent-mon-stat" }, h("div", { className: "v" }, st.count), h("div", { className: "l" }, "signals today")),
          h(Sparkline, { data: st.counts60.slice(-7), gid: m.id + "_c", onClick: function () { setChart(m); } })),
        h("div", { className: "ent-mon-foot" },
          h("span", { className: "ent-mon-updated" }, m.frequency + " · " + timeAgo(st.updatedTs)),
          critText(st.critical)));
    }

    return h("div", null,
      h(PageHead, {
        title: "Monitors",
        sub: "Your monitors track the topics, regions and organisations that matter to your team. Mira scans thousands of sources and surfaces the most important changes.",
        actions: canEdit ? h("button", { className: "ent-btn ent-btn--primary", onClick: function () { setModal("new"); } }, h(Ico, { name: "plus", size: 15 }), "New Monitor") : null,
      }),
      h("div", { className: "ent-kpis", style: { marginBottom: "18px" } },
        h(KPI, { label: "Active monitors", value: list.filter(function (m) { return !m.paused; }).length, icon: "monitor", delta: "Monitoring in real time", trend: "flat" }),
        h(KPI, { label: "Signals today", value: signalsToday, icon: "signal", delta: "Across all monitors", trend: "flat" }),
        h(KPI, { label: "High priority", value: highCount, icon: "bell", delta: "Needs your attention", trend: highCount > 0 ? "down" : "flat" }),
        h(KPI, { label: "Regions tracked", value: regionsTracked, icon: "globe", delta: "Across " + list.length + " monitors", trend: "flat" })),
      h("div", { className: "ent-filters" },
        h("div", { className: "ent-search-box" }, h(Ico, { name: "search", size: 15 }), h("input", { placeholder: "Search monitors…", value: q, onChange: function (e) { setQ(e.target.value); } })),
        h("select", { className: "ent-select", value: sf, "aria-label": "Filter by status", onChange: function (e) { setSf(e.target.value); } }, ["All Status", "Active", "Paused", "High Priority", "Medium Priority", "Low Priority"].map(function (p) { return h("option", { key: p }, p); })),
        h("select", { className: "ent-select", value: tf, "aria-label": "Filter by type", onChange: function (e) { setTf(e.target.value); } }, typeOpts.map(function (p) { return h("option", { key: p }, p); })),
        h("select", { className: "ent-select", value: sort, "aria-label": "Sort", onChange: function (e) { setSort(e.target.value); } }, ["Newest", "Priority", "Signals today", "Last updated"].map(function (p) { return h("option", { key: p, value: p }, "Sort: " + p); })),
        h("div", { style: { display: "inline-flex", border: "1px solid var(--ent-border)", borderRadius: "var(--ent-radius-s)", overflow: "hidden", marginLeft: "auto" } },
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", "aria-label": "List view", "aria-pressed": view === "list", style: { borderRadius: 0, background: view === "list" ? "var(--ent-accent-t)" : "transparent", color: view === "list" ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setView("list"); } }, h(Ico, { name: "menu", size: 15 })),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", "aria-label": "Grid view", "aria-pressed": view === "grid", style: { borderRadius: 0, background: view === "grid" ? "var(--ent-accent-t)" : "transparent", color: view === "grid" ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setView("grid"); } }, h(Ico, { name: "layers", size: 15 })))),
      filtered.length === 0 ? h(EmptyState, { icon: "monitor", text: q ? "No active monitors match this search." : "No monitors yet. Create one to start tracking." })
        : (view === "grid"
            ? h("div", { className: "ent-mon-grid" }, filtered.map(card))
            : h("div", { className: "ent-card ent-list" }, filtered.map(row))),
      h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "14px", flexWrap: "wrap", marginTop: "18px", padding: "12px 16px", background: "var(--ent-surface-2)", border: "1px solid var(--ent-border-2)", borderRadius: "var(--ent-radius-s)", fontSize: "12.5px", color: "var(--ent-muted)" } },
        h("span", { style: { display: "flex", alignItems: "center", gap: "8px" } }, h(Ico, { name: "clock", size: 14 }), "Monitors update automatically. You’ll get notified when important changes happen."),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { toast("Guide to monitors is coming soon"); } }, "How monitors work")),
      modal ? h(MonitorModal, { monitor: modal === "new" ? null : modal, onSave: saveMonitor, onClose: function () { setModal(null); } }) : null,
      chart ? h(MonitorChartModal, { monitor: chart, stats: statsFor(chart), stories: stories, onClose: function () { setChart(null); }, toast: toast }) : null);
  }

  // Monitor templates for the New Monitor flow (searchable). Preview data.
  var MONITOR_TEMPLATES = [
    { name: "Climate Finance - South Asia", topics: ["Climate", "Economy"], regions: ["South Asia"], sourceTypes: ["News", "Agencies"], priority: "High", signal: "Funding & policy", desc: "Climate adaptation funding, green finance and COP commitments across South Asia.", kw: "climate finance adaptation green cop mitigation south asia" },
    { name: "AI in Development", topics: ["AI"], regions: ["Global"], sourceTypes: ["News", "Research"], priority: "Medium", signal: "Technology", desc: "How AI is reshaping public services, jobs and governance in developing economies.", kw: "ai artificial intelligence development digital automation" },
    { name: "Food Security Watch", topics: ["Food"], regions: ["Africa", "South Asia"], sourceTypes: ["Agencies", "News"], priority: "Medium", signal: "Risk", desc: "Food prices, harvests, famine risk and nutrition across food-insecure regions.", kw: "food security famine hunger crop harvest nutrition" },
    { name: "Humanitarian Access", topics: ["Humanitarian", "Conflict"], regions: ["Africa", "Middle East"], sourceTypes: ["Agencies"], priority: "High", signal: "Access", desc: "Access constraints, NGO operating conditions and aid corridor changes.", kw: "humanitarian access ngo aid corridor conflict relief" },
    { name: "Migration & Displacement", topics: ["Humanitarian"], regions: ["Global"], sourceTypes: ["Agencies", "News"], priority: "Medium", signal: "Displacement", desc: "Refugee flows, internal displacement and border-policy shifts.", kw: "migration displacement refugee border asylum idp" },
    { name: "Debt Stress Monitor", topics: ["Economy"], regions: ["Global"], sourceTypes: ["News", "Research"], priority: "High", signal: "Economic", desc: "Sovereign debt distress, IMF programmes and restructuring in emerging markets.", kw: "debt imf restructuring sovereign default distress" },
    { name: "Global Health Policy", topics: ["Health"], regions: ["Global"], sourceTypes: ["News", "Research", "Government"], priority: "Low", signal: "Health", desc: "Disease outbreaks, health financing and WHO policy changes.", kw: "health disease outbreak who vaccine policy pandemic" },
    { name: "Education Systems Watch", topics: ["Health"], regions: ["Global"], sourceTypes: ["News", "Research"], priority: "Low", signal: "Social", desc: "Access to schooling, learning outcomes and education financing.", kw: "education schools learning literacy teachers" },
    { name: "Governance & Elections", topics: ["Conflict"], regions: ["Global"], sourceTypes: ["News"], priority: "Medium", signal: "Political", desc: "Elections, democratic backsliding, corruption and institutional reform.", kw: "governance election democracy corruption reform politics" },
    { name: "Energy Transition Watch", topics: ["Climate", "Economy"], regions: ["Global"], sourceTypes: ["News", "Research"], priority: "Medium", signal: "Energy", desc: "Renewables, fossil phase-out and energy access in developing economies.", kw: "energy transition renewable solar climate power grid" },
    { name: "Disaster Risk Monitor", topics: ["Disaster", "Climate"], regions: ["Global"], sourceTypes: ["Agencies", "News"], priority: "High", signal: "Disaster", desc: "Floods, cyclones, earthquakes and early warning across exposed regions.", kw: "disaster flood cyclone earthquake climate relief risk" },
    { name: "Water Security Watch", topics: ["Food", "Climate"], regions: ["Global"], sourceTypes: ["Agencies", "Research"], priority: "Medium", signal: "Resource", desc: "Water scarcity, drought and transboundary water tensions.", kw: "water drought scarcity food climate river basin" },
    { name: "Aid Funding Signals", topics: ["Humanitarian", "Economy"], regions: ["Global"], sourceTypes: ["Agencies"], priority: "Medium", signal: "Funding", desc: "Donor pledges, humanitarian appeals and funding shortfalls.", kw: "aid funding donor appeal pledge humanitarian shortfall" },
    { name: "Donor Policy Tracker", topics: ["Economy"], regions: ["Global"], sourceTypes: ["Government", "News"], priority: "Low", signal: "Policy", desc: "Bilateral and multilateral donor strategy and ODA policy shifts.", kw: "donor policy oda aid strategy government funding" },
    { name: "Conflict Early Warning", topics: ["Conflict"], regions: ["Africa", "Middle East"], sourceTypes: ["Agencies", "News"], priority: "High", signal: "Security", desc: "Escalation indicators, ceasefire breakdowns and displacement triggers.", kw: "conflict war ceasefire escalation security early warning" },
    { name: "Agriculture & Crop Risk", topics: ["Food", "Climate"], regions: ["Africa", "South Asia"], sourceTypes: ["Agencies", "Research"], priority: "Medium", signal: "Risk", desc: "Crop conditions, fertiliser access and agricultural output risk.", kw: "agriculture crop food fertiliser harvest climate yield" },
    { name: "Infrastructure Finance", topics: ["Economy"], regions: ["Global"], sourceTypes: ["News", "Research"], priority: "Low", signal: "Investment", desc: "Roads, ports, energy and digital infrastructure investment.", kw: "infrastructure finance investment ports roads digital" },
    { name: "Refugee Response Monitor", topics: ["Humanitarian"], regions: ["Global"], sourceTypes: ["Agencies"], priority: "Medium", signal: "Displacement", desc: "Refugee camp conditions, resettlement and host-country policy.", kw: "refugee response camp resettlement migration displacement" },
    { name: "Public Finance & Debt", topics: ["Economy"], regions: ["Global"], sourceTypes: ["Research", "News"], priority: "Medium", signal: "Economic", desc: "Fiscal space, budget stress and public debt sustainability.", kw: "public finance debt budget fiscal tax sustainability" },
    { name: "Trade & Supply Chains", topics: ["Economy"], regions: ["Global"], sourceTypes: ["News"], priority: "Low", signal: "Economic", desc: "Trade flows, tariffs, ports and supply-chain disruptions.", kw: "trade supply chain tariff export import ports logistics" },
    { name: "AI and Public Health", topics: ["AI", "Health"], regions: ["Global"], sourceTypes: ["Research", "News"], priority: "Medium", signal: "Technology", desc: "AI diagnostics, health surveillance and access in low-resource systems.", kw: "ai health public diagnostics surveillance disease" },
    { name: "Digital Governance Monitor", topics: ["AI"], regions: ["Global"], sourceTypes: ["Government", "News"], priority: "Medium", signal: "Governance", desc: "Digital ID, algorithmic governance, surveillance and data policy.", kw: "digital governance ai surveillance data id algorithm" },
  ];

  function MonitorModal(props) {
    var editing = !!props.monitor;
    var m = props.monitor || {};
    var _step = useState(editing ? "config" : "pick"), step = _step[0], setStep = _step[1];
    var _tq = useState(""), tq = _tq[0], setTq = _tq[1];
    var _n = useState(m.name || ""), name = _n[0], setName = _n[1];
    var _desc = useState(m.description || ""), desc = _desc[0], setDesc = _desc[1];
    var _t = useState(m.topics || []), topics = _t[0], setTopics = _t[1];
    var _r = useState(m.regions || []), regions = _r[0], setRegions = _r[1];
    var _st = useState(m.sourceTypes || ["News"]), stypes = _st[0], setStypes = _st[1];
    var _p = useState(m.priority || "Medium"), pri = _p[0], setPri = _p[1];
    var _f = useState(m.frequency || "Daily"), freq = _f[0], setFreq = _f[1];
    function toggle(arr, setArr, v) { setArr(arr.indexOf(v) === -1 ? arr.concat([v]) : arr.filter(function (x) { return x !== v; })); }
    function chk(arr, v) { return "ent-check" + (arr.indexOf(v) !== -1 ? " is-on" : ""); }
    var valid = name.trim() && topics.length && regions.length;
    function applyTemplate(t) { setName(t.name); setDesc(t.desc || ""); setTopics(t.topics || []); setRegions(t.regions || []); setStypes(t.sourceTypes || ["News"]); setPri(t.priority || "Medium"); setStep("config"); }
    var matches = MONITOR_TEMPLATES.filter(function (t) { var qq = tq.trim().toLowerCase(); if (!qq) return true; return (t.name + " " + (t.topics || []).join(" ") + " " + (t.kw || "")).toLowerCase().indexOf(qq) !== -1; });

    if (step === "pick") {
      return h(Modal, { title: "Create a monitor", wide: true, onClose: props.onClose,
        foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"),
          h("button", { key: "x", className: "ent-btn", onClick: function () { setStep("config"); } }, "Create custom monitor")] },
        h("p", { style: { fontSize: 13, color: "var(--ent-muted)", margin: "-4px 0 12px" } }, "Search a template to start, or create a custom monitor."),
        h("div", { className: "ent-search-box", style: { marginBottom: 14 } }, h(Ico, { name: "search", size: 15 }), h("input", { placeholder: "Search monitor templates… (climate, food, AI, debt)", value: tq, onChange: function (e) { setTq(e.target.value); } })),
        matches.length === 0
          ? h(EmptyState, { icon: "monitor", text: "No templates match this search. Create a custom monitor instead." })
          : h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(230px, 1fr))", gap: 12, maxHeight: 384, overflowY: "auto", paddingRight: 2 } },
              matches.map(function (t) {
                return h("button", { key: t.name, onClick: function () { applyTemplate(t); },
                    style: { textAlign: "left", background: "var(--ent-surface)", border: "1px solid var(--ent-border)", borderRadius: 12, padding: 14, cursor: "pointer", display: "flex", flexDirection: "column", gap: 6, font: "inherit" } },
                  h("div", { style: { display: "flex", alignItems: "center", gap: 8 } },
                    h("span", { style: { width: 30, height: 30, borderRadius: 9, flex: "none", display: "grid", placeItems: "center", background: monTint({ priority: t.priority }).bg, color: monTint({ priority: t.priority }).fg, fontWeight: 800, fontSize: 11 } }, monInitials(t.name)),
                    h("span", { style: { fontSize: 13.5, fontWeight: 700, color: "var(--ent-ink)" } }, t.name)),
                  h("span", { style: { fontSize: 12, color: "var(--ent-muted)", lineHeight: 1.45 } }, t.desc),
                  h("div", { style: { display: "flex", flexWrap: "wrap", gap: 5, marginTop: 2 } },
                    (t.topics || []).slice(0, 2).map(function (tp) { return h("span", { key: tp, className: "ent-badge ent-badge--pending" }, tp); }),
                    t.signal ? h("span", { className: "ent-badge ent-badge--pending" }, t.signal) : null),
                  h("span", { style: { fontSize: 11.5, color: "var(--ent-faint)", marginTop: 2 } }, (t.regions || []).join(", ") + " · " + (t.sourceTypes || []).join(", ")));
              })));
    }

    return h(Modal, { title: editing ? "Edit monitor" : "Configure monitor", wide: true, onClose: props.onClose,
      foot: [!editing ? h("button", { key: "b", className: "ent-btn ent-btn--ghost", onClick: function () { setStep("pick"); } }, "Back") : null,
        h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"),
        h("button", { key: "s", className: "ent-btn ent-btn--primary", disabled: !valid, onClick: function () { saveM(); } }, editing ? "Save monitor" : "Create monitor")] },
      h("div", { className: "ent-field" }, h("label", null, "Monitor name"), h("input", { className: "ent-input", placeholder: "e.g. South Asia flood risk", value: name, onChange: function (e) { setName(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Description"), h("input", { className: "ent-input", placeholder: "What should Mira track for your team?", value: desc, onChange: function (e) { setDesc(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Topics"), h("div", { className: "ent-checks" }, Object.keys(TOPIC_KW).map(function (t) { return h("button", { key: t, className: chk(topics, t), onClick: function () { toggle(topics, setTopics, t); } }, t); }))),
      h("div", { className: "ent-field" }, h("label", null, "Countries / regions"), h("div", { className: "ent-checks" }, Object.keys(REGION_KW).map(function (r) { return h("button", { key: r, className: chk(regions, r), onClick: function () { toggle(regions, setRegions, r); } }, r); }))),
      h("div", { className: "ent-field" }, h("label", null, "Source types"), h("div", { className: "ent-checks" }, ["News", "Agencies", "Research", "Government", "NGO"].map(function (s) { return h("button", { key: s, className: chk(stypes, s), onClick: function () { toggle(stypes, setStypes, s); } }, s); }))),
      h("div", { style: { display: "flex", gap: "14px" } },
        h("div", { className: "ent-field", style: { flex: 1 } }, h("label", null, "Priority"), h("select", { className: "ent-select", value: pri, onChange: function (e) { setPri(e.target.value); } }, ["High", "Medium", "Low"].map(function (p) { return h("option", { key: p }, p); }))),
        h("div", { className: "ent-field", style: { flex: 1 } }, h("label", null, "Briefing frequency"), h("select", { className: "ent-select", value: freq, onChange: function (e) { setFreq(e.target.value); } }, ["Daily", "Weekly", "Real-time"].map(function (p) { return h("option", { key: p }, p); })))));
    function saveM() { props.onSave(Object.assign({}, m, { name: name.trim(), description: desc, topics: topics, regions: regions, sourceTypes: stypes, priority: pri, frequency: freq })); }
  }  // ============================================================
  //  SIGNALS
  // ============================================================
  function SignalsPage(props) {
    var ws = props.ws, stories = props.stories, sess = props.session, toast = props.toast;
    var monitors = Store.monitors(ws.id);
    var pool = stories.filter(isFresh48); if (pool.length < 6) pool = stories;
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _mf = useState("All"), mf = _mf[0], setMf = _mf[1];
    var _pf = useState("All"), pf = _pf[0], setPf = _pf[1];
    var _sort = useState("Newest"), sort = _sort[0], setSort = _sort[1];
    var _saved = useState(function () { return Store.saved(sess.email).signals; }), saved = _saved[0], setSaved = _saved[1];
    var _menu = useState(null), menu = _menu[0], setMenu = _menu[1];             // open three-dot menu id
    var _rev = useState(function () { return {}; }), reviewed = _rev[0], setReviewed = _rev[1];
    var _hid = useState(function () { return {}; }), hidden = _hid[0], setHidden = _hid[1];
    useEffect(function () { function onDoc() { setMenu(null); } document.addEventListener("click", onDoc); return function () { document.removeEventListener("click", onDoc); }; }, []);

    var signals = useMemo(function () {
      var out = [];
      monitors.forEach(function (m) {
        monitorStories(m, pool).slice(0, 6).forEach(function (a) {
          out.push({ id: (m.id + "_" + (a.url || a.title)).slice(0, 60), monitor: m.name, monitorId: m.id, title: a.title, expl: (a.summary || "").slice(0, 150), priority: priorityFromSig(sig(a)), detected: a.published || a.scraped_at, source: a.source, url: a.url });
        });
      });
      var seen = {}; out = out.filter(function (s) { if (seen[s.title]) return false; seen[s.title] = 1; return true; });
      return out;
    }, [pool.length, monitors.length]);

    var filtered = signals.filter(function (s) {
      if (hidden[s.id]) return false;
      if (mf !== "All" && s.monitor !== mf) return false;
      if (pf !== "All" && s.priority !== pf) return false;
      if (q && (s.title + " " + s.expl).toLowerCase().indexOf(q.toLowerCase()) === -1) return false;
      return true;
    });
    if (sort === "Priority") { var order = { High: 0, Medium: 1, Low: 2 }; filtered = filtered.slice().sort(function (a, b) { return order[a.priority] - order[b.priority]; }); }
    else if (sort === "Source") filtered = filtered.slice().sort(function (a, b) { return (a.source || "").localeCompare(b.source || ""); });
    else if (sort === "Monitor") filtered = filtered.slice().sort(function (a, b) { return a.monitor.localeCompare(b.monitor); });
    else filtered = filtered.slice().sort(function (a, b) { return new Date(b.detected || 0) - new Date(a.detected || 0); });

    function bookmark(id) { setSaved(Store.toggleSaved(sess.email, "signals", id).slice()); }

    var high = signals.filter(function (s) { return s.priority === "High"; }).length;
    return h("div", null,
      h(PageHead, {
        title: "Signals", sub: "Important detected changes across your monitors, ranked by priority and grounded in real reporting.",
        actions: h("button", { className: "ent-btn", onClick: function () { go("settings"); } }, h(Ico, { name: "settings", size: 15 }), "Signal settings"),
      }),
      h("div", { className: "ent-kpis", style: { marginBottom: "18px" } },
        h(KPI, { label: "Signals today", value: signals.length, icon: "signal" }),
        h(KPI, { label: "High priority", value: high, icon: "bell", delta: high > 5 ? "elevated" : "normal", trend: high > 5 ? "down" : "flat" }),
        h(KPI, { label: "New this week", value: Math.round(signals.length * 1.6), icon: "spark" }),
        h(KPI, { label: "Avg time to signal", value: "12m", icon: "clock" })),
      h("div", { className: "ent-filters" },
        h("div", { className: "ent-search-box" }, h(Ico, { name: "search", size: 15 }), h("input", { placeholder: "Search signals…", value: q, onChange: function (e) { setQ(e.target.value); } })),
        h("select", { className: "ent-select", value: mf, onChange: function (e) { setMf(e.target.value); } }, ["All"].concat(monitors.map(function (m) { return m.name; })).map(function (m) { return h("option", { key: m }, m); })),
        h("select", { className: "ent-select", value: pf, onChange: function (e) { setPf(e.target.value); } }, ["All", "High", "Medium", "Low"].map(function (p) { return h("option", { key: p }, p); })),
        h("select", { className: "ent-select", value: sort, onChange: function (e) { setSort(e.target.value); } }, ["Newest", "Priority", "Source", "Monitor"].map(function (p) { return h("option", { key: p }, p); }))),
      monitors.length === 0
        ? h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
            h(EmptyState, { icon: "signal", text: "No signals yet. Signals appear after Mira scans your monitors and sources." }),
            h("div", { style: { display: "flex", gap: "8px", justifyContent: "center", flexWrap: "wrap" } },
              h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { go("monitors"); } }, "Create monitor"),
              h("button", { className: "ent-btn ent-btn--sm", onClick: function () { go("sources"); } }, "Add sources")))
        : filtered.length === 0 ? h(EmptyState, { icon: "signal", text: "No signals match your filters." })
        : h("div", null,
            h("div", { className: "ent-card" }, h("div", { className: "ent-list" }, filtered.map(function (s) {
              var pc = s.priority === "High" ? { bg: "#FCE7EC", fg: "#C0506A" } : s.priority === "Medium" ? { bg: "#FBEFD8", fg: "#B5771E" } : { bg: "#E6F2E6", fg: "#4B8B54" };
              return h("div", { key: s.id, className: "ent-item", style: reviewed[s.id] ? { opacity: 0.6 } : null },
                h("span", { "aria-hidden": "true", style: { width: 34, height: 34, borderRadius: 10, flex: "none", display: "grid", placeItems: "center", background: pc.bg, color: pc.fg } }, h(Ico, { name: "signal", size: 16 })),
                h("div", { className: "ent-item-body" },
                  h("div", { className: "ent-item-title" }, s.url ? h("a", { href: s.url, target: "_blank", rel: "noopener" }, s.title) : s.title),
                  h("div", { className: "ent-item-expl" }, s.expl),
                  h("div", { className: "ent-item-meta" },
                    h("span", null, h(Ico, { name: "monitor", size: 12 }), " " + s.monitor),
                    h("span", null, h(Ico, { name: "clock", size: 12 }), " " + timeAgo(s.detected)),
                    s.source ? h("span", null, s.source) : null,
                    reviewed[s.id] ? h("span", { style: { color: "#4B8B54", fontWeight: 600 } }, "Reviewed") : null)),
                h("div", { className: "ent-item-side" },
                  h(Badge, { kind: s.priority.toLowerCase() }, s.priority),
                  h("button", { className: "ent-bookmark" + (saved.indexOf(s.id) !== -1 ? " is-on" : ""), title: "Save", onClick: function () { bookmark(s.id); } }, h(Ico, { name: "bookmark", size: 16 })),
                  h("div", { style: { position: "relative" }, onClick: function (e) { e.stopPropagation(); } },
                    h("button", { className: "ent-bookmark", title: "More actions", "aria-haspopup": "true", onClick: function () { setMenu(menu === s.id ? null : s.id); } }, h(Ico, { name: "dots", size: 16 })),
                    menu === s.id ? h("div", { className: "ent-tb-menu-pop", style: { top: "34px", right: 0, minWidth: "186px" } },
                      h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); toast("Signal detail view is coming soon"); } }, h(Ico, { name: "external", size: 15 }), "View details"),
                      h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); toast("Add to report is coming soon"); } }, h(Ico, { name: "report", size: 15 }), "Add to report"),
                      h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); var n = {}; for (var k in reviewed) n[k] = reviewed[k]; n[s.id] = true; setReviewed(n); } }, h(Ico, { name: "check", size: 15 }), "Mark as reviewed"),
                      h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); var n = {}; for (var k in hidden) n[k] = hidden[k]; n[s.id] = true; setHidden(n); } }, h(Ico, { name: "eye", size: 15 }), "Hide signal")
                    ) : null)));
            }))),
            h("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 14, padding: "0 4px", fontSize: 12.5, color: "var(--ent-muted)" } },
              h("span", null, "Signals are generated automatically and may change as new information emerges."),
              h("button", { style: { marginLeft: "auto", border: "none", background: "none", font: "inherit", fontSize: 12.5, fontWeight: 600, color: "var(--ent-accent)", cursor: "pointer" }, onClick: function () { toast("Guide coming soon"); } }, "Learn how signals work"))));
  }

  // ============================================================
  //  BRIEFINGS
  // ============================================================
  function BriefingsPage(props) {
    var ws = props.ws, stories = props.stories, toast = props.toast, sess = props.session;
    var email = (sess && sess.email) || "";
    var monitors = Store.monitors(ws.id);

    var _tab = useState("today"), tab = _tab[0], setTab = _tab[1];
    var _topic = useState("All Topics"), topicF = _topic[0], setTopicF = _topic[1];
    var _limit = useState(4), limit = _limit[0], setLimit = _limit[1];
    var _why = useState(null), whyStory = _why[0], setWhyStory = _why[1];
    var _cfg = useState(false), cfgOpen = _cfg[0], setCfgOpen = _cfg[1];
    var _share = useState(false), shareOpen = _share[0], setShareOpen = _share[1];
    var _menu = useState(false), menuOpen = _menu[0], setMenuOpen = _menu[1];
    var _expand = useState(null), expandDay = _expand[0], setExpandDay = _expand[1];
    var _stick = useState(0), savedTick = _stick[0], setSavedTick = _stick[1];
    // briefing settings (persisted to workspace settings — real)
    var _bt = useState(Store.settings(ws.id).briefTime || "08:00"), briefTime = _bt[0], setBriefTime = _bt[1];
    var _fr = useState(Store.settings(ws.id).briefFreq || "Daily"), briefFreq = _fr[0], setBriefFreq = _fr[1];
    var _em = useState(Store.settings(ws.id).emailDelivery !== false), emailOn = _em[0], setEmailOn = _em[1];

    // close the daily-card overflow menu on any outside click
    useEffect(function () {
      if (!menuOpen) return;
      function close() { setMenuOpen(false); }
      window.addEventListener("click", close);
      return function () { window.removeEventListener("click", close); };
    }, [menuOpen]);

    var pool = stories.filter(isFresh48); if (pool.length < 6) pool = stories;

    function srcName(a) { return a.sourceName || a.source || a.sourceDomain || "Source"; }
    // cluster-aware source count — distinct outlets covering the same story
    function clusterSources(a) {
      if (!a.clusterId) return 1;
      var s = {}; stories.forEach(function (x) { if (x.clusterId === a.clusterId) s[srcName(x)] = 1; });
      var n = Object.keys(s).length; return n < 1 ? 1 : n;
    }
    function clusterList(a) {
      if (!a.clusterId) return [a];
      var list = stories.filter(function (x) { return x.clusterId === a.clusterId; });
      return list.length ? list.slice(0, 6) : [a];
    }
    // classify a story into a monitored/known topic (real keyword match)
    function classifyTopic(a) {
      var txt = ((a.display_title || a.title || "") + " " + (a.summary || "")).toLowerCase();
      var hit = null;
      Object.keys(TOPIC_KW).some(function (t) { if (TOPIC_KW[t].some(function (w) { return txt.indexOf(w) !== -1; })) { hit = t; return true; } return false; });
      return hit || a.country || a.region || "Global";
    }
    function headline(a) { return a.display_title || a.title || "Untitled"; }
    function summ(a) { return a.summary || a.deeper_summary || ""; }

    // top stories, monitor-weighted (real)
    var scoped = useMemo(function () {
      return pool.map(function (a) {
        var s = sig(a) * 2;
        monitors.forEach(function (m) { if (monitorStories(m, [a]).length) s += 3; });
        return { a: a, s: s };
      }).sort(function (x, y) { return y.s - x.s || new Date(y.a.published || 0) - new Date(x.a.published || 0); })
        .slice(0, 24).map(function (x) { return x.a; });
    }, [pool.length, monitors.length]);

    var savedIds = Store.saved(email).briefs || [];
    function isSaved(a) { return savedIds.indexOf(a.id) !== -1; }
    function toggleSave(a) { var was = isSaved(a); Store.toggleSaved(email, "briefs", a.id); setSavedTick(savedTick + 1); toast(was ? "Removed from saved" : "Saved to your briefings"); }

    var srcCount = (function () { var s = {}; scoped.forEach(function (a) { s[srcName(a)] = 1; }); return Object.keys(s).length; })();
    var topicOptions = ["All Topics"].concat((function () { var s = {}; scoped.forEach(function (a) { s[classifyTopic(a)] = 1; }); return Object.keys(s); })());
    var topicMatched = topicF === "All Topics" ? scoped : scoped.filter(function (a) { return classifyTopic(a) === topicF; });
    var shownStories = topicMatched.slice(0, limit);

    // real day-over-day deltas from publish timestamps
    var dayStats = useMemo(function () {
      var now = Date.now(), d1 = 0, d2 = 0, hi1 = 0;
      stories.forEach(function (a) {
        var age = now - new Date(a.published || a.scraped_at || 0).getTime();
        if (age < 86400000) { d1++; if (sig(a) >= 3) hi1++; }
        else if (age < 172800000) { d2++; }
      });
      return { today: d1, yest: d2, hiToday: hi1 };
    }, [stories.length]);
    var scanPct = dayStats.yest ? Math.round((dayStats.today - dayStats.yest) / dayStats.yest * 100) : null;
    var regionCount = (function () { var s = {}; pool.forEach(function (a) { if (a.country) s[a.country] = 1; }); return Object.keys(s).length; })();
    var signalCount = (function () { var n = 0; monitors.forEach(function (m) { n += monitorStories(m, pool).length; }); return n; })();

    function exportText() {
      try {
        var blob = new Blob([teamUpdate(scoped)], { type: "text/plain" });
        var url = URL.createObjectURL(blob);
        var a = document.createElement("a");
        a.href = url; a.download = "mira-briefing-" + new Date().toISOString().slice(0, 10) + ".txt";
        document.body.appendChild(a); a.click(); document.body.removeChild(a);
        setTimeout(function () { URL.revokeObjectURL(url); }, 1000);
        toast("Briefing exported");
      } catch (e) { toast("Export isn’t available in this browser"); }
    }
    function saveCfg() { Store.setSettings(ws.id, { briefTime: briefTime, briefFreq: briefFreq, emailDelivery: emailOn }); setCfgOpen(false); toast("Briefing settings saved"); }

    // ── shared story row (Today / Saved / Past-expanded) ──
    function StoryRow(a, i, showRank) {
      var nSrc = clusterSources(a);
      return h("div", { key: a.id || i, className: "ent-item" },
        showRank ? h("div", { style: { fontFamily: "var(--ent-serif)", fontSize: "17px", fontWeight: 600, color: "var(--ent-faint)", width: "20px", flex: "none", textAlign: "center", paddingTop: "2px" } }, i + 1) : null,
        h("div", { style: { width: "58px", height: "58px", borderRadius: "10px", flex: "none", overflow: "hidden", background: a.dominantColor || a.accentColor || "var(--ent-tint)", display: "grid", placeItems: "center", color: "#fff" } },
          a.image_url ? h("img", { src: a.image_url, alt: "", loading: "lazy", style: { width: "100%", height: "100%", objectFit: "cover" }, onError: function (e) { e.target.style.display = "none"; } }) : h(Ico, { name: "brief", size: 20 })),
        h("div", { className: "ent-item-body" },
          h("span", { className: "ent-pill ent-pill--accent", style: { marginBottom: "6px" } }, classifyTopic(a)),
          h("div", { className: "ent-item-title" }, a.url ? h("a", { href: a.url, target: "_blank", rel: "noopener" }, headline(a)) : headline(a)),
          summ(a) ? h("div", { className: "ent-item-expl" }, summ(a).slice(0, 180)) : null,
          h("div", { className: "ent-item-meta" },
            h("span", null, timeAgo(a.published || a.scraped_at)),
            h("span", null, nSrc + (nSrc === 1 ? " source" : " sources")),
            h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { padding: "2px 6px" }, onClick: function () { setWhyStory(a); } }, "Why it matters", h(Ico, { name: "arrow", size: 12 })))),
        h("div", { className: "ent-item-side" },
          h(Badge, { kind: priorityFromSig(sig(a)).toLowerCase() }, impactLabel(sig(a))),
          h("button", { className: "ent-bookmark" + (isSaved(a) ? " is-on" : ""), "aria-label": isSaved(a) ? "Remove bookmark" : "Save story", "aria-pressed": isSaved(a), onClick: function () { toggleSave(a); } }, h(Ico, { name: "bookmark", size: 17 }))));
    }

    // ── TODAY ──
    var trackTopics = (function () { var s = {}; monitors.forEach(function (m) { (m.topics || []).forEach(function (t) { s[t] = 1; }); }); return Object.keys(s).length; })();
    var fullDate = (function () { try { return new Date().toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long", year: "numeric" }); } catch (e) { return fmtDate(Date.now()); } })();

    var dailyCard = h("div", { className: "ent-card" },
      h("div", { className: "ent-card-hd" },
        h("div", null,
          h("h3", null, "Daily Briefing"),
          h("div", { className: "ent-card-hd-sub" }, fullDate + " · Tracking " + trackTopics + " topics · " + regionCount + " regions")),
        h("div", { className: "ent-card-hd-actions" },
          h("button", { className: "ent-btn ent-btn--sm", onClick: function () { setShareOpen(true); } }, h(Ico, { name: "share", size: 14 }), "Share briefing"),
          h("div", { style: { position: "relative" } },
            h("button", { className: "ent-menu-btn", "aria-label": "More actions", onClick: function (e) { e.stopPropagation(); setMenuOpen(!menuOpen); } }, h(Ico, { name: "dots", size: 18 })),
            menuOpen ? h("div", { className: "ent-tb-menu-pop", style: { top: "34px" }, onClick: function (e) { e.stopPropagation(); } },
              h("button", { className: "ent-tb-menu-item", onClick: function () { setMenuOpen(false); copyText(teamUpdate(scoped)); toast("Briefing copied as text"); } }, h(Ico, { name: "copy", size: 15 }), "Copy as text"),
              h("button", { className: "ent-tb-menu-item", onClick: function () { setMenuOpen(false); exportText(); } }, h(Ico, { name: "download", size: 15 }), "Download .txt"),
              h("button", { className: "ent-tb-menu-item", onClick: function () { setMenuOpen(false); setCfgOpen(true); } }, h(Ico, { name: "settings", size: 15 }), "Briefing settings")) : null))),
      h("div", { className: "ent-card-pad" },
        h("p", { style: { fontSize: "14px", color: "var(--ent-body)", lineHeight: 1.6, margin: "0 0 8px" } }, "Here’s what changed today in global development and why it matters to your team."),
        scoped[0] ? h("p", { style: { fontSize: "13px", color: "var(--ent-muted)", lineHeight: 1.6, margin: 0 } }, h("strong", { style: { color: "var(--ent-ink)" } }, "Today’s lead: "), summ(scoped[0]) || headline(scoped[0])) : h("p", { style: { fontSize: "13px", color: "var(--ent-muted)", margin: 0 } }, "No fresh stories in the current window.")));

    var topCard = h("div", { className: "ent-card" },
      h("div", { className: "ent-card-hd" },
        h("div", null, h("h3", null, "Top Stories"), h("div", { className: "ent-card-hd-sub" }, "The most important changes from the last 24 hours.")),
        h("div", { className: "ent-card-hd-actions" },
          h("select", { className: "ent-select", value: topicF, onChange: function (e) { setTopicF(e.target.value); setLimit(4); }, "aria-label": "Filter by topic" },
            topicOptions.map(function (t) { return h("option", { key: t, value: t }, t); })))),
      shownStories.length ? h("div", { className: "ent-list" }, shownStories.map(function (a, i) { return StoryRow(a, i, true); }))
        : h(EmptyState, { icon: "brief", text: "No stories match this topic." }),
      topicMatched.length > shownStories.length ? h("div", { style: { padding: "14px 20px", borderTop: "1px solid var(--ent-border-2)" } },
        h("button", { className: "ent-btn ent-btn--sm", onClick: function () { setLimit(limit + 4); } }, "Load more stories")) : null);

    var todayView = h("div", { className: "ent-col" }, dailyCard, topCard);

    // ── PAST (real stories grouped by day) ──
    var pastDays = useMemo(function () {
      var byDay = {}, todayKey = new Date().toISOString().slice(0, 10);
      stories.forEach(function (a) {
        var ts = a.published || a.scraped_at; if (!ts) return;
        var dt = new Date(ts); if (isNaN(dt.getTime())) return;
        var k = dt.toISOString().slice(0, 10); if (k === todayKey) return;
        (byDay[k] = byDay[k] || []).push(a);
      });
      return Object.keys(byDay).filter(function (k) { return byDay[k].length >= 2; }).sort().reverse().slice(0, 6).map(function (k) {
        var list = byDay[k].slice().sort(function (a, b) { return sig(b) - sig(a) || new Date(b.published || 0) - new Date(a.published || 0); });
        var srcs = {}; list.forEach(function (a) { srcs[srcName(a)] = 1; });
        var label; try { label = new Date(k + "T12:00:00").toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" }); } catch (e) { label = k; }
        return { key: k, label: label, count: list.length, sources: Object.keys(srcs).length, stories: list.slice(0, 5) };
      });
    }, [stories.length]);

    var pastView = pastDays.length ? h("div", { className: "ent-col" }, pastDays.map(function (d) {
      var open = expandDay === d.key;
      return h("div", { key: d.key, className: "ent-card" },
        h("div", { className: "ent-card-hd" },
          h("div", null, h("h3", null, d.label), h("div", { className: "ent-card-hd-sub" }, d.count + " stories · " + d.sources + " sources")),
          h("div", { className: "ent-card-hd-actions" },
            h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { copyText(teamUpdate(d.stories)); toast("Briefing copied as text"); } }, h(Ico, { name: "copy", size: 14 }), "Copy"),
            h("button", { className: "ent-btn ent-btn--sm", onClick: function () { setExpandDay(open ? null : d.key); } }, open ? "Hide" : "View briefing"))),
        open ? h("div", { className: "ent-list" }, d.stories.map(function (a, i) { return StoryRow(a, i, true); })) : null);
    })) : h(EmptyState, { icon: "brief", text: "Past briefings appear here as stories accumulate day over day." });

    // ── SAVED ──
    var savedStories = stories.filter(function (a) { return savedIds.indexOf(a.id) !== -1; });
    var savedView = savedStories.length ? h("div", { className: "ent-card" },
      h("div", { className: "ent-card-hd" }, h("h3", null, "Saved Briefings"), h("div", { className: "ent-card-hd-sub" }, savedStories.length + " saved")),
      h("div", { className: "ent-list" }, savedStories.map(function (a, i) { return StoryRow(a, i, false); })))
      : h(EmptyState, { icon: "bookmark", text: "Bookmark stories from Today’s Briefing to save them here." });

    var main = h("div", { key: "main", className: "ent-col" },
      h(PageHead, {
        title: "Briefings",
        sub: "Your daily development intelligence briefing, powered by Mira.",
        actions: h("button", { className: "ent-btn", onClick: function () { setCfgOpen(true); } }, h(Ico, { name: "settings", size: 15 }), "Briefing settings"),
      }),
      h("div", { className: "ent-tabs" },
        [["today", "Today’s Briefing"], ["past", "Past Briefings"], ["saved", "Saved Briefings"]].map(function (t) {
          return h("button", { key: t[0], className: "ent-tab" + (tab === t[0] ? " is-active" : ""), onClick: function () { setTab(t[0]); } }, t[1]);
        })),
      tab === "today" ? todayView : tab === "past" ? pastView : savedView);

    var rail = h("div", { key: "rail", className: "ent-rail" },
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Briefing Summary"),
        h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "Stories scanned"),
          h("span", { className: "v" }, (dayStats.today || pool.length),
            scanPct !== null ? h("span", { className: "ent-kpi-delta " + (scanPct >= 0 ? "up" : "down"), style: { marginLeft: "6px", fontWeight: 600 } }, (scanPct >= 0 ? "↑ " : "↓ ") + Math.abs(scanPct) + "%") : null)),
        h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "High impact stories"), h("span", { className: "v" }, scoped.filter(function (a) { return sig(a) >= 3; }).length)),
        h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "Regions updated"), h("span", { className: "v" }, regionCount)),
        h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "Signals detected"), h("span", { className: "v" }, signalCount))),
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title", style: { display: "flex", alignItems: "center", justifyContent: "space-between" } }, "Your Focus Areas",
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { go("monitors"); } }, "Edit")),
        monitors.slice(0, 5).map(function (m, i) {
          var updates = monitorStories(m, pool).length;
          return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, m.name), h("span", { className: "v" }, updates + (updates === 1 ? " update" : " updates")));
        }),
        monitors.length > 5 ? h("div", { className: "ent-rail-row" }, h("span", { className: "l", style: { color: "var(--ent-accent-d)" } }, "+" + (monitors.length - 5) + " more topics")) : null,
        monitors.length === 0 ? h("div", { style: { fontSize: "12.5px", color: "var(--ent-muted)", paddingTop: "4px" } }, "No monitors yet — add one to shape your briefing.") : null),
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Delivered to your team"),
        h("div", { style: { fontSize: "13px", color: "var(--ent-body)" } }, "Daily briefing sent to " + (ws.members || []).length + " members"),
        h("div", { style: { fontSize: "12px", color: "var(--ent-muted)", marginTop: "2px" } }, "Today, " + (Store.settings(ws.id).briefTime || "08:00")),
        h("button", { className: "ent-btn ent-btn--sm", style: { marginTop: "10px" }, onClick: function () { toast("Automatic resend is coming soon — briefings send daily at " + (Store.settings(ws.id).briefTime || "08:00")); } }, h(Ico, { name: "share", size: 14 }), "Resend")));

    // ── modals (fixed-position; out of grid flow) ──
    var whyNode = whyStory ? h(Modal, { key: "why", title: "Why it matters", onClose: function () { setWhyStory(null); } },
      h("span", { className: "ent-pill ent-pill--accent" }, classifyTopic(whyStory)),
      h("h3", { style: { fontFamily: "var(--ent-serif)", fontSize: "18px", margin: "10px 0 14px", lineHeight: 1.25 } }, headline(whyStory)),
      h("div", { className: "ent-field" }, h("label", null, "Why this matters"), h("p", { style: { margin: 0, fontSize: "13.5px", color: "var(--ent-body)", lineHeight: 1.6 } }, whyStory.deeper_summary || summ(whyStory) || "Mira flagged this as a notable change across your monitored topics.")),
      h("div", { className: "ent-field" }, h("label", null, "Who is affected"), h("p", { style: { margin: 0, fontSize: "13.5px", color: "var(--ent-body)" } }, (whyStory.country || whyStory.region || "Multiple regions") + " and connected communities.")),
      h("div", { className: "ent-field" }, h("label", null, "What to watch next"), h("p", { style: { margin: 0, fontSize: "13.5px", color: "var(--ent-body)" } }, "Follow-on reporting and monitor updates as the story develops.")),
      h("div", { className: "ent-field", style: { marginBottom: 0 } }, h("label", null, "Sources (" + clusterSources(whyStory) + ")"),
        h("div", { className: "ent-ask-sources" }, clusterList(whyStory).map(function (x, i) {
          return h("a", { key: i, className: "ent-ask-src", href: x.url || undefined, target: x.url ? "_blank" : undefined, rel: "noopener" }, h(Ico, { name: "external", size: 12 }), srcName(x));
        })))) : null;

    var focusTopics = (function () { var s = {}; monitors.forEach(function (m) { (m.topics || []).forEach(function (t) { s[t] = 1; }); }); return Object.keys(s); })();
    var focusRegions = (function () { var s = {}; monitors.forEach(function (m) { (m.regions || []).forEach(function (r) { s[r] = 1; }); }); return Object.keys(s); })();
    var cfgNode = cfgOpen ? h(Modal, { key: "cfg", title: "Briefing settings", wide: true, onClose: function () { setCfgOpen(false); },
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: function () { setCfgOpen(false); } }, "Cancel"), h("button", { key: "s", className: "ent-btn ent-btn--primary", onClick: saveCfg }, "Save settings")] },
      h("div", { style: { display: "flex", gap: "14px", flexWrap: "wrap" } },
        h("div", { className: "ent-field", style: { flex: 1, minWidth: "160px" } }, h("label", null, "Delivery time"), h("input", { className: "ent-input", type: "time", value: briefTime, onChange: function (e) { setBriefTime(e.target.value); } })),
        h("div", { className: "ent-field", style: { flex: 1, minWidth: "160px" } }, h("label", null, "Frequency"), h("select", { className: "ent-select", value: briefFreq, onChange: function (e) { setBriefFreq(e.target.value); } }, ["Daily", "Weekly", "Real-time"].map(function (p) { return h("option", { key: p }, p); })))),
      h("div", { className: "ent-field" }, h("label", null, "Topics (" + focusTopics.length + ")"), h("div", { className: "ent-checks" }, focusTopics.length ? focusTopics.map(function (t) { return h("span", { key: t, className: "ent-check is-on" }, t); }) : h("span", { style: { fontSize: "12.5px", color: "var(--ent-muted)" } }, "Set topics via your monitors."))),
      h("div", { className: "ent-field" }, h("label", null, "Regions (" + focusRegions.length + ")"), h("div", { className: "ent-checks" }, focusRegions.length ? focusRegions.map(function (r) { return h("span", { key: r, className: "ent-check is-on" }, r); }) : h("span", { style: { fontSize: "12.5px", color: "var(--ent-muted)" } }, "Set regions via your monitors."))),
      h("div", { className: "ent-field" }, h("label", null, "Recipients (" + (ws.members || []).length + ")"),
        h("div", { style: { fontSize: "13px", color: "var(--ent-body)" } }, (ws.members || []).map(function (m) { return m.name || m.email; }).join(", ") || "No members yet"),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: "8px" }, onClick: function () { setCfgOpen(false); go("team"); } }, "Manage recipients")),
      h("label", { style: { display: "flex", alignItems: "center", gap: "10px" } }, h("input", { type: "checkbox", checked: emailOn, onChange: function (e) { setEmailOn(e.target.checked); } }), h("span", { style: { fontSize: "13px" } }, "Email delivery to recipients"))) : null;

    var shareNode = shareOpen ? h(Modal, { key: "share", title: "Share briefing", onClose: function () { setShareOpen(false); } },
      h("div", { className: "ent-action-list" },
        h("button", { className: "ent-action-btn", onClick: function () { copyText(window.location.href); toast("Briefing link copied"); } }, h(Ico, { name: "copy", size: 16 }), "Copy briefing link"),
        h("button", { className: "ent-action-btn", onClick: function () { exportText(); setShareOpen(false); } }, h(Ico, { name: "download", size: 16 }), "Export as text"),
        h("button", { className: "ent-action-btn", disabled: true }, h(Ico, { name: "share", size: 16 }), "Email to team", h("span", { className: "ent-soon", style: { marginLeft: "auto" } }, "Soon"))),
      h("p", { style: { fontSize: "12px", color: "var(--ent-muted)", marginTop: "12px" } }, "Copy the link or export as text now. Automated email-to-team is coming soon.")) : null;

    if (monitors.length === 0) {
      var faMain = h("div", { className: "ent-col" },
        h(PageHead, { title: "Briefings", sub: "Briefings turn your monitors and signals into daily team intelligence summaries." }),
        h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
          h(EmptyState, { icon: "brief", text: "No briefing generated yet. Your first briefing will appear after you create monitors and choose briefing settings." }),
          h("div", { style: { display: "flex", gap: "8px", justifyContent: "center", flexWrap: "wrap" } },
            h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { go("monitors"); } }, "Create monitor"),
            h("button", { className: "ent-btn ent-btn--sm", onClick: function () { go("settings"); } }, "Set briefing preferences"))));
      return [faMain, rail, cfgNode];
    }
    return [main, rail, whyNode, cfgNode, shareNode];
  }
  function impactLabel(s) { return s >= 3 ? "High impact" : s === 2 ? "Notable" : "Context"; }

  // ============================================================
  //  SOURCES
  // ============================================================
  // ============================================================
  //  SOURCES  (demo source directory — labelled demo, kept separate from
  //  public Globly story data; never written into public pages)
  //  TODO: Protect Enterprise sources with workspace access before launch.
  // ============================================================
  // ============================================================
  //  SOURCES
  //  Enterprise preview source data. Replace with the workspace source
  //  database before launch. EVERY number on the Sources page is computed
  //  from this list — nothing is hardcoded.
  //  TODO: Protect Enterprise sources with workspace access before launch.
  //  TODO: persist Enterprise sources to workspace database before launch.
  // ============================================================
  var SRC_STATUSES = ["Active", "Warning", "Inactive", "Blocked"];
  var SRC_PERPAGE = 10;
  function demoSourceSeed() {
    var now = Date.now(), MIN = 60000, DAY = 86400000;
    // [name, domain, category, type, region, reliability(0-100), status, updatedMinAgo, createdDaysAgo]
    var raw = [
      ["United Nations", "un.org", "International Organizations", "Website", "Global", 98, "Active", 10, 320],
      ["World Bank", "worldbank.org", "Financial Institutions", "Website", "Global", 95, "Active", 15, 300],
      ["Reuters", "reuters.com", "News Media", "Wire", "Global", 92, "Active", 8, 380],
      ["Al Jazeera", "aljazeera.com", "News Media", "News", "Middle East, Africa", 90, "Active", 6, 360],
      ["Brookings Institution", "brookings.edu", "Think Tanks", "Website", "Global", 88, "Active", 60, 250],
      ["ReliefWeb", "reliefweb.int", "Data Portals", "Database", "Global", 85, "Active", 22, 340],
      ["FAO", "fao.org", "UN Agencies", "Website", "Global", 93, "Active", 12, 330],
      ["OECD", "oecd.org", "International Organizations", "Website", "Global", 87, "Active", 45, 310],
      ["WHO", "who.int", "UN Agencies", "Website", "Global", 96, "Active", 5, 350],
      ["UNHCR", "unhcr.org", "UN Agencies", "Website", "Global", 94, "Active", 9, 345],
      ["UNICEF", "unicef.org", "UN Agencies", "Website", "Global", 93, "Active", 14, 344],
      ["WFP", "wfp.org", "UN Agencies", "Website", "Global", 92, "Active", 18, 342],
      ["IMF", "imf.org", "Financial Institutions", "Website", "Global", 94, "Active", 30, 305],
      ["African Development Bank", "afdb.org", "Financial Institutions", "Website", "Africa", 88, "Active", 120, 2],
      ["Asian Development Bank", "adb.org", "Financial Institutions", "Website", "Asia", 87, "Active", 90, 40],
      ["International Crisis Group", "crisisgroup.org", "Think Tanks", "Website", "Global", 86, "Active", 200, 210],
      ["Human Rights Watch", "hrw.org", "NGO / Non-profit", "Website", "Global", 89, "Active", 35, 260],
      ["Amnesty International", "amnesty.org", "NGO / Non-profit", "Website", "Global", 88, "Active", 50, 265],
      ["OCHA", "unocha.org", "UN Agencies", "Website", "Global", 93, "Active", 16, 335],
      ["IOM", "iom.int", "UN Agencies", "Website", "Global", 90, "Active", 25, 320],
      ["ILO", "ilo.org", "UN Agencies", "Website", "Global", 89, "Active", 70, 318],
      ["UNDP", "undp.org", "UN Agencies", "Website", "Global", 91, "Active", 20, 322],
      ["UNESCO", "unesco.org", "UN Agencies", "Website", "Global", 88, "Active", 80, 316],
      ["Climate Home News", "climatechangenews.com", "News Media", "News", "Global", 82, "Active", 40, 3],
      ["The Lancet Global Health", "thelancet.com", "Academic / Research", "Journal", "Global", 90, "Active", 300, 5],
      ["Devex", "devex.com", "News Media", "News", "Global", 84, "Active", 55, 120],
      ["Center for Global Development", "cgdev.org", "Think Tanks", "Website", "Global", 85, "Active", 110, 150],
      ["ODI Global", "odi.org", "Think Tanks", "Website", "Global", 84, "Active", 130, 160],
      ["Chatham House", "chathamhouse.org", "Think Tanks", "Website", "Global", 85, "Active", 140, 170],
      ["World Resources Institute", "wri.org", "NGO / Non-profit", "Website", "Global", 86, "Active", 65, 180],
      ["Our World in Data", "ourworldindata.org", "Data Portals", "Database", "Global", 91, "Active", 75, 190],
      ["World Bank DataBank", "databank.worldbank.org", "Data Portals", "Database", "Global", 90, "Active", 85, 200],
      ["FEWS NET", "fews.net", "Data Portals", "Database", "Africa", 83, "Active", 95, 205],
      ["ACLED", "acleddata.com", "Data Portals", "Database", "Global", 88, "Active", 33, 145],
      ["The Guardian", "theguardian.com", "News Media", "News", "Global", 85, "Active", 11, 400],
      ["BBC News", "bbc.com", "News Media", "News", "Global", 89, "Active", 7, 410],
      ["Associated Press", "apnews.com", "News Media", "Wire", "Global", 91, "Active", 13, 405],
      ["Agence France-Presse", "afp.com", "News Media", "Wire", "Global", 90, "Active", 17, 402],
      ["Bloomberg", "bloomberg.com", "News Media", "News", "Global", 86, "Active", 21, 300],
      ["Financial Times", "ft.com", "News Media", "News", "Global", 87, "Active", 19, 305],
      ["European Commission", "ec.europa.eu", "Government", "Website", "Europe", 88, "Active", 120, 280],
      ["USAID", "usaid.gov", "Donor Agencies", "Website", "Global", 84, "Warning", 4320, 240],
      ["UK FCDO", "gov.uk", "Donor Agencies", "Website", "Global", 83, "Active", 240, 235],
      ["GIZ", "giz.de", "Donor Agencies", "Website", "Europe", 82, "Active", 300, 220],
      ["Sida", "sida.se", "Donor Agencies", "Website", "Europe", 80, "Warning", 4320, 210],
      ["Gates Foundation", "gatesfoundation.org", "Donor Agencies", "Website", "Global", 85, "Active", 160, 200],
      ["IFRC", "ifrc.org", "NGO / Non-profit", "Website", "Global", 87, "Active", 28, 260],
      ["Medecins Sans Frontieres", "msf.org", "NGO / Non-profit", "Website", "Global", 88, "Active", 24, 262],
      ["Oxfam", "oxfam.org", "NGO / Non-profit", "Website", "Global", 84, "Active", 130, 255],
      ["Save the Children", "savethechildren.net", "NGO / Non-profit", "Website", "Global", 84, "Active", 140, 250],
      ["IPCC", "ipcc.ch", "Academic / Research", "Website", "Global", 92, "Active", 600, 230],
      ["Nature", "nature.com", "Academic / Research", "Journal", "Global", 90, "Active", 500, 240],
      ["Science", "science.org", "Academic / Research", "Journal", "Global", 89, "Active", 520, 238],
      ["SIPRI", "sipri.org", "Think Tanks", "Website", "Europe", 85, "Active", 700, 225],
      ["Transparency International", "transparency.org", "NGO / Non-profit", "Website", "Global", 83, "Warning", 3000, 215],
      ["PR Newswire", "prnewswire.com", "News Media", "Wire", "Global", 68, "Inactive", 26000, 300],
      ["Regional Aggregator Feed", "aggregator.example", "Other", "Aggregator", "Global", 34, "Blocked", 40000, 90],
      ["Archived Gov Portal", "archive.example", "Government", "Website", "Global", 55, "Inactive", 60000, 500],
    ];
    return raw.map(function (r, i) {
      return {
        id: "src-" + (i + 1), name: r[0], domain: r[1], category: r[2], type: r[3], region: r[4],
        reliability: r[5], status: r[6], updatedAt: now - r[7] * MIN, createdAt: now - r[8] * DAY,
      };
    }).filter(function (s) {
      // validate: non-blank name/domain/category, reliability 0-100, valid status
      return s.name && s.domain && s.category && s.reliability >= 0 && s.reliability <= 100 && SRC_STATUSES.indexOf(s.status) !== -1;
    });
  }
  function srcInitials(n) { return (n || "?").split(/\s+/).map(function (w) { return w[0]; }).slice(0, 2).join("").toUpperCase(); }
  function srcRelColor(r) { return r >= 90 ? "#4F8A54" : r >= 75 ? "#B5701E" : "#C4442E"; }
  function srcUpdatedLabel(ts) {
    var m = Math.round((Date.now() - ts) / 60000);
    if (m < 1) return "just now";
    if (m < 60) return m + " min ago";
    var hr = Math.round(m / 60); if (hr < 24) return hr + " hr" + (hr > 1 ? "s" : "") + " ago";
    var d = Math.round(hr / 24); return d + " day" + (d > 1 ? "s" : "") + " ago";
  }

  function SourcesPage(props) {
    var toast = props.toast, ws = props.ws;
    var _src = useState(function () { return Store.sources(ws.id); }), sources = _src[0], setSources = _src[1];
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _cat = useState("All Categories"), cat = _cat[0], setCat = _cat[1];
    var _typ = useState("All Types"), typ = _typ[0], setTyp = _typ[1];
    var _reg = useState("All Regions"), reg = _reg[0], setReg = _reg[1];
    var _sort = useState("Reliability"), sortBy = _sort[0], setSortBy = _sort[1];
    var _view = useState("list"), view = _view[0], setView = _view[1];
    var _menu = useState(null), menu = _menu[0], setMenu = _menu[1];
    var _modal = useState(null), modal = _modal[0], setModal = _modal[1];
    var _detail = useState(null), detail = _detail[0], setDetail = _detail[1];
    var _page = useState(1), page = _page[0], setPage = _page[1];

    useEffect(function () {
      if (menu === null) return;
      function onDoc() { setMenu(null); }
      document.addEventListener("click", onDoc);
      return function () { document.removeEventListener("click", onDoc); };
    }, [menu]);
    // reset to page 1 whenever the filtered set changes
    useEffect(function () { setPage(1); }, [q, cat, typ, reg, sortBy]);
    // persist source changes to the real workspace store
    useEffect(function () { Store.setSources(ws.id, sources); }, [sources]);
    function useRecommendedSources() { var recs = demoSourceSeed().slice(0, 12); setSources(recs); setModal(null); toast(recs.length + " recommended sources added to your workspace."); }

    // ── options derived from the actual data ──
    var cats = useMemo(function () { var m = {}; sources.forEach(function (s) { m[s.category] = 1; }); return ["All Categories"].concat(Object.keys(m).sort()); }, [sources]);
    var types = useMemo(function () { var m = {}; sources.forEach(function (s) { m[s.type] = 1; }); return ["All Types"].concat(Object.keys(m).sort()); }, [sources]);
    var regions = useMemo(function () { var m = {}; sources.forEach(function (s) { m[s.region] = 1; }); return ["All Regions"].concat(Object.keys(m).sort()); }, [sources]);

    // ── stats computed from the actual data ──
    var total = sources.length;
    var activeCount = sources.filter(function (s) { return s.status === "Active"; }).length;
    var todayStart = new Date(); todayStart.setHours(0, 0, 0, 0);
    var updatedToday = sources.filter(function (s) { return s.updatedAt >= todayStart.getTime(); }).length;
    var avgRel = total ? Math.round(sources.reduce(function (n, s) { return n + s.reliability; }, 0) / total) : 0;
    var health = SRC_STATUSES.map(function (st) {
      var count = sources.filter(function (s) { return s.status === st; }).length;
      return { label: st, count: count, pct: total ? Math.round(count / total * 100) : 0 };
    });
    var healthColor = { Active: "#4F8A54", Warning: "#B5701E", Inactive: "#A79E92", Blocked: "#C4442E" };
    var topCats = useMemo(function () {
      var m = {}; sources.forEach(function (s) { m[s.category] = (m[s.category] || 0) + 1; });
      return Object.keys(m).map(function (k) { return [k, m[k]]; }).sort(function (a, b) { return b[1] - a[1]; });
    }, [sources]);
    var recent = sources.slice().sort(function (a, b) { return b.createdAt - a.createdAt; }).slice(0, 3);

    // ── filter + sort across ALL sources, then paginate ──
    var filtered = sources.filter(function (s) {
      if (cat !== "All Categories" && s.category !== cat) return false;
      if (typ !== "All Types" && s.type !== typ) return false;
      if (reg !== "All Regions" && s.region !== reg) return false;
      if (q.trim()) {
        var hay = (s.name + " " + s.domain + " " + s.category + " " + s.type + " " + s.region + " " + s.status).toLowerCase();
        if (hay.indexOf(q.trim().toLowerCase()) === -1) return false;
      }
      return true;
    }).sort(function (a, b) {
      if (sortBy === "Reliability") return b.reliability - a.reliability;
      if (sortBy === "Last updated") return b.updatedAt - a.updatedAt;
      if (sortBy === "Name") return a.name.localeCompare(b.name);
      if (sortBy === "Status") return a.status.localeCompare(b.status);
      if (sortBy === "Category") return a.category.localeCompare(b.category);
      return 0;
    });
    var pageCount = Math.max(1, Math.ceil(filtered.length / SRC_PERPAGE));
    var curPage = Math.min(page, pageCount);
    var startIdx = (curPage - 1) * SRC_PERPAGE;
    var visible = filtered.slice(startIdx, startIdx + SRC_PERPAGE);

    // ── source management (preview local state) ──
    function pauseSource(s) {
      if (s.status === "Inactive") { toast(s.name + " is already paused"); return; }
      setSources(sources.map(function (x) { return x.id === s.id ? Object.assign({}, x, { status: "Inactive", updatedAt: Date.now() }) : x; }));
      toast(s.name + " paused (set to Inactive)");
    }
    function removeSource(s) {
      if (!window.confirm("Remove " + s.name + " from your preview workspace?")) return;
      setSources(sources.filter(function (x) { return x.id !== s.id; }));
      if (detail && detail.id === s.id) setDetail(null);
      toast(s.name + " removed");
    }
    function addSource(rec) { setSources([rec].concat(sources)); setModal(null); toast("Source added to preview workspace."); }

    function rowMenu(s) {
      return h("div", { style: { position: "relative" } },
        h("button", { className: "ent-menu-btn", "aria-label": "Source actions", onClick: function (e) { e.stopPropagation(); setMenu(menu === s.id ? null : s.id); } }, h(Ico, { name: "dots", size: 16 })),
        menu === s.id ? h("div", { className: "ent-tb-menu-pop", style: { top: "28px", right: 0, minWidth: "188px" }, onClick: function (e) { e.stopPropagation(); } },
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setDetail(s); } }, h(Ico, { name: "eye", size: 15 }), "View source details"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setDetail(s); } }, h(Ico, { name: "signal", size: 15 }), "View recent signals"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); pauseSource(s); } }, h(Ico, { name: "pause", size: 15 }), "Pause source"),
          h("button", { className: "ent-tb-menu-item", style: { color: "#C4442E" }, onClick: function () { setMenu(null); removeSource(s); } }, h(Ico, { name: "trash", size: 15 }), "Remove source")) : null);
    }
    function catPill(c) { return h("span", { style: { fontSize: "11.5px", color: "var(--ent-body)", background: "var(--ent-surface-2)", border: "1px solid var(--ent-border-2)", borderRadius: "6px", padding: "2px 8px", whiteSpace: "nowrap", display: "inline-block" } }, c); }
    function relCell(s) {
      return h("div", { style: { minWidth: "82px" } },
        h("div", { style: { fontWeight: 700, fontSize: "13px", marginBottom: "3px" } }, s.reliability),
        h("div", { className: "ent-bar", style: { width: "72px" } }, h("i", { style: { width: s.reliability + "%", background: srcRelColor(s.reliability) } })));
    }
    function srcAvatar(s) { return h("div", { style: { width: "30px", height: "30px", borderRadius: "8px", background: "var(--ent-tint)", color: "var(--ent-accent-d)", display: "grid", placeItems: "center", fontSize: "11px", fontWeight: 700, flex: "none" } }, srcInitials(s.name)); }

    var listView = h("div", { className: "ent-table-wrap" }, h("table", { className: "ent-table" },
      h("thead", null, h("tr", null, ["Source", "Category", "Type", "Region", "Reliability", "Last updated", "Status", ""].map(function (c, i) { return h("th", { key: i }, c); }))),
      h("tbody", null, visible.map(function (s) {
        return h("tr", { key: s.id, style: { cursor: "pointer" }, onClick: function () { setDetail(s); } },
          h("td", null, h("div", { style: { display: "flex", alignItems: "center", gap: "10px" } }, srcAvatar(s), h("div", null, h("div", { className: "ent-td-name" }, s.name), h("div", { className: "ent-td-domain" }, s.domain)))),
          h("td", null, catPill(s.category)),
          h("td", null, s.type), h("td", null, s.region),
          h("td", null, relCell(s)),
          h("td", null, srcUpdatedLabel(s.updatedAt)),
          h("td", null, h(Badge, { kind: s.status.toLowerCase() }, s.status)),
          h("td", { style: { textAlign: "right" }, onClick: function (e) { e.stopPropagation(); } }, rowMenu(s)));
      }))));

    var gridView = h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(230px,1fr))", gap: "12px" } },
      visible.map(function (s) {
        return h("div", { key: s.id, className: "ent-card ent-card-pad", style: { cursor: "pointer" }, onClick: function () { setDetail(s); } },
          h("div", { style: { display: "flex", alignItems: "center", gap: "10px", marginBottom: "10px" } }, srcAvatar(s),
            h("div", { style: { flex: 1, minWidth: 0 } }, h("div", { className: "ent-td-name" }, s.name), h("div", { className: "ent-td-domain" }, s.domain)),
            h("div", { onClick: function (e) { e.stopPropagation(); } }, rowMenu(s))),
          h("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "10px" } }, catPill(s.category), h(Badge, { kind: s.status.toLowerCase() }, s.status)),
          h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", fontSize: "12px", color: "var(--ent-muted)" } }, h("span", null, "Reliability ", h("b", { style: { color: "var(--ent-ink)" } }, s.reliability)), h("span", null, srcUpdatedLabel(s.updatedAt))),
          h("div", { className: "ent-bar", style: { marginTop: "6px" } }, h("i", { style: { width: s.reliability + "%", background: srcRelColor(s.reliability) } })));
      }));

    // ── pager (real) ──
    function pageBtn(n) { return h("button", { key: "p" + n, className: "ent-btn ent-btn--sm" + (n === curPage ? " ent-btn--primary" : ""), onClick: function () { setPage(n); } }, n); }
    var pageNums = [];
    if (pageCount <= 7) { for (var pi = 1; pi <= pageCount; pi++) pageNums.push(pageBtn(pi)); }
    else {
      pageNums.push(pageBtn(1));
      if (curPage > 3) pageNums.push(h("span", { key: "e1", style: { color: "var(--ent-faint)", padding: "0 4px" } }, "…"));
      var lo = Math.max(2, curPage - 1), hi = Math.min(pageCount - 1, curPage + 1);
      for (var pj = lo; pj <= hi; pj++) pageNums.push(pageBtn(pj));
      if (curPage < pageCount - 2) pageNums.push(h("span", { key: "e2", style: { color: "var(--ent-faint)", padding: "0 4px" } }, "…"));
      pageNums.push(pageBtn(pageCount));
    }
    var showingLo = filtered.length ? startIdx + 1 : 0;
    var showingHi = startIdx + visible.length;

    var main = h("div", { className: "ent-col" },
      h(PageHead, {
        title: "Sources",
        sub: "Mira scans trusted sources to keep your intelligence accurate and up to date. Manage your sources, connect new feeds, and track source performance.",
        actions: h("button", { className: "ent-btn ent-btn--primary", onClick: function () { setModal("add"); } }, h(Ico, { name: "plus", size: 15 }), "Add Source"),
      }),
      h("div", { className: "ent-kpis", style: { marginBottom: "16px" } },
        h(KPI, { label: "Total sources", value: total, icon: "source", delta: topCats.length + " categories", trend: "flat" }),
        h(KPI, { label: "Active sources", value: activeCount, icon: "check", delta: (total ? Math.round(activeCount / total * 100) : 0) + "% of total sources", trend: "up" }),
        h(KPI, { label: "Updated today", value: updatedToday, icon: "clock", delta: (activeCount ? Math.round(updatedToday / activeCount * 100) : 0) + "% of active sources", trend: "flat" }),
        h(KPI, { label: "Avg. reliability score", value: total ? avgRel : "—", icon: "shield", delta: total ? (avgRel >= 85 ? "High reliability" : avgRel >= 70 ? "Moderate reliability" : "Mixed reliability") : "Not enough data", trend: "flat" })),
      h("div", { className: "ent-filters" },
        h("div", { className: "ent-search-box" }, h(Ico, { name: "search", size: 15 }), h("input", { type: "search", placeholder: "Search sources...", value: q, onChange: function (e) { setQ(e.target.value); } })),
        h("select", { className: "ent-select", value: cat, "aria-label": "Category", onChange: function (e) { setCat(e.target.value); } }, cats.map(function (o) { return h("option", { key: o, value: o }, o); })),
        h("select", { className: "ent-select", value: typ, "aria-label": "Type", onChange: function (e) { setTyp(e.target.value); } }, types.map(function (o) { return h("option", { key: o, value: o }, o); })),
        h("select", { className: "ent-select", value: reg, "aria-label": "Region", onChange: function (e) { setReg(e.target.value); } }, regions.map(function (o) { return h("option", { key: o, value: o }, o); })),
        h("select", { className: "ent-select", value: sortBy, "aria-label": "Sort", onChange: function (e) { setSortBy(e.target.value); } }, ["Reliability", "Last updated", "Name", "Status", "Category"].map(function (o) { return h("option", { key: o, value: o }, "Sort: " + o); })),
        h("div", { style: { display: "flex", gap: "4px", marginLeft: "auto" } },
          h("button", { className: "ent-btn ent-btn--sm" + (view === "list" ? " ent-btn--primary" : ""), "aria-label": "List view", onClick: function () { setView("list"); } }, h(Ico, { name: "menu", size: 15 })),
          h("button", { className: "ent-btn ent-btn--sm" + (view === "grid" ? " ent-btn--primary" : ""), "aria-label": "Grid view", onClick: function () { setView("grid"); } }, h(Ico, { name: "layers", size: 15 })))),
      total === 0
        ? h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
            h(EmptyState, { icon: "source", text: "No sources connected yet. Sources are the trusted places Mira scans for your monitors." }),
            h("div", { style: { display: "flex", gap: "8px", justifyContent: "center", flexWrap: "wrap" } },
              h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { setModal("add"); } }, "Add source"),
              h("button", { className: "ent-btn ent-btn--sm", onClick: useRecommendedSources }, "Use recommended sources")))
        : (filtered.length === 0 ? h(EmptyState, { icon: "search", text: "No sources match this search." }) : (view === "list" ? listView : gridView)),
      filtered.length ? h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: "14px", flexWrap: "wrap", gap: "10px" } },
        h("div", { style: { fontSize: "12.5px", color: "var(--ent-muted)" } }, "Showing " + showingLo + " to " + showingHi + " of " + filtered.length + " source" + (filtered.length === 1 ? "" : "s")),
        pageCount > 1 ? h("div", { style: { display: "flex", gap: "4px", alignItems: "center" } },
          h("button", { className: "ent-btn ent-btn--sm", disabled: curPage === 1, onClick: function () { if (curPage > 1) setPage(curPage - 1); } }, "Prev"),
          pageNums,
          h("button", { className: "ent-btn ent-btn--sm", disabled: curPage === pageCount, onClick: function () { if (curPage < pageCount) setPage(curPage + 1); } }, "Next")) : null) : null,
      modal === "add" ? h(Modal, { title: "Add source", onClose: function () { setModal(null); } }, h(AddSourceForm, { onAdd: addSource, onCancel: function () { setModal(null); } })) : null,
      modal === "health" ? h(Modal, { title: "Source health report", onClose: function () { setModal(null); }, foot: h("button", { className: "ent-btn ent-btn--primary", onClick: function () { setModal(null); } }, "Close") },
        h("div", null,
          health.map(function (hh, i) {
            return h("div", { key: i, style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 0", borderBottom: "1px solid var(--ent-border-2)" } },
              h("span", { className: "ent-badge ent-badge--" + hh.label.toLowerCase() }, hh.label),
              h("span", null, h("b", null, hh.count), h("span", { style: { color: "var(--ent-muted)", marginLeft: "8px" } }, hh.pct + "%")));
          }),
          h("p", { style: { fontSize: "12.5px", color: "var(--ent-muted)", marginTop: "14px", lineHeight: 1.5 } }, "Percentages are computed live from " + total + " source records. Reliability blends update recency, publishing volume and historical consistency. Status reflects activity, not an editorial endorsement — Mira does not claim every source is independently verified."))) : null,
      detail ? h(Modal, { title: detail.name, onClose: function () { setDetail(null); },
        foot: [
          h("button", { key: "p", className: "ent-btn", onClick: function () { pauseSource(detail); setDetail(Object.assign({}, detail, { status: "Inactive" })); } }, "Pause"),
          h("button", { key: "r", className: "ent-btn", style: { color: "#C4442E" }, onClick: function () { removeSource(detail); } }, "Remove"),
          h("button", { key: "c", className: "ent-btn ent-btn--primary", onClick: function () { setDetail(null); } }, "Close"),
        ] },
        h("div", null,
          h("div", { style: { display: "flex", gap: "12px", alignItems: "center", marginBottom: "14px" } }, srcAvatar(detail),
            h("div", null, h("div", { style: { fontWeight: 700 } }, detail.name), h("a", { href: "https://" + detail.domain, target: "_blank", rel: "noopener", className: "ent-td-domain", style: { color: "var(--ent-accent-d)" } }, detail.domain))),
          [["Category", detail.category], ["Type", detail.type], ["Region", detail.region], ["Reliability", detail.reliability + " / 100"], ["Status", detail.status], ["Last updated", srcUpdatedLabel(detail.updatedAt)], ["Added", srcUpdatedLabel(detail.createdAt)]].map(function (row, i) {
            return h("div", { key: i, style: { display: "flex", justifyContent: "space-between", padding: "7px 0", borderBottom: "1px solid var(--ent-border-2)", fontSize: "13px" } }, h("span", { style: { color: "var(--ent-muted)" } }, row[0]), h("span", { style: { fontWeight: 600 } }, row[1]));
          }),
          h("div", { className: "ent-bar", style: { marginTop: "12px" } }, h("i", { style: { width: detail.reliability + "%", background: srcRelColor(detail.reliability) } })),
          h("div", { style: { marginTop: "16px" } }, h("div", { className: "ent-rail-title" }, "Recent signals"), h(EmptyState, { icon: "signal", text: "Live signals from this source will appear here once monitors are connected." })))) : null);

    var rail = h("div", { className: "ent-rail" },
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Source health"),
        (function () {
          var a = health[0].pct, w = health[1].pct, ia = health[2].pct;
          var g = "conic-gradient(#4F8A54 0% " + a + "%, #B5701E " + a + "% " + (a + w) + "%, #A79E92 " + (a + w) + "% " + (a + w + ia) + "%, #C4442E " + (a + w + ia) + "% 100%)";
          return h("div", { style: { display: "flex", justifyContent: "center", padding: "6px 0 14px" } },
            h("div", { style: { width: "120px", height: "120px", borderRadius: "50%", background: g, display: "grid", placeItems: "center" } },
              h("div", { style: { width: "84px", height: "84px", borderRadius: "50%", background: "var(--ent-surface)", display: "grid", placeItems: "center", textAlign: "center" } },
                h("div", null, h("div", { style: { fontSize: "22px", fontWeight: 700, fontFamily: "Georgia,serif" } }, health[0].pct + "%"), h("div", { style: { fontSize: "11px", color: "var(--ent-muted)" } }, "Active")))));
        })(),
        health.map(function (hh, i) {
          return h("div", { key: i, className: "ent-rail-row" },
            h("span", { className: "l" }, h("span", { style: { width: "9px", height: "9px", borderRadius: "50%", background: healthColor[hh.label], display: "inline-block" } }), hh.label),
            h("span", { className: "v" }, hh.count + " · " + hh.pct + "%"));
        }),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: "10px", width: "100%", justifyContent: "center" }, onClick: function () { setModal("health"); } }, "View health report")),
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Top categories"),
        topCats.map(function (c, i) { return h("div", { key: i, className: "ent-rail-row", style: { cursor: "pointer" }, onClick: function () { setCat(c[0]); } }, h("span", { className: "l" }, c[0]), h("span", { className: "v" }, c[1])); })),
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Recently added"),
        recent.map(function (s, i) {
          return h("div", { key: s.id, style: { padding: "8px 0", borderTop: i ? "1px solid var(--ent-border-2)" : "none", cursor: "pointer" }, onClick: function () { setDetail(s); } },
            h("div", { style: { fontSize: "13px", fontWeight: 600 } }, s.name),
            h("div", { style: { fontSize: "11.5px", color: "var(--ent-faint)" } }, s.type + " · " + s.region + " · " + srcUpdatedLabel(s.createdAt)));
        })),
      h("div", { className: "ent-rail-card" },
        h("div", { style: { fontSize: "13px", fontWeight: 700, marginBottom: "4px" } }, "Need more sources?"),
        h("div", { style: { fontSize: "12px", color: "var(--ent-muted)", marginBottom: "10px", lineHeight: 1.45 } }, "Request a source or connect a custom feed."),
        h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", style: { width: "100%", justifyContent: "center" }, onClick: function () { setModal("add"); } }, "Request a source")));

    return [main, rail];
  }

  function AddSourceForm(props) {
    var onAdd = props.onAdd, onCancel = props.onCancel;
    var _n = useState(""), name = _n[0], setName = _n[1];
    var _u = useState(""), url = _u[0], setUrl = _u[1];
    var _c = useState("News Media"), cat = _c[0], setCat = _c[1];
    var _t = useState("Website"), type = _t[0], setType = _t[1];
    var _r = useState("Global"), reg = _r[0], setReg = _r[1];
    var _w = useState(""), why = _w[0], setWhy = _w[1];
    var _err = useState(""), err = _err[0], setErr = _err[1];
    // TODO: persist Enterprise sources to workspace database before launch.
    function submit() {
      if (!name.trim() || !url.trim()) { setErr("Source name and website URL are required."); return; }
      var dom = url.trim();
      try { dom = new URL(/^https?:\/\//.test(url.trim()) ? url.trim() : "https://" + url.trim()).hostname.replace(/^www\./, ""); } catch (e) {}
      onAdd({ id: "src-new-" + Date.now(), name: name.trim(), domain: dom, category: cat, type: type, region: reg, reliability: 70, status: "Active", updatedAt: Date.now(), createdAt: Date.now(), pending: true });
    }
    return h("div", null,
      err ? h("div", { className: "ent-gate-msg ent-gate-msg--err", style: { marginBottom: "12px" } }, err) : null,
      h("div", { className: "ent-field" }, h("label", null, "Source name"), h("input", { className: "ent-input", placeholder: "e.g. African Development Bank", value: name, onChange: function (e) { setName(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Website URL"), h("input", { className: "ent-input", placeholder: "https://example.org", value: url, onChange: function (e) { setUrl(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Category"), h("select", { className: "ent-select", value: cat, onChange: function (e) { setCat(e.target.value); } }, ["News Media", "International Organizations", "UN Agencies", "NGO / Non-profit", "Think Tanks", "Government", "Academic / Research", "Financial Institutions", "Donor Agencies", "Data Portals", "Other"].map(function (o) { return h("option", { key: o, value: o }, o); }))),
      h("div", { className: "ent-field" }, h("label", null, "Type"), h("select", { className: "ent-select", value: type, onChange: function (e) { setType(e.target.value); } }, ["Website", "News", "Wire", "Database", "Journal", "Official", "Aggregator"].map(function (o) { return h("option", { key: o, value: o }, o); }))),
      h("div", { className: "ent-field" }, h("label", null, "Region"), h("select", { className: "ent-select", value: reg, onChange: function (e) { setReg(e.target.value); } }, ["Global", "Africa", "Middle East, Africa", "Asia", "Latin America", "Europe"].map(function (o) { return h("option", { key: o, value: o }, o); }))),
      h("div", { className: "ent-field" }, h("label", null, "Why should Mira track this?"), h("textarea", { className: "ent-textarea", rows: 3, placeholder: "What this source adds to your coverage...", value: why, onChange: function (e) { setWhy(e.target.value); } })),
      h("div", { style: { display: "flex", justifyContent: "flex-end", gap: "10px", marginTop: "4px" } },
        h("button", { className: "ent-btn", onClick: onCancel }, "Cancel"),
        h("button", { className: "ent-btn ent-btn--primary", onClick: submit }, "Add source")));
  }


  // ============================================================
  //  REPORTS
  // ============================================================
  // Enterprise DEMO report records — labelled demo, kept out of the public
  // news app. Report CONTENT (summary, insights, stories) is derived from the
  // real Globly stories passed in, so nothing is fabricated.
  function demoReports() {
    var now = Date.now(), d = 86400000;
    return [
      { id: "wk-cur", title: "Weekly Intelligence Report", type: "Weekly", monitor: "All monitors", date: now, monitors: 12, signals: 54,
        summary: "This week saw significant developments in climate finance, regional conflicts and food security. Funding commitments increased in South Asia, while displacement numbers continued to rise in Sudan. AI adoption in health systems also accelerated globally." },
      { id: "daily", title: "Daily Brief", type: "Daily", monitor: "Priority monitors", date: now - d, monitors: 7, signals: 21,
        summary: "A concise summary of the most important overnight changes across your priority monitors." },
      { id: "wk-prev", title: "Weekly Intelligence — prior week", type: "Weekly", monitor: "All monitors", date: now - 7 * d, monitors: 12, signals: 49,
        summary: "The previous week's in-depth analysis and trends across all active monitors." },
      { id: "climate", title: "Climate Finance Deep Dive", type: "Custom", monitor: "Climate Finance", date: now - 5 * d, monitors: 3, signals: 18,
        summary: "A focused custom report on adaptation finance commitments and disbursement gaps in South Asia." },
    ];
  }
  var REPORT_TYPES = [
    { name: "Daily Brief", desc: "Quick daily summary of key changes", badge: "Daily", kind: "pending" },
    { name: "Weekly Intelligence", desc: "In-depth weekly analysis and trends", badge: "Weekly", kind: "pending" },
    { name: "Monthly Outlook", desc: "Deep dive into monthly patterns", badge: "Monthly", kind: "active" },
    { name: "Custom Report", desc: "Build a report for your specific needs", badge: "Custom", kind: "warning" },
  ];
  var REPORT_SCHEDULE = [
    { title: "Daily Brief", cadence: "Every day, 8:00 AM", next: "Tomorrow, 8:00 AM", type: "Daily", kind: "pending" },
    { title: "Weekly Intelligence Report", cadence: "Every Monday, 9:00 AM", next: "Monday, 9:00 AM", type: "Weekly", kind: "pending" },
    { title: "Monthly Outlook", cadence: "1st of each month", next: "1 Aug, 9:00 AM", type: "Monthly", kind: "active" },
  ];
  function reportTypeKind(t) { return t === "Monthly" ? "active" : t === "Custom" ? "warning" : "pending"; }
  function reportInsights(top) {
    // Impact-ranked insights derived from the real top stories (source-grounded).
    return top.slice(0, 3).map(function (a) {
      var s = sig(a);
      return {
        title: (a.title || "").slice(0, 90),
        desc: (a.summary || a.deeper_summary || a.title || "").slice(0, 150),
        impact: s >= 3 ? "high" : s >= 2 ? "medium" : "low",
      };
    });
  }

  function ReportsPage(props) {
    var ws = props.ws, stories = props.stories, toast = props.toast;
    var monitors = Store.monitors(ws.id);
    var _tab = useState("overview"), tab = _tab[0], setTab = _tab[1];
    var _rt = useState("summary"), rt = _rt[0], setRt = _rt[1];
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _ft = useState("All Types"), ftype = _ft[0], setFtype = _ft[1];
    var _fm = useState("All Monitors"), fmon = _fm[0], setFmon = _fm[1];
    var _fp = useState("All Time"), fper = _fp[0], setFper = _fp[1];
    var _view = useState("list"), view = _view[0], setView = _view[1];
    var _menu = useState(null), menu = _menu[0], setMenu = _menu[1];
    var _modal = useState(false), modal = _modal[0], setModal = _modal[1];

    useEffect(function () {
      if (menu === null) return;
      function onDoc() { setMenu(null); }
      document.addEventListener("click", onDoc);
      return function () { document.removeEventListener("click", onDoc); };
    }, [menu]);

    var pool = stories.filter(isFresh48); if (pool.length < 6) pool = stories;
    var top = pool.slice().sort(function (a, b) { return sig(b) - sig(a); }).slice(0, 8);
    var insights = reportInsights(top);
    var _reports = useState(function () { return Store.reports(ws.id); }), reports = _reports[0], setReports = _reports[1];
    function createReport(cfg) {
      // TODO: persist Enterprise reports to the workspace database before launch.
      if (monitors.length === 0) { setModal(false); toast("Create a monitor first to generate a report."); return; }
      cfg = cfg || {};
      var typeMap = { "Daily Brief": "Daily", "Weekly Intelligence": "Weekly", "Monthly Outlook": "Monthly", "Custom Report": "Custom" };
      var rep = { id: "rep_" + Date.now().toString(36), title: (cfg.name && cfg.name.trim()) || (cfg.type || "Custom Report"),
        type: typeMap[cfg.type] || "Custom", monitor: "All monitors", date: Date.now(), monitors: monitors.length, signals: top.length,
        summary: "Generated from " + monitors.length + " monitor" + (monitors.length === 1 ? "" : "s") + " over " + (cfg.range || "the last 7 days") + ", grounded in current reporting." };
      var next = [rep].concat(reports); setReports(next); Store.setReports(ws.id, next); setModal(false); toast("Report created."); }
    var monitorOpts = ["All Monitors"].concat(monitors.map(function (m) { return m.name; }));

    var filtered = reports.filter(function (r) {
      if (ftype !== "All Types" && r.type !== ftype) return false;
      if (fmon !== "All Monitors" && monitors.length && r.monitor !== fmon) return false;
      if (fper !== "All Time") {
        var days = fper === "Today" ? 1 : fper === "This week" ? 7 : 31;
        if (Date.now() - r.date > days * 86400000) return false;
      }
      if (q.trim()) {
        var hay = (r.title + " " + r.type + " " + r.monitor + " " + fmtDate(r.date) + " " + r.summary).toLowerCase();
        if (hay.indexOf(q.trim().toLowerCase()) === -1) return false;
      }
      return true;
    });
    var featured = filtered[0] || reports[0];

    function printReport(rep) {
      var w = window.open("", "_blank");
      if (!w) { toast("Allow pop-ups to export"); return; }
      var esc = escapeHtml;
      var typeLabel = { Weekly: "Weekly Intelligence Report", Daily: "Daily Brief", Monthly: "Monthly Outlook", Custom: "Custom Intelligence Report" }[rep.type] || "Intelligence Report";
      var genDate = fmtDate(Date.now());
      var periodStart = fmtDate(rep.date - 6 * 86400000), periodEnd = fmtDate(rep.date);
      var regions = topRegions(top);
      function priOf(a) { var s = sig(a); return s >= 3 ? "high" : s >= 2 ? "medium" : "low"; }
      function priCap(k) { return k.charAt(0).toUpperCase() + k.slice(1); }

      var storyCards = top.map(function (a, i) {
        var region = a.region || a.country || "";
        var src = a.sourceName || a.source || "";
        var sum = (a.summary || a.deeper_summary || "").replace(/\s+/g, " ").trim().slice(0, 190);
        var pk = priOf(a);
        return '<div class="block story">' +
          '<div class="rank">' + (i + 1) + '</div>' +
          '<div class="story-main">' +
            '<div class="story-head">' + esc(a.title || "") + '</div>' +
            (sum ? '<div class="story-sum">' + esc(sum) + '</div>' : '') +
            '<div class="tags">' +
              (region ? '<span class="pill pill-neutral">' + esc(region) + '</span>' : '') +
              '<span class="pill pri-' + pk + '">' + priCap(pk) + ' priority</span>' +
              (src ? '<span class="src">' + esc(src) + '</span>' : '') +
            '</div>' +
          '</div>' +
        '</div>';
      }).join("");

      var insightCards = insights.map(function (ins) {
        var lab = ins.impact === "high" ? "High impact" : ins.impact === "medium" ? "Medium impact" : "Low impact";
        return '<div class="block insight">' +
          '<div class="insight-top"><div class="insight-title">' + esc(ins.title) + '</div><span class="pill pri-' + ins.impact + '">' + lab + '</span></div>' +
          '<div class="insight-desc">' + esc(ins.desc) + '</div>' +
        '</div>';
      }).join("");

      var monCells = monitors.map(function (m) {
        var pk = (m.priority || "").toLowerCase();
        return '<div class="mon"><span class="mon-name">' + esc(m.name) + '</span><span class="pill pri-' + pk + '">' + esc(m.priority || "") + '</span></div>';
      }).join("");

      var regionChips = regions.map(function (r) {
        return '<span class="rchip">' + esc(r.name) + '<b>' + r.count + '</b></span>';
      }).join("");

      var n = 1;
      function sec(title) { var k = ("0" + (n++)).slice(-2); return '<div class="block sec-hd"><span class="kicker">' + k + '</span>' + title + '</div>'; }

      var content =
        '<div class="block hero">' +
          '<div class="eyebrow">Globally &middot; Mira Enterprise</div>' +
          '<h1 class="title">' + esc(rep.title) + '</h1>' +
          '<div class="hero-meta"><span class="type-pill">' + esc(rep.type) + ' report</span><span>' + esc(ws.name) + '</span><span class="dot">&middot;</span><span>Generated ' + esc(genDate) + '</span><span class="dot">&middot;</span><span>Period ' + esc(periodStart) + ' &ndash; ' + esc(periodEnd) + '</span></div>' +
          '<div class="hero-stats"><div><b>' + (rep.monitors || monitors.length) + '</b>monitors</div><div><b>' + (rep.signals || top.length) + '</b>signals</div><div><b>' + top.length + '</b>top stories</div></div>' +
        '</div>' +
        sec('Executive summary') +
        '<div class="block summary-card">' + esc(rep.summary) + '</div>' +
        (insightCards ? sec('Key insights') + insightCards : '') +
        (storyCards ? sec('Top stories') + storyCards : '') +
        (regionChips ? sec('Regions to watch') + '<div class="block rchips">' + regionChips + '</div>' : '') +
        (monCells ? sec('Active monitors') + '<div class="block mon-grid">' + monCells + '</div>' : '');

      var css = `
        *{box-sizing:border-box;-webkit-print-color-adjust:exact;print-color-adjust:exact;}
        html,body{margin:0;padding:0;background:#EDEAE3;}
        body{font-family:ui-sans-serif,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;color:#1A1712;-webkit-font-smoothing:antialiased;}
        #content{position:absolute;left:-9999px;top:0;width:174mm;}
        @page{size:A4;margin:0;}
        .page{width:210mm;height:297mm;padding:20mm 18mm 26mm;position:relative;background:#fff;overflow:hidden;page-break-after:always;box-shadow:0 1px 6px rgba(0,0,0,.12);margin:0 auto;}
        .page:last-child{page-break-after:auto;}
        @media print{.page{box-shadow:none;margin:0;} body{background:#fff;}}
        .hero{padding-bottom:16px;border-bottom:2px solid #1A1712;margin-bottom:8px;}
        .eyebrow{font-size:11px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#7C3AED;margin-bottom:11px;}
        .title{font-family:Georgia,"Times New Roman",serif;font-size:33px;line-height:1.08;font-weight:700;letter-spacing:-.015em;margin:0 0 14px;color:#1A1712;}
        .hero-meta{font-size:12px;color:#6b6459;display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
        .hero-meta .dot{color:#c9c1b4;}
        .type-pill{font-size:9.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#7C3AED;background:#F1ECFB;padding:3px 9px;border-radius:999px;}
        .hero-stats{display:flex;gap:30px;margin-top:16px;}
        .hero-stats div{font-size:11px;color:#8a8275;text-transform:uppercase;letter-spacing:.06em;font-weight:600;}
        .hero-stats b{font-family:Georgia,serif;font-size:22px;color:#1A1712;display:block;font-weight:700;letter-spacing:-.01em;margin-bottom:2px;text-transform:none;}
        .sec-hd{font-family:Georgia,serif;font-size:18px;font-weight:700;color:#1A1712;margin:24px 0 12px;display:flex;align-items:baseline;gap:11px;}
        .sec-hd .kicker{font-family:ui-sans-serif,sans-serif;font-size:11px;font-weight:800;color:#7C3AED;letter-spacing:.12em;}
        .summary-card{background:#FBF9F4;border:1px solid #EAE4D8;border-left:3px solid #7C3AED;border-radius:12px;padding:18px 20px;font-size:13px;line-height:1.65;color:#3a352d;}
        .insight{border:1px solid #EAE4D8;border-radius:12px;padding:14px 16px;margin-bottom:9px;background:#fff;}
        .insight-top{display:flex;justify-content:space-between;gap:12px;align-items:flex-start;margin-bottom:5px;}
        .insight-title{font-size:13px;font-weight:700;color:#1A1712;line-height:1.35;}
        .insight-desc{font-size:12px;line-height:1.5;color:#6b6459;}
        .story{display:flex;gap:13px;padding:13px 2px;border-bottom:1px solid #EFEAE0;}
        .story-main{flex:1;min-width:0;}
        .rank{font-family:Georgia,serif;font-size:14px;font-weight:700;color:#7C3AED;width:26px;height:26px;border-radius:8px;background:#F1ECFB;display:flex;align-items:center;justify-content:center;flex:none;}
        .story-head{font-size:13.5px;font-weight:700;line-height:1.35;color:#1A1712;}
        .story-sum{font-size:12px;line-height:1.5;color:#6b6459;margin-top:4px;}
        .tags{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:8px;}
        .pill{font-size:10px;font-weight:700;padding:2.5px 9px;border-radius:999px;white-space:nowrap;}
        .pill-neutral{background:#F4F1EA;color:#6b6459;}
        .pri-high{background:#FCE7EC;color:#B4384F;}
        .pri-medium{background:#FBEFD8;color:#946017;}
        .pri-low{background:#EAF3EA;color:#3f7a48;}
        .src{font-size:10.5px;color:#a49b8d;margin-left:auto;font-style:italic;}
        .rchips{display:flex;flex-wrap:wrap;gap:8px;}
        .rchip{font-size:12px;color:#3a352d;background:#FBF9F4;border:1px solid #EAE4D8;border-radius:999px;padding:5px 13px;}
        .rchip b{color:#7C3AED;margin-left:7px;}
        .mon-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
        .mon{display:flex;justify-content:space-between;align-items:center;gap:10px;border:1px solid #EAE4D8;border-radius:10px;padding:10px 13px;background:#fff;}
        .mon-name{font-size:12.5px;font-weight:600;color:#1A1712;}
        .pfoot{position:absolute;left:18mm;right:18mm;bottom:13mm;display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:9px;border-top:1px solid #E7E1D5;}
        .pfoot-line{font-size:9px;color:#b3ab9d;letter-spacing:.02em;}
        .pfoot-right{display:flex;align-items:center;gap:14px;}
        .brand{display:flex;align-items:center;gap:7px;}
        .brand-mark{width:17px;height:17px;border-radius:5px;background:#7C3AED;color:#fff;font-family:Georgia,serif;font-weight:700;font-size:11px;display:flex;align-items:center;justify-content:center;line-height:1;}
        .brand-name{font-size:11px;font-weight:700;color:#1A1712;letter-spacing:.01em;}
        .pnum{font-size:10px;color:#8a8275;font-weight:600;}
      `;

      var script =
        '<script>(function(){' +
        'var MM=96/25.4;var avail=Math.floor((297-20-26)*MM)-8;' +
        'var pagesWrap=document.getElementById("pages");var src=document.getElementById("content");' +
        'var blocks=[].slice.call(src.children);' +
        'function newPage(){var p=document.createElement("div");p.className="page";var b=document.createElement("div");b.className="page-body";p.appendChild(b);pagesWrap.appendChild(p);return b;}' +
        'var cur=newPage();' +
        'blocks.forEach(function(b){cur.appendChild(b);if(cur.scrollHeight>avail){cur.removeChild(b);var prev=cur.lastElementChild;var carry=(prev&&prev.className.indexOf("sec-hd")!==-1)?prev:null;if(carry)cur.removeChild(carry);cur=newPage();if(carry)cur.appendChild(carry);cur.appendChild(b);}});' +
        'var pages=[].slice.call(document.querySelectorAll(".page"));var total=pages.length;' +
        'pages.forEach(function(p,i){var f=document.createElement("div");f.className="pfoot";' +
        'f.innerHTML=\'<div class="pfoot-line">Source-grounded intelligence generated by Mira Enterprise</div><div class="pfoot-right"><div class="brand"><span class="brand-mark">G</span><span class="brand-name">Globally &middot; Mira Enterprise</span></div><div class="pnum">Page \'+(i+1)+\' of \'+total+\'</div></div>\';' +
        'p.appendChild(f);});' +
        'src.parentNode.removeChild(src);' +
        'setTimeout(function(){window.focus();window.print();},400);' +
        '})();<\/script>';

      var doc = '<!doctype html><html><head><meta charset="utf-8"><title>' + esc(rep.title) + ' — Globally</title><style>' + css + '</style></head><body>' +
        '<div id="content">' + content + '</div><div id="pages"></div>' + script +
        '</body></html>';
      w.document.open(); w.document.write(doc); w.document.close();
      toast("Report opened — use your browser's Save as PDF");
    }

    function dotMenu(rep) {
      return h("div", { style: { position: "relative" } },
        h("button", { className: "ent-menu-btn", "aria-label": "Report actions", onClick: function (e) { e.stopPropagation(); setMenu(menu === rep.id ? null : rep.id); } }, h(Ico, { name: "dots", size: 16 })),
        menu === rep.id ? h("div", { className: "ent-tb-menu-pop", style: { top: "30px", minWidth: "168px" }, onClick: function (e) { e.stopPropagation(); } },
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setTab("overview"); setRt("summary"); toast("Viewing " + rep.title); } }, h(Ico, { name: "eye", size: 15 }), "View report"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); printReport(rep); } }, h(Ico, { name: "download", size: 15 }), "Download"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); toast("Duplicate is coming soon"); } }, h(Ico, { name: "copy", size: 15 }), "Duplicate"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setTab("scheduled"); } }, h(Ico, { name: "clock", size: 15 }), "Schedule"),
          h("button", { className: "ent-tb-menu-item", style: { color: "#C4442E" }, onClick: function () { setMenu(null); toast("Delete is coming soon"); } }, h(Ico, { name: "trash", size: 15 }), "Delete")) : null);
    }

    var main = h("div", null,
      h(PageHead, {
        title: "Reports",
        sub: "Reports turn signals and insights into clear, decision-ready intelligence. Create scheduled reports or generate custom reports anytime.",
        actions: h("button", { className: "ent-btn ent-btn--primary", onClick: function () { setModal(true); } }, h(Ico, { name: "plus", size: 15 }), "New Report"),
      }),
      h("div", { className: "ent-tabs" },
        [["overview", "Overview"], ["scheduled", "Scheduled"]].map(function (t) { return h("button", { key: t[0], className: "ent-tab" + (tab === t[0] ? " is-active" : ""), onClick: function () { setTab(t[0]); } }, t[1]); })),
      h("div", { className: "ent-kpis", style: { marginBottom: "16px" } },
        h(KPI, { label: "Reports created", value: reports.length, icon: "report", delta: reports.length ? "In this workspace" : "None yet", trend: "flat" }),
        h(KPI, { label: "Scheduled reports", value: 0, icon: "clock", delta: "Scheduling coming soon", trend: "flat" }),
        h(KPI, { label: "Downloads", value: 0, icon: "download", delta: "Across all reports", trend: "flat" }),
        h(KPI, { label: "Team views", value: 0, icon: "team", delta: "Across all reports", trend: "flat" })),
      tab === "overview" ? h("div", null,
        h("div", { className: "ent-filters" },
          h("div", { className: "ent-search-box" }, h(Ico, { name: "search", size: 15 }), h("input", { type: "search", placeholder: "Search reports...", value: q, onChange: function (e) { setQ(e.target.value); } })),
          h("select", { className: "ent-select", value: ftype, "aria-label": "All Types", onChange: function (e) { setFtype(e.target.value); } }, ["All Types", "Daily", "Weekly", "Monthly", "Custom"].map(function (o) { return h("option", { key: o }, o); })),
          h("select", { className: "ent-select", value: fmon, "aria-label": "All Monitors", onChange: function (e) { setFmon(e.target.value); } }, monitorOpts.map(function (o) { return h("option", { key: o }, o); })),
          h("select", { className: "ent-select", value: fper, "aria-label": "All Time", onChange: function (e) { setFper(e.target.value); } }, ["All Time", "Today", "This week", "This month"].map(function (o) { return h("option", { key: o }, o); })),
          h("div", { style: { display: "flex", gap: "4px", marginLeft: "auto" } },
            h("button", { className: "ent-btn ent-btn--sm" + (view === "list" ? " ent-btn--primary" : ""), "aria-label": "List view", onClick: function () { setView("list"); setTab("overview"); } }, h(Ico, { name: "menu", size: 15 })),
            h("button", { className: "ent-btn ent-btn--sm" + (view === "calendar" ? " ent-btn--primary" : ""), "aria-label": "Calendar view", onClick: function () { setView("calendar"); setTab("scheduled"); } }, h(Ico, { name: "clock", size: 15 })))),
        (reports.length === 0
          ? h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
              h(EmptyState, { icon: "report", text: "No reports yet. Reports are generated from your monitors, signals and briefings." }),
              h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { monitors.length ? setModal(true) : toast("Create a monitor first to generate a report."); } }, monitors.length ? "Create report" : "Create a monitor first"))
          : filtered.length === 0 ? h(EmptyState, { icon: "search", text: "No reports match your search." }) : h("div", { className: "ent-card" },
          h("div", { className: "ent-card-hd" },
            h("h3", null, featured.title),
            h("span", { className: "ent-badge ent-badge--" + reportTypeKind(featured.type), style: { marginLeft: "2px" } }, featured.type),
            h("div", { className: "ent-card-hd-actions" },
              h("span", { className: "ent-card-hd-sub" }, fmtDate(featured.date - 86400000 * 6) + " – " + fmtDate(featured.date)),
              h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { printReport(featured); } }, h(Ico, { name: "download", size: 14 }), "Download PDF"),
              dotMenu(featured))),
          h("div", { style: { display: "flex", gap: "20px", padding: "12px 20px", borderBottom: "1px solid var(--ent-border-2)", fontSize: "13px", color: "var(--ent-muted)" } },
            h("span", null, h("b", { style: { color: "var(--ent-ink)" } }, featured.monitors), " monitors"),
            h("span", null, h("b", { style: { color: "var(--ent-ink)" } }, featured.signals), " signals"),
            h("span", null, h("b", { style: { color: "var(--ent-ink)" } }, top.length), " top signals in view")),
          h("div", { className: "ent-tabs", style: { padding: "0 20px", marginBottom: 0, marginTop: "6px" } },
            [["summary", "Summary"], ["insights", "Key insights"], ["stories", "Top stories"], ["risks", "Risks & opportunities"], ["regions", "Regions"], ["sources", "Sources"]].map(function (t) {
              return h("button", { key: t[0], className: "ent-tab" + (rt === t[0] ? " is-active" : ""), onClick: function () { setRt(t[0]); } }, t[1]);
            })),
          h("div", { className: "ent-card-pad" },
            rt === "summary" ? h("div", null,
              h("h4", { style: { fontSize: "14px", fontWeight: 700, margin: "0 0 8px" } }, "Executive summary"),
              h("p", { style: { fontSize: "14px", lineHeight: 1.6, color: "var(--ent-body)", margin: 0 } }, featured.summary)) :
            rt === "insights" ? h("div", { style: { display: "flex", flexDirection: "column", gap: "10px" } },
              insights.map(function (ins, i) {
                return h("div", { key: i, style: { display: "flex", gap: "12px", alignItems: "flex-start", padding: "13px 14px", border: "1px solid var(--ent-border-2)", borderRadius: "10px", background: "var(--ent-surface-2)" } },
                  h("div", { style: { flex: 1, minWidth: 0 } },
                    h("div", { style: { fontSize: "13.5px", fontWeight: 700, color: "var(--ent-ink)" } }, ins.title),
                    h("div", { style: { fontSize: "12.5px", color: "var(--ent-muted)", marginTop: "3px", lineHeight: 1.45 } }, ins.desc)),
                  h("span", { className: "ent-badge ent-badge--" + ins.impact, style: { flex: "none" } }, ins.impact === "high" ? "High impact" : ins.impact === "medium" ? "Medium impact" : "Low impact"));
              }),
              h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: "4px" }, onClick: function () { printReport(featured); } }, "View full report", h(Ico, { name: "arrow", size: 14 }))) :
            h(ReportSection, { which: rt, top: top, monitors: monitors }))
        ))
      ) : h("div", { className: "ent-card ent-card-pad", style: { textAlign: "center" } },
        h(EmptyState, { icon: "clock", text: "No scheduled reports yet. Schedule a recurring report to have Mira generate it automatically." }),
        h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", onClick: function () { monitors.length ? setModal(true) : toast("Create a monitor first to generate a report."); } }, "Create a report")
      ),
      modal ? h(Modal, { title: "New report", onClose: function () { setModal(false); },
        foot: [
          h("button", { key: "c", className: "ent-btn", onClick: function () { setModal(false); } }, "Cancel"),
          h("button", { key: "g", className: "ent-btn ent-btn--primary", onClick: function () { createReport({ type: "Custom Report" }); } }, h(Ico, { name: "report", size: 15 }), "Generate report"),
        ] }, h(NewReportForm, { monitors: monitors })) : null);

    var rail = h("div", { className: "ent-rail" },
      h("div", { className: "ent-rail-card" },
        h("div", { className: "ent-rail-title" }, "Report types"),
        h("div", { className: "ent-action-list" }, REPORT_TYPES.map(function (t, i) {
          return h("button", { key: i, className: "ent-action-btn", style: { flexDirection: "column", alignItems: "stretch", gap: "3px" }, onClick: function () { setModal(true); } },
            h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "8px" } },
              h("span", { style: { fontWeight: 650, color: "var(--ent-ink)" } }, t.name),
              h("span", { className: "ent-badge ent-badge--" + t.kind }, t.badge)),
            h("span", { style: { fontSize: "12px", color: "var(--ent-muted)", fontWeight: 400 } }, t.desc));
        })),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: "10px" }, onClick: function () { toast("Template management is coming soon"); } }, "Manage templates")),
      h("div", { className: "ent-rail-card" },
        h("div", { style: { display: "flex", alignItems: "center", marginBottom: "10px" } },
          h("div", { className: "ent-rail-title", style: { marginBottom: 0 } }, "Recent reports"),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginLeft: "auto" }, onClick: function () { setTab("overview"); setQ(""); setFtype("All Types"); setFmon("All Monitors"); setFper("All Time"); } }, "View all")),
        reports.map(function (r) {
          return h("div", { key: r.id, style: { display: "flex", alignItems: "center", gap: "10px", padding: "8px 0", borderTop: "1px solid var(--ent-border-2)" } },
            h("div", { style: { width: "32px", height: "32px", borderRadius: "8px", background: "var(--ent-tint)", color: "var(--ent-accent-d)", display: "grid", placeItems: "center", flex: "none" } }, h(Ico, { name: "report", size: 15 })),
            h("div", { style: { flex: 1, minWidth: 0 } },
              h("div", { style: { fontSize: "13px", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" } }, r.title),
              h("div", { style: { fontSize: "11.5px", color: "var(--ent-faint)" } }, fmtDate(r.date) + " · " + r.monitors + " monitors")),
            dotMenu(r));
        })));

    return [main, rail];
  }

  function NewReportForm(props) {
    var monitors = props.monitors || [];
    var _n = useState(""), name = _n[0], setName = _n[1];
    var _t = useState("Weekly Intelligence"), type = _t[0], setType = _t[1];
    var _sel = useState([]), sel = _sel[0], setSel = _sel[1];
    var _dr = useState("Last 7 days"), dr = _dr[0], setDr = _dr[1];
    var _out = useState("PDF"), out = _out[0], setOut = _out[1];
    function toggle(n) { setSel(sel.indexOf(n) >= 0 ? sel.filter(function (x) { return x !== n; }) : sel.concat(n)); }
    var monNames = monitors.length ? monitors.map(function (m) { return m.name; }) : ["Climate Finance", "Migration & Displacement", "Food Security", "Global Health"];
    return h("div", null,
      h("div", { className: "ent-field" }, h("label", null, "Report name"), h("input", { className: "ent-input", placeholder: "e.g. Q3 Climate Finance Review", value: name, onChange: function (e) { setName(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Report type"), h("select", { className: "ent-select", value: type, onChange: function (e) { setType(e.target.value); } }, ["Daily Brief", "Weekly Intelligence", "Monthly Outlook", "Custom Report"].map(function (o) { return h("option", { key: o }, o); }))),
      h("div", { className: "ent-field" }, h("label", null, "Monitors to include"), h("div", { className: "ent-checks" }, monNames.map(function (m) { return h("button", { key: m, className: "ent-check" + (sel.indexOf(m) >= 0 ? " is-on" : ""), onClick: function () { toggle(m); } }, m); }))),
      h("div", { className: "ent-field" }, h("label", null, "Date range"), h("select", { className: "ent-select", value: dr, onChange: function (e) { setDr(e.target.value); } }, ["Last 24 hours", "Last 7 days", "Last 30 days", "This quarter"].map(function (o) { return h("option", { key: o }, o); }))),
      h("div", { className: "ent-field", style: { marginBottom: 0 } }, h("label", null, "Output type"), h("select", { className: "ent-select", value: out, onChange: function (e) { setOut(e.target.value); } }, ["PDF", "Email summary", "Shareable link"].map(function (o) { return h("option", { key: o }, o); }))));
  }
  function ReportSection(props) {
    var top = props.top, which = props.which, monitors = props.monitors;
    if (which === "summary") return h("p", { style: { fontSize: "14px", lineHeight: 1.6, color: "var(--ent-body)" } }, top[0] ? (top[0].summary || top[0].title) : "No data in the current window.");
    if (which === "insights") return h("ul", { style: { paddingLeft: "18px", lineHeight: 1.7, color: "var(--ent-body)" } }, top.slice(0, 4).map(function (a, i) { return h("li", { key: i }, (a.deeper_summary || a.summary || a.title || "").slice(0, 160)); }));
    if (which === "stories") return h("ol", { style: { paddingLeft: "18px", lineHeight: 1.8, color: "var(--ent-body)" } }, top.map(function (a, i) { return h("li", { key: i }, a.url ? h("a", { href: a.url, target: "_blank", rel: "noopener", style: { color: "var(--ent-accent-d)" } }, a.title) : a.title); }));
    if (which === "risks") return h("div", null, h("p", { style: { fontWeight: 600 } }, "Elevated"), h("ul", { style: { paddingLeft: "18px", color: "var(--ent-body)" } }, top.filter(function (a) { return sig(a) >= 3; }).slice(0, 4).map(function (a, i) { return h("li", { key: i }, a.title); })));
    if (which === "regions") { var c = topRegions(top); return h("div", { className: "ent-barlist" }, c.map(function (r, i) { return h("div", { key: i, className: "ent-barlist-row" }, h("div", { className: "l" }, h("span", null, r.name), h("span", { className: "v" }, r.count)), h("div", { className: "ent-bar" }, h("i", { style: { width: (r.count / c[0].count * 100) + "%" } }))); })); }
    var s = {}; top.forEach(function (a) { if (a.source) s[a.source] = (s[a.source] || 0) + 1; });
    return h("ul", { style: { paddingLeft: "18px", color: "var(--ent-body)", lineHeight: 1.7 } }, Object.keys(s).map(function (k, i) { return h("li", { key: i }, k + " (" + s[k] + ")"); }));
  }
  function escapeHtml(s) { return String(s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); }

  // ============================================================
  //  TEAM
  // ============================================================
  // ── Team page (public preview) ──────────────────────────────────────────
  // Enterprise is in PUBLIC PREVIEW: no sign-in / payment / team code required.
  // TODO: Protect Enterprise Team page with workspace admin access before launch.
  // TODO: Store hashed Enterprise team access codes and enforce seat limits before launch.
  // Demo team data is isolated in its own localStorage keys — NEVER mixed into
  // the auth/users table or public Globly data. Labelled as demo throughout.
  var TEAM_LSK = { members: "ent_demo_team_v1", invites: "ent_demo_invites_v1", code: "ent_demo_teamcode_v1" };
  var TEAM_SEAT_LIMIT = 12;
  var TEAM_DEFAULT_CODE = "G7mQ2xP9Aa4L";
  var TEAM_DEMO_MEMBERS = [
    { name: "Ayan Mohideen", email: "ayan@globlyresearch.com", role: "Team Admin", access: "Full Access", monitors: 14, joined: "2024-03-12", status: "Active" },
    { name: "Fatima Rahman", email: "fatima@globlyresearch.com", role: "Admin", access: "Full Access", monitors: 11, joined: "2024-04-03", status: "Active" },
    { name: "Yusuf Ahmed", email: "yusuf@globlyresearch.com", role: "Admin", access: "Full Access", monitors: 10, joined: "2024-04-20", status: "Active" },
    { name: "Omar Khan", email: "omar@globlyresearch.com", role: "Analyst", access: "Edit Access", monitors: 9, joined: "2024-05-18", status: "Active" },
    { name: "Priya Nair", email: "priya@globlyresearch.com", role: "Analyst", access: "Edit Access", monitors: 8, joined: "2024-05-05", status: "Active" },
    { name: "Leila Hassan", email: "leila@globlyresearch.com", role: "Analyst", access: "Edit Access", monitors: 7, joined: "2024-06-02", status: "Active" },
    { name: "Noah Bennett", email: "noah@globlyresearch.com", role: "Analyst", access: "Edit Access", monitors: 6, joined: "2024-05-28", status: "Active" },
    { name: "Daniel Park", email: "daniel@globlyresearch.com", role: "Viewer", access: "Read Only", monitors: 5, joined: "2024-06-15", status: "Active" },
    { name: "Sara Malik", email: "sara@globlyresearch.com", role: "Viewer", access: "Read Only", monitors: 4, joined: "2024-07-01", status: "Active" },
    { name: "Mei Chen", email: "mei@globlyresearch.com", role: "Viewer", access: "Read Only", monitors: 3, joined: "2024-06-22", status: "Active" },
    { name: "Tariq Khalid", email: "tariq@globlyresearch.com", role: "Guest", access: "Limited Access", monitors: 2, joined: "2024-07-08", status: "Pending" },
    { name: "Hana Ali", email: "hana@globlyresearch.com", role: "Guest", access: "Limited Access", monitors: 0, joined: "2024-07-08", status: "Pending" },
  ];
  var TEAM_DEMO_INVITES = [
    { name: "Ibrahim Joshi", email: "ibrahim@globlyresearch.com" },
    { name: "Maya Patel", email: "maya@globlyresearch.com" },
  ];
  var TEAM_ACTIVITY = [];
  var ROLE_PERMS = [
    ["Team Admin", ["Manage billing", "Manage team", "Regenerate access code", "Create/edit monitors", "View all reports"]],
    ["Admin", ["Manage monitors", "Manage sources", "Create reports", "Invite members"]],
    ["Analyst", ["Create monitors", "Review signals", "Build reports"]],
    ["Viewer", ["View briefings", "View reports", "Read signals"]],
    ["Guest", ["Limited read access"]],
  ];
  function teamRoleKind(r) { return r === "Team Admin" || r === "Admin" ? "pending" : r === "Analyst" ? "active" : r === "Viewer" ? "inactive" : "warning"; }
  function teamStatusKind(s) { return s === "Active" ? "active" : s === "Pending" ? "warning" : "blocked"; }
  function teamInitials(name) { return (name || "?").split(/\s+/).map(function (w) { return w[0]; }).slice(0, 2).join("").toUpperCase(); }
  function fmtJoined(s) { try { return new Date(s + "T00:00:00").toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); } catch (e) { return s; } }

  function TeamDonut(props) {
    var segs = props.segments, r = 52, C = 2 * Math.PI * r, off = 0;
    var total = segs.reduce(function (n, s) { return n + s.count; }, 0) || 1;
    var arcs = segs.map(function (s, i) {
      var len = (s.count / total) * C;
      var el = h("circle", { key: i, cx: 70, cy: 70, r: r, fill: "none", stroke: s.color, strokeWidth: 15, strokeDasharray: len.toFixed(2) + " " + (C - len).toFixed(2), strokeDashoffset: (-off).toFixed(2), transform: "rotate(-90 70 70)", strokeLinecap: "butt" });
      off += len; return el;
    });
    return h("div", { style: { display: "flex", justifyContent: "center", position: "relative", margin: "4px 0 14px" } },
      h("svg", { width: 140, height: 140, viewBox: "0 0 140 140", role: "img", "aria-label": props.total + " total members" },
        h("circle", { cx: 70, cy: 70, r: r, fill: "none", stroke: "var(--ent-border-2)", strokeWidth: 15 }), arcs),
      h("div", { style: { position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" } },
        h("div", { style: { fontFamily: "var(--ent-serif)", fontSize: 24, fontWeight: 700, lineHeight: 1 } }, props.total),
        h("div", { style: { fontSize: 11, color: "var(--ent-muted)", marginTop: 2 } }, "Total")));
  }

  function TeamPage(props) {
    var toast = props.toast, ws = props.ws;
    // Real workspace members (the current admin to start). Persist to isolated keys.
    var _members = useState(function () {
      var saved = lsGet(TEAM_LSK.members, null);
      if (saved) return saved;
      return (ws.members || []).map(function (m) {
        return { name: m.name, email: m.email, role: m.role,
          access: (m.role === "Team Admin" || m.role === "Admin") ? "Full Access" : m.role === "Analyst" ? "Edit Access" : "Read Only",
          monitors: 0, joined: fmtDate(m.joinedAt || Date.now()), status: m.status || "Active" };
      });
    }), members = _members[0], setMembers = _members[1];
    var _invites = useState(function () { return lsGet(TEAM_LSK.invites, null) || []; }), invites = _invites[0], setInvites = _invites[1];
    var _code = useState(function () { return lsGet(TEAM_LSK.code, null) || ws.code || genCode(); }), code = _code[0], setCode = _code[1];
    var _tab = useState("All Members"), tab = _tab[0], setTab = _tab[1];
    var _q = useState(""), q = _q[0], setQ = _q[1];
    var _rf = useState("All Roles"), rf = _rf[0], setRf = _rf[1];
    var _sf = useState("All Statuses"), sf = _sf[0], setSf = _sf[1];
    var _view = useState("list"), view = _view[0], setView = _view[1];
    var _menu = useState(null), menu = _menu[0], setMenu = _menu[1];
    var _invite = useState(false), inviteOpen = _invite[0], setInviteOpen = _invite[1];
    var _perms = useState(false), permsOpen = _perms[0], setPermsOpen = _perms[1];
    var _chRole = useState(null), chRole = _chRole[0], setChRole = _chRole[1];   // member being re-roled
    var _profile = useState(null), profile = _profile[0], setProfile = _profile[1]; // member drawer
    var _mob = useState(function () { return typeof window !== "undefined" && window.innerWidth < 760; }), mobile = _mob[0], setMobile = _mob[1];

    useEffect(function () {
      function onDoc() { setMenu(null); }
      function onResize() { setMobile(window.innerWidth < 760); }
      document.addEventListener("click", onDoc); window.addEventListener("resize", onResize);
      return function () { document.removeEventListener("click", onDoc); window.removeEventListener("resize", onResize); };
    }, []);

    function persistMembers(next) { setMembers(next); lsSet(TEAM_LSK.members, next); }
    function persistInvites(next) { setInvites(next); lsSet(TEAM_LSK.invites, next); }
    function saveCode(c) { setCode(c); lsSet(TEAM_LSK.code, c); }

    function changeRole(email, newRole) {
      var access = newRole === "Team Admin" || newRole === "Admin" ? "Full Access" : newRole === "Analyst" ? "Edit Access" : newRole === "Viewer" ? "Read Only" : "Limited Access";
      persistMembers(members.map(function (m) { return m.email === email ? Object.assign({}, m, { role: newRole, access: access }) : m; }));
      setChRole(null); toast("Role updated to " + newRole);
    }
    function removeMember(m) {
      if (typeof window !== "undefined" && window.confirm && !window.confirm("Remove " + m.name + " from the team? This cannot be undone.")) return;
      persistMembers(members.filter(function (x) { return x.email !== m.email; })); toast("Member removed");
    }
    function deactivate(m) {
      persistMembers(members.map(function (x) { return x.email === m.email ? Object.assign({}, x, { status: "Removed" }) : x; })); toast("Access deactivated");
    }
    function sendInvite(email, name) {
      persistInvites(invites.concat([{ name: name || email.split("@")[0], email: email }]));
      setInviteOpen(false); toast("Invite created. Email delivery will be connected before launch.");
    }
    function regenCode() { saveCode(genCode()); toast("New team code generated. The old code no longer works."); }

    // derived KPIs (from the member list)
    var total = members.length;
    var activeN = members.filter(function (m) { return m.status === "Active"; }).length;
    var adminN = members.filter(function (m) { return m.role === "Team Admin" || m.role === "Admin"; }).length;
    var analystN = members.filter(function (m) { return m.role === "Analyst"; }).length;
    var viewerN = members.filter(function (m) { return m.role === "Viewer"; }).length;
    var guestN = members.filter(function (m) { return m.role === "Guest"; }).length;
    var pct = function (n) { return total ? Math.round(n / total * 100) : 0; };
    var seatsUsed = activeN;

    // tab + filters
    var byTab = members.filter(function (m) {
      if (tab === "Admins") return m.role === "Team Admin" || m.role === "Admin";
      if (tab === "Guests") return m.role === "Guest";
      return true;
    });
    var filtered = byTab.filter(function (m) {
      if (rf !== "All Roles" && m.role !== rf) return false;
      if (sf !== "All Statuses" && m.status !== sf) return false;
      if (q) {
        var hay = (m.name + " " + m.email + " " + m.role + " " + m.status).toLowerCase();
        if (hay.indexOf(q.toLowerCase()) === -1) return false;
      }
      return true;
    });

    function memberMenu(m) {
      return h("div", { style: { position: "relative", display: "inline-block" }, onClick: function (e) { e.stopPropagation(); } },
        h("button", { className: "ent-menu-btn", "aria-label": "Member actions", "aria-haspopup": "true", "aria-expanded": menu === m.email, onClick: function () { setMenu(menu === m.email ? null : m.email); } }, h(Ico, { name: "dots", size: 16 })),
        menu === m.email ? h("div", { className: "ent-tb-menu-pop", style: { top: "30px", right: 0, minWidth: "184px" } },
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setProfile(m); } }, h(Ico, { name: "eye", size: 15 }), "View profile"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); setChRole(m); } }, h(Ico, { name: "pencil", size: 15 }), "Change role"),
          h("button", { className: "ent-tb-menu-item", onClick: function () { setMenu(null); deactivate(m); } }, h(Ico, { name: "pause", size: 15 }), "Deactivate access"),
          h("button", { className: "ent-tb-menu-item", style: { color: "var(--ent-hi)" }, onClick: function () { setMenu(null); removeMember(m); } }, h(Ico, { name: "trash", size: 15 }), "Remove member")) : null);
    }
    function avatar(m, size) {
      var s = size || 34;
      return h("div", { "aria-hidden": "true", style: { flex: "none", width: s, height: s, borderRadius: "50%", background: "var(--ent-accent-t)", color: "var(--ent-accent-d)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: s * 0.38 } }, teamInitials(m.name));
    }
    function roleBadge(m) { return h("span", { className: "ent-badge ent-badge--" + teamRoleKind(m.role) }, m.role); }
    function statusBadge(m) { return h("span", { className: "ent-badge ent-badge--" + teamStatusKind(m.status) }, m.status); }
    function monitorsCell(m) { return m.monitors ? m.monitors : "—"; }

    // table (desktop list view)
    var table = h("div", { className: "ent-table-wrap" }, h("table", { className: "ent-table" },
      h("thead", null, h("tr", null, ["Member", "Role", "Access", "Monitors", "Joined", "Status", ""].map(function (c, i) { return h("th", { key: i }, c); }))),
      h("tbody", null, filtered.map(function (m) {
        return h("tr", { key: m.email, style: { opacity: m.status === "Removed" ? 0.55 : 1 } },
          h("td", null, h("div", { style: { display: "flex", alignItems: "center", gap: 11 } }, avatar(m), h("div", null, h("div", { className: "ent-td-name" }, m.name), h("div", { className: "ent-td-domain" }, m.email)))),
          h("td", null, roleBadge(m)),
          h("td", null, m.access),
          h("td", null, monitorsCell(m)),
          h("td", null, fmtJoined(m.joined)),
          h("td", null, statusBadge(m)),
          h("td", { style: { textAlign: "right" } }, memberMenu(m)));
      }))));

    // cards (grid / mobile)
    var cards = h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))", gap: 12 } },
      filtered.map(function (m) {
        return h("div", { key: m.email, className: "ent-card", style: { padding: 16, display: "flex", flexDirection: "column", gap: 10, opacity: m.status === "Removed" ? 0.55 : 1 } },
          h("div", { style: { display: "flex", alignItems: "center", gap: 11 } }, avatar(m, 40),
            h("div", { style: { flex: 1, minWidth: 0 } }, h("div", { className: "ent-td-name" }, m.name), h("div", { className: "ent-td-domain", style: { overflow: "hidden", textOverflow: "ellipsis" } }, m.email)),
            memberMenu(m)),
          h("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" } }, roleBadge(m), statusBadge(m)),
          h("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 12.5, color: "var(--ent-muted)" } }, h("span", null, "Access"), h("span", { style: { color: "var(--ent-ink)", fontWeight: 600 } }, m.access)),
          h("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 12.5, color: "var(--ent-muted)" } }, h("span", null, "Monitors"), h("span", { style: { color: "var(--ent-ink)", fontWeight: 600 } }, monitorsCell(m))),
          h("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 12.5, color: "var(--ent-muted)" } }, h("span", null, "Joined"), h("span", { style: { color: "var(--ent-ink)", fontWeight: 600 } }, fmtJoined(m.joined))));
      }));

    var effView = mobile ? "grid" : view;

    var main = h("div", { className: "ent-col" },
      h(PageHead, {
        title: "Team", sub: "Manage your team members, roles and permissions.",
        actions: h("button", { className: "ent-btn ent-btn--primary", onClick: function () { setInviteOpen(true); } }, h(Ico, { name: "plus", size: 15 }), "Invite Member"),
      }),
      h("div", { className: "ent-kpis", style: { marginBottom: "18px" } },
        h(KPI, { label: "Total members", value: total, icon: "team", delta: "↑ 2 new this month", trend: "up" }),
        h(KPI, { label: "Active members", value: activeN, icon: "check", delta: pct(activeN) + "% of total", trend: "flat" }),
        h(KPI, { label: "Admins", value: adminN, icon: "shield", delta: pct(adminN) + "% of total", trend: "flat" }),
        h(KPI, { label: "Pending invites", value: invites.length, icon: "bell", delta: "Invites awaiting", trend: "flat" })),
      // tabs
      h("div", { className: "ent-tabs" }, ["All Members", "Admins", "Guests"].map(function (t) {
        return h("button", { key: t, className: "ent-tab" + (tab === t ? " is-active" : ""), onClick: function () { setTab(t); } }, t);
      })),
      // filters
      h("div", { className: "ent-filters" },
        h("div", { className: "ent-search-box" }, h(Ico, { name: "search", size: 15 }), h("input", { placeholder: "Search members…", value: q, onChange: function (e) { setQ(e.target.value); }, "aria-label": "Search members" })),
        h("select", { className: "ent-select", value: rf, "aria-label": "Filter by role", onChange: function (e) { setRf(e.target.value); } }, ["All Roles", "Team Admin", "Admin", "Analyst", "Viewer", "Guest"].map(function (p) { return h("option", { key: p }, p); })),
        h("select", { className: "ent-select", value: sf, "aria-label": "Filter by status", onChange: function (e) { setSf(e.target.value); } }, ["All Statuses", "Active", "Pending", "Removed"].map(function (p) { return h("option", { key: p }, p); })),
        h("div", { style: { display: "inline-flex", border: "1px solid var(--ent-border)", borderRadius: "var(--ent-radius-s)", overflow: "hidden", marginLeft: "auto" } },
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", "aria-label": "List view", "aria-pressed": view === "list", style: { borderRadius: 0, background: view === "list" ? "var(--ent-accent-t)" : "transparent", color: view === "list" ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setView("list"); } }, h(Ico, { name: "menu", size: 15 })),
          h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", "aria-label": "Grid view", "aria-pressed": view === "grid", style: { borderRadius: 0, background: view === "grid" ? "var(--ent-accent-t)" : "transparent", color: view === "grid" ? "var(--ent-accent-d)" : "var(--ent-muted)" }, onClick: function () { setView("grid"); } }, h(Ico, { name: "layers", size: 15 })))),
      filtered.length === 0 ? h(EmptyState, { icon: "team", text: "No members match your filters." }) : (effView === "grid" ? cards : table));

    var donutSegs = [
      { label: "Admins", count: adminN, color: "#5E6AD2" },
      { label: "Analysts", count: analystN, color: "#4F8A54" },
      { label: "Viewers", count: viewerN, color: "#B5701E" },
      { label: "Guests", count: guestN, color: "#A79E92" },
    ];
    var rail = h("div", { className: "ent-rail" },
      // Team Overview
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Team overview"),
        h(TeamDonut, { segments: donutSegs, total: total }),
        donutSegs.map(function (s, i) {
          return h("div", { key: i, className: "ent-rail-row" },
            h("span", { className: "l" }, h("span", { style: { width: 9, height: 9, borderRadius: "50%", background: s.color, display: "inline-block" } }), s.label),
            h("span", { className: "v" }, s.count + " · " + pct(s.count) + "%"));
        }),
        h("button", { className: "ent-btn ent-btn--sm", style: { width: "100%", justifyContent: "center", marginTop: 12 }, onClick: function () { setPermsOpen(true); } }, "View role permissions")),
      // Activity Feed
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Activity feed"),
        TEAM_ACTIVITY.map(function (a, i) {
          return h("div", { key: i, style: { display: "flex", gap: 10, padding: "8px 0", borderBottom: i < TEAM_ACTIVITY.length - 1 ? "1px solid var(--ent-border-2)" : "0" } },
            h("span", { style: { flex: "none", width: 7, height: 7, borderRadius: "50%", background: "var(--ent-accent)", marginTop: 5 } }),
            h("div", null, h("div", { style: { fontSize: 12.5, color: "var(--ent-body)", lineHeight: 1.4 } }, a.text), h("div", { style: { fontSize: 11, color: "var(--ent-faint)", marginTop: 2 } }, a.when)));
        }),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: 8 }, onClick: function () { toast("Full activity log is coming soon"); } }, "View all activity")),
      // Pending Invites
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Pending invites"),
        invites.length === 0 ? h("div", { style: { fontSize: 12.5, color: "var(--ent-muted)" } }, "No pending invites.")
          : invites.map(function (v, i) {
              return h("div", { key: i, style: { display: "flex", alignItems: "center", gap: 10, padding: "8px 0", borderBottom: i < invites.length - 1 ? "1px solid var(--ent-border-2)" : "0" } },
                avatar(v, 30),
                h("div", { style: { flex: 1, minWidth: 0 } }, h("div", { style: { fontSize: 13, fontWeight: 600 } }, v.name), h("div", { className: "ent-td-domain", style: { overflow: "hidden", textOverflow: "ellipsis" } }, v.email)),
                h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { toast("Invite resend is coming soon."); } }, "Resend"));
            }),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: 8 }, onClick: function () { toast("All invites view is coming soon"); } }, "View all invites")),
      // Team access code
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Team access code"),
        h("p", { style: { fontSize: 12.5, color: "var(--ent-muted)", marginBottom: 10, lineHeight: 1.5 } }, "Members with a Globly account can join this workspace using your organisation code while seats are available."),
        h("div", { className: "ent-code-chip", style: { width: "100%", justifyContent: "space-between" } }, code,
          h("button", { className: "ent-menu-btn", "aria-label": "Copy code", onClick: function () { copyText(code); toast("Team code copied"); } }, h(Ico, { name: "copy", size: 14 }))),
        h("div", { className: "ent-rail-row", style: { marginTop: 10 } }, h("span", { className: "l" }, "Seats used"), h("span", { className: "v" }, seatsUsed + " / " + TEAM_SEAT_LIMIT + " seats used")),
        h("div", { className: "ent-bar", style: { margin: "8px 0" } }, h("i", { style: { width: Math.min(100, seatsUsed / TEAM_SEAT_LIMIT * 100) + "%" } })),
        h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "Status"), h(Badge, { kind: "active" }, "Active")),
        h("div", { style: { display: "flex", gap: 8, marginTop: 12 } },
          h("button", { className: "ent-btn ent-btn--sm", style: { flex: 1, justifyContent: "center" }, onClick: function () { copyText(code); toast("Team code copied"); } }, h(Ico, { name: "copy", size: 14 }), "Copy code"),
          h("button", { className: "ent-btn ent-btn--sm", style: { flex: 1, justifyContent: "center" }, onClick: regenCode }, "Regenerate")),
        h("p", { style: { fontSize: 11, color: "var(--ent-med)", marginTop: 10 } }, "Regenerating this code will stop the old code from working."),
        h("div", { className: "ent-demo-note", style: { marginTop: 10 } }, "Demo data")));

    return [R.cloneElement(main, { key: "main" }), R.cloneElement(rail, { key: "rail" }),
      inviteOpen ? h(InviteMemberModal, { key: "invite", onClose: function () { setInviteOpen(false); }, onSend: sendInvite }) : null,
      permsOpen ? h(RolePermsModal, { key: "perms", onClose: function () { setPermsOpen(false); } }) : null,
      chRole ? h(ChangeRoleModal, { key: "chrole", member: chRole, onClose: function () { setChRole(null); }, onSave: changeRole }) : null,
      profile ? h(MemberProfileDrawer, { key: "profile", member: profile, onClose: function () { setProfile(null); } }) : null];
  }

  function InviteMemberModal(props) {
    var _e = useState(""), email = _e[0], setEmail = _e[1];
    var _r = useState("Analyst"), role = _r[0], setRole = _r[1];
    var _a = useState("Edit Access"), access = _a[0], setAccess = _a[1];
    var _m = useState(""), msg = _m[0], setMsg = _m[1];
    var valid = /.+@.+\..+/.test(email.trim());
    return h(Modal, { title: "Invite member", onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"),
        h("button", { key: "s", className: "ent-btn ent-btn--primary", disabled: !valid, onClick: function () { props.onSend(email.trim(), ""); } }, "Send invite")] },
      h("div", { className: "ent-field" }, h("label", null, "Email address"), h("input", { className: "ent-input", type: "email", placeholder: "name@organisation.com", value: email, onChange: function (e) { setEmail(e.target.value); } })),
      h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
        h("div", { className: "ent-field", style: { flex: 1, minWidth: 160 } }, h("label", null, "Role"), h("select", { className: "ent-select", value: role, onChange: function (e) { setRole(e.target.value); } }, ["Admin", "Analyst", "Viewer", "Guest"].map(function (r) { return h("option", { key: r }, r); }))),
        h("div", { className: "ent-field", style: { flex: 1, minWidth: 160 } }, h("label", null, "Access level"), h("select", { className: "ent-select", value: access, onChange: function (e) { setAccess(e.target.value); } }, ["Full Access", "Edit Access", "Read Only", "Limited Access"].map(function (a) { return h("option", { key: a }, a); })))),
      h("div", { className: "ent-field" }, h("label", null, "Optional message"), h("textarea", { className: "ent-textarea", rows: 3, style: { width: "100%", resize: "vertical" }, placeholder: "Add a short note to your invite…", value: msg, onChange: function (e) { setMsg(e.target.value); } })),
      h("p", { style: { fontSize: 11.5, color: "var(--ent-muted)", margin: 0 } }, "Email delivery will be connected before launch — this creates a pending invite in the preview."));
  }

  function RolePermsModal(props) {
    return h(Modal, { title: "Role permissions", wide: true, onClose: props.onClose,
      foot: [h("button", { key: "d", className: "ent-btn ent-btn--primary", onClick: props.onClose }, "Done")] },
      h("div", { style: { display: "flex", flexDirection: "column", gap: 14 } },
        ROLE_PERMS.map(function (rp, i) {
          return h("div", { key: i, style: { borderBottom: i < ROLE_PERMS.length - 1 ? "1px solid var(--ent-border-2)" : "0", paddingBottom: 12 } },
            h("div", { style: { marginBottom: 8 } }, h("span", { className: "ent-badge ent-badge--" + teamRoleKind(rp[0]) }, rp[0])),
            h("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 } }, rp[1].map(function (p, j) {
              return h("span", { key: j, style: { display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--ent-body)" } }, h(Ico, { name: "check", size: 14 }), p);
            })));
        })));
  }

  function ChangeRoleModal(props) {
    var m = props.member;
    var _r = useState(m.role), role = _r[0], setRole = _r[1];
    return h(Modal, { title: "Change role — " + m.name, onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"),
        h("button", { key: "s", className: "ent-btn ent-btn--primary", onClick: function () { props.onSave(m.email, role); } }, "Save role")] },
      h("div", { className: "ent-field" }, h("label", null, "Role"), h("select", { className: "ent-select", style: { width: "100%" }, value: role, onChange: function (e) { setRole(e.target.value); } }, ["Team Admin", "Admin", "Analyst", "Viewer", "Guest"].map(function (r) { return h("option", { key: r }, r); }))),
      h("p", { style: { fontSize: 12.5, color: "var(--ent-muted)", margin: 0 } }, "Access level updates automatically to match the selected role."));
  }

  function MemberProfileDrawer(props) {
    var m = props.member;
    return h("div", { className: "ent-modal-backdrop", onClick: props.onClose, style: { justifyContent: "flex-end" } },
      h("div", { onClick: function (e) { e.stopPropagation(); }, style: { background: "var(--ent-surface)", height: "100%", width: "min(380px, 92vw)", boxShadow: "-8px 0 40px rgba(26,23,18,0.18)", padding: 24, overflowY: "auto" } },
        h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18 } },
          h("div", { className: "ent-rail-title", style: { margin: 0 } }, "Member profile"),
          h("button", { className: "ent-modal-close", onClick: props.onClose }, "×")),
        h("div", { style: { display: "flex", alignItems: "center", gap: 12, marginBottom: 18 } },
          h("div", { "aria-hidden": "true", style: { width: 52, height: 52, borderRadius: "50%", background: "var(--ent-accent-t)", color: "var(--ent-accent-d)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 18 } }, teamInitials(m.name)),
          h("div", null, h("div", { style: { fontSize: 16, fontWeight: 700 } }, m.name), h("div", { className: "ent-td-domain" }, m.email))),
        [["Role", m.role], ["Access", m.access], ["Monitors", m.monitors || "—"], ["Joined", fmtJoined(m.joined)], ["Status", m.status]].map(function (r, i) {
          return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, r[0]), h("span", { className: "v" }, r[1]));
        }),
        h("div", { className: "ent-demo-note", style: { marginTop: 16 } }, "Demo profile")));
  }

  // ============================================================
  //  BILLING
  // ============================================================
  function BillingPage(props) {
    var ws = props.ws, role = props.role, toast = props.toast;
    var isAdmin = role === "Team Admin" || role === "Admin";
    var monitors = Store.monitors(ws.id);
    var reportCount = Store.reports(ws.id).length;
    var main = h("div", { className: "ent-col" },
      h(PageHead, { title: "Billing", sub: "Your Mira Enterprise subscription, usage, and invoices." }),
      h("div", { className: "ent-kpis", style: { marginBottom: "18px" } },
        h(KPI, { label: "Current plan", value: "Starter", icon: "billing", delta: "$99 / month", trend: "flat" }),
        h(KPI, { label: "Billing status", value: "Not connected", icon: "clock", delta: "Connect Stripe to activate", trend: "flat" }),
        h(KPI, { label: "Monitors used", value: monitors.length + " / 5", icon: "monitor", delta: "This workspace", trend: "flat" }),
        h(KPI, { label: "Team seats", value: (ws.members || []).length + " / " + ws.seatsLimit, icon: "team", delta: "In use", trend: "flat" })),
      h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("h3", null, "Mira Enterprise Starter"),
          h("div", { className: "ent-card-hd-actions" }, h("span", { className: "ent-pill ent-pill--dot" }, "Not connected"))),
        h("div", { className: "ent-card-pad", style: { display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: "16px" } },
          h("div", null,
            h("div", { style: { fontFamily: "Georgia,serif", fontSize: "28px", fontWeight: 600 } }, "$99", h("span", { style: { fontSize: "14px", color: "var(--ent-muted)", fontWeight: 400 } }, " / month per organisation")),
            h("div", { style: { fontSize: "13px", color: "var(--ent-muted)", marginTop: "4px" } }, "Daily team briefing · up to 5 monitors · 5 regions · source-grounded Mira Q&A · weekly report · team workspace")),
          isAdmin
            ? h("button", { className: "ent-btn ent-btn--primary", onClick: function () { toast("Stripe billing connection is coming soon"); } }, "Connect billing")
            : h("span", { style: { fontSize: "12.5px", color: "var(--ent-muted)" } }, "Only admins can manage the plan"))),
      h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("h3", null, "Usage this month")),
        h("div", { className: "ent-card-pad ent-barlist" },
          usageRow("Monitors", monitors.length, 5),
          usageRow("Regions", (function () { var s = {}; monitors.forEach(function (m) { (m.regions || []).forEach(function (r) { s[r] = 1; }); }); return Object.keys(s).length; })(), 5),
          usageRow("Team seats", (ws.members || []).length, ws.seatsLimit),
          usageRow("Weekly reports", reportCount, 4))),
      h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("h3", null, "Invoices")),
        h("div", { className: "ent-table-wrap", style: { border: 0 } }, h("table", { className: "ent-table" },
          h("thead", null, h("tr", null, ["Date", "Description", "Amount", "Status", ""].map(function (c) { return h("th", { key: c }, c); }))),
          h("tbody", null, h("tr", null, h("td", { colSpan: 5, style: { textAlign: "center", padding: "26px", color: "var(--ent-muted)", fontSize: "13px" } }, "No invoices yet. Invoices appear here once billing is connected.")))))));

    var rail = h("div", { className: "ent-rail" },
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Payment method"),
        h("div", { style: { fontSize: "13.5px", color: "var(--ent-muted)" } }, "No payment method on file."),
        h("div", { style: { fontSize: "12.5px", color: "var(--ent-muted)", marginTop: "3px" } }, "Billing is not connected yet."),
        h("button", { className: "ent-btn ent-btn--primary ent-btn--sm", style: { marginTop: "10px" }, onClick: function () { toast("Stripe billing connection is coming soon"); } }, "Connect billing")),
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Plan features"),
        ["Daily team briefing", "Up to 5 monitors", "Up to 5 regions", "Source-grounded Mira Q&A", "Weekly report", "Team workspace"].map(function (f, i) {
          return h("div", { key: i, className: "ent-rail-row" }, h("span", { className: "l" }, h(Ico, { name: "check", size: 14 }), f)); })));

    return [main, rail];
  }
  function usageRow(label, val, max) {
    return h("div", { className: "ent-barlist-row" }, h("div", { className: "l" }, h("span", null, label), h("span", { className: "v" }, val + " / " + max)), h("div", { className: "ent-bar" }, h("i", { style: { width: Math.min(100, val / max * 100) + "%" } })));
  }

  // ============================================================
  //  SETTINGS
  // ============================================================
  // ── Settings (public preview) ───────────────────────────────────────────
  // Enterprise is in PUBLIC PREVIEW: no sign-in / payment / team code required.
  // TODO: Protect Enterprise settings with workspace admin access before launch.
  // TODO: Persist Enterprise workspace settings to database before launch.
  // TODO: Store hashed Enterprise team access codes and enforce seat limits before launch.
  // Demo settings persist to an isolated localStorage key — never real user/auth data.
  var SETTINGS_LSK = "ent_demo_settings_v1";
  var SETTINGS_DEFAULTS = {
    fullName: "", email: "", role: "Team Admin",
    wsName: "", wsId: "", industry: "", teamSize: "",
    language: "English (UK)", timezone: "", dateFormat: "",
    briefTime: "", reportType: "Weekly Intelligence", theme: "System",
    topics: [], regions: [], reportFreq: "Weekly",
    notif: { daily: false, weekly: false, signals: false, team: false, product: false },
  };
  var PLAN_FEATURES = ["Daily team briefing", "Up to 5 monitors", "Source-grounded Mira answers", "Weekly intelligence report", "Team workspace", "Basic source library", "Early access support"];
  var ACCOUNT_ACTIVITY = [];
  var USAGE_ROWS = [["Reports generated", 0, 50], ["Monitors used", 0, 5], ["Sources tracked", 0, 100], ["Mira questions", 0, 500]];

  function EntToggle(props) {
    return h("button", { role: "switch", "aria-checked": !!props.on, "aria-label": props.label, onClick: props.onClick,
      style: { flex: "none", width: 38, height: 22, borderRadius: 11, border: 0, padding: 0, background: props.on ? "var(--ent-accent)" : "var(--ent-border)", position: "relative", cursor: "pointer", transition: "background .15s" } },
      h("span", { style: { position: "absolute", top: 2, left: props.on ? 18 : 2, width: 18, height: 18, borderRadius: "50%", background: "#fff", transition: "left .15s", boxShadow: "0 1px 2px rgba(0,0,0,.25)" } }));
  }

  function SettingsPage(props) {
    var toast = props.toast;
    var _tab = useState("account"), tab = _tab[0], setTab = _tab[1];
    var _s = useState(function () {
      var base = Object.assign({}, SETTINGS_DEFAULTS, {
        fullName: (props.session && props.session.name) || "",
        email: (props.session && props.session.email) || "",
        wsName: (props.ws && props.ws.name) || "",
      });
      return Object.assign(base, lsGet(SETTINGS_LSK, {}));
    }), s = _s[0], setS = _s[1];
    var _code = useState(function () { return lsGet(TEAM_LSK.code, null) || (props.ws && props.ws.code) || genCode(); }), code = _code[0], setCode = _code[1];
    var _modal = useState(null), modal = _modal[0], setModal = _modal[1]; // 'profile' | 'workspace' | 'delete' | 'plan' | 'usage'

    function persist(next) { setS(next); lsSet(SETTINGS_LSK, next); }
    function setField(k, v) { persist(Object.assign({}, s, (function () { var o = {}; o[k] = v; return o; })())); }
    function setNotif(k) { var n = Object.assign({}, s.notif); n[k] = !n[k]; setField("notif", n); }
    function savePrefs() { toast("Preferences saved."); }
    function regenCode() { var c = genCode(); setCode(c); lsSet(TEAM_LSK.code, c); toast("New team code generated. The old code no longer works."); }
    function toggleArr(k, v) { var a = s[k] || []; setField(k, a.indexOf(v) === -1 ? a.concat([v]) : a.filter(function (x) { return x !== v; })); }

    var TABS = [["account", "Account"], ["preferences", "Preferences"], ["notifications", "Notifications"], ["security", "Security"], ["integrations", "Integrations"], ["api", "API"], ["workspace", "Workspace"]];

    // shared bits
    function card(title, sub, children, actions) {
      return h("div", { className: "ent-card" },
        h("div", { className: "ent-card-hd" }, h("div", null, h("h3", null, title), sub ? h("div", { className: "ent-card-hd-sub" }, sub) : null), actions ? h("div", { className: "ent-card-hd-actions" }, actions) : null),
        h("div", { className: "ent-card-pad" }, children));
    }
    function readRow(label, value) {
      return h("div", { style: { display: "flex", justifyContent: "space-between", gap: 12, padding: "10px 0", borderBottom: "1px solid var(--ent-border-2)" } },
        h("span", { style: { fontSize: 13, color: "var(--ent-muted)" } }, label),
        h("span", { style: { fontSize: 13.5, fontWeight: 600, color: "var(--ent-ink)", textAlign: "right" } }, value));
    }
    function fieldSelect(label, k, options) {
      return h("div", { className: "ent-field" }, h("label", null, label), h("select", { className: "ent-select", style: { width: "100%" }, value: s[k], onChange: function (e) { setField(k, e.target.value); } }, options.map(function (o) { return h("option", { key: o }, o); })));
    }
    function themeSelector() {
      return h("div", { className: "ent-field" }, h("label", null, "Theme"),
        h("div", { style: { display: "flex", gap: 8 } }, ["Light", "Dark", "System"].map(function (t) {
          var on = s.theme === t;
          return h("button", { key: t, className: "ent-btn ent-btn--sm", "aria-pressed": on, style: { flex: 1, justifyContent: "center", background: on ? "var(--ent-accent-t)" : "var(--ent-surface)", borderColor: on ? "var(--ent-accent)" : "var(--ent-border)", color: on ? "var(--ent-accent-d)" : "var(--ent-body)" }, onClick: function () { setField("theme", t); } }, t);
        })));
    }
    function checkRow(k, v) { return h("button", { key: v, className: "ent-check" + ((s[k] || []).indexOf(v) !== -1 ? " is-on" : ""), onClick: function () { toggleArr(k, v); } }, v); }

    var body;
    if (tab === "account") {
      body = h("div", { style: { display: "flex", flexDirection: "column", gap: 16 } },
        // Profile Information
        card("Profile Information", "Update your personal information and profile details.",
          h("div", { style: { display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" } },
            h("div", { style: { position: "relative", flex: "none" } },
              h("div", { "aria-hidden": "true", style: { width: 60, height: 60, borderRadius: "50%", background: "var(--ent-accent-t)", color: "var(--ent-accent-d)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 20 } }, teamInitials(s.fullName)),
              h("button", { "aria-label": "Change photo", onClick: function () { setModal("profile"); }, style: { position: "absolute", right: -2, bottom: -2, width: 24, height: 24, borderRadius: "50%", background: "var(--ent-accent)", color: "#fff", border: "2px solid var(--ent-surface)", display: "grid", placeItems: "center", cursor: "pointer" } }, h(Ico, { name: "pencil", size: 12 }))),
            h("div", { style: { flex: "1 1 260px", minWidth: 220 } }, readRow("Full Name", s.fullName), readRow("Email Address", s.email), h("div", { style: { display: "flex", justifyContent: "space-between", padding: "10px 0" } }, h("span", { style: { fontSize: 13, color: "var(--ent-muted)" } }, "Role"), h(Badge, { kind: "pending" }, s.role)))),
          h("button", { className: "ent-btn", onClick: function () { setModal("profile"); } }, h(Ico, { name: "pencil", size: 14 }), "Edit Profile")),
        // Company / Workspace
        card("Company / Workspace", "Manage your organisation and workspace details.",
          h("div", null, readRow("Workspace Name", s.wsName), readRow("Workspace ID", s.wsId), readRow("Industry", s.industry), readRow("Team Size", s.teamSize)),
          h("button", { className: "ent-btn", onClick: function () { setModal("workspace"); } }, h(Ico, { name: "pencil", size: 14 }), "Edit Workspace")),
        // Preferences
        card("Preferences", "Customise your experience and default settings.",
          h("div", null,
            h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
              h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Language", "language", ["English (UK)", "English (US)", "Français", "العربية", "हिन्दी"])),
              h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Timezone", "timezone", ["UTC+00:00 London", "UTC+04:00 Dubai", "UTC+05:30 India", "UTC-05:00 New York", "UTC+03:00 Nairobi"]))),
            h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
              h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Date Format", "dateFormat", ["6 July 2026", "July 6, 2026", "06/07/2026", "2026-07-06"])),
              h("div", { style: { flex: 1, minWidth: 180 } }, h("div", { className: "ent-field" }, h("label", null, "Default Briefing Time"), h("input", { className: "ent-input", type: "time", style: { width: "100%" }, value: s.briefTime, onChange: function (e) { setField("briefTime", e.target.value); } })))),
            fieldSelect("Default Report Type", "reportType", ["Weekly Intelligence", "Daily Digest", "Monthly Outlook"]),
            themeSelector(),
            h("button", { className: "ent-btn ent-btn--primary", style: { marginTop: 4 }, onClick: savePrefs }, "Save Preferences"))),
        // Danger Zone
        h("div", { className: "ent-card", style: { borderColor: "var(--ent-hi-t)" } },
          h("div", { className: "ent-card-hd" }, h("div", null, h("h3", { style: { color: "var(--ent-hi)" } }, "Danger Zone"), h("div", { className: "ent-card-hd-sub" }, "Irreversible and destructive actions for your workspace."))),
          h("div", { className: "ent-card-pad", style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 14, flexWrap: "wrap" } },
            h("div", null, h("div", { style: { fontSize: 14, fontWeight: 700 } }, "Delete Workspace"), h("div", { style: { fontSize: 12.5, color: "var(--ent-muted)", maxWidth: 420 } }, "Permanently delete your workspace and all associated data. This action cannot be undone.")),
            h("button", { className: "ent-btn", style: { borderColor: "var(--ent-hi)", color: "var(--ent-hi)" }, onClick: function () { setModal("delete"); } }, "Delete Workspace"))));
    } else if (tab === "preferences") {
      body = card("Preferences", "Defaults for briefings, reports and display.",
        h("div", null,
          h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
            h("div", { style: { flex: 1, minWidth: 180 } }, h("div", { className: "ent-field" }, h("label", null, "Default briefing time"), h("input", { className: "ent-input", type: "time", style: { width: "100%" }, value: s.briefTime, onChange: function (e) { setField("briefTime", e.target.value); } }))),
            h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Report frequency", "reportFreq", ["Daily", "Weekly", "Monthly"]))),
          h("div", { className: "ent-field" }, h("label", null, "Default topics"), h("div", { className: "ent-checks" }, Object.keys(TOPIC_KW).map(function (t) { return checkRow("topics", t); }))),
          h("div", { className: "ent-field" }, h("label", null, "Default regions"), h("div", { className: "ent-checks" }, Object.keys(REGION_KW).map(function (r) { return checkRow("regions", r); }))),
          h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
            h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Language", "language", ["English (UK)", "English (US)", "Français", "العربية", "हिन्दी"])),
            h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Timezone", "timezone", ["UTC+00:00 London", "UTC+04:00 Dubai", "UTC+05:30 India", "UTC-05:00 New York", "UTC+03:00 Nairobi"]))),
          themeSelector(),
          h("button", { className: "ent-btn ent-btn--primary", onClick: savePrefs }, "Save preferences")));
    } else if (tab === "notifications") {
      var NOTIFS = [["daily", "Daily briefing email", "Your team brief, every morning."], ["weekly", "Weekly report email", "A decision-ready summary each week."], ["signals", "High-priority signal alerts", "Get notified when something urgent is detected."], ["team", "Team activity alerts", "Member joins, role changes and invites."], ["product", "Product update emails", "New features and improvements."]];
      body = card("Notifications", "Choose what Mira emails your team.",
        h("div", null, NOTIFS.map(function (n, i) {
          return h("div", { key: n[0], style: { display: "flex", alignItems: "center", gap: 12, padding: "12px 0", borderBottom: i < NOTIFS.length - 1 ? "1px solid var(--ent-border-2)" : "0" } },
            h("div", { style: { flex: 1 } }, h("div", { style: { fontSize: 13.5, fontWeight: 600 } }, n[1]), h("div", { style: { fontSize: 12, color: "var(--ent-muted)" } }, n[2])),
            h(EntToggle, { on: s.notif[n[0]], label: n[1], onClick: function () { setNotif(n[0]); } }));
        })));
    } else if (tab === "security") {
      body = h("div", { style: { display: "flex", flexDirection: "column", gap: 16 } },
        card("Password", "Manage how you sign in.",
          h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, flexWrap: "wrap" } },
            h("div", { style: { fontSize: 13, color: "var(--ent-muted)" } }, "Your password is managed through your Globly account."),
            h("button", { className: "ent-btn", onClick: function () { toast("Manage your password from your Globly account"); } }, "Change password"))),
        card("Two-factor authentication", "Add an extra layer of security.",
          h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } }, h("span", { style: { fontSize: 13, color: "var(--ent-muted)" } }, "Protect your workspace with 2FA."), h("span", { className: "ent-soon" }, "Coming soon"))),
        card("Active sessions", "Devices currently signed in.",
          h("div", null,
            h("div", { style: { display: "flex", justifyContent: "space-between", padding: "8px 0", borderBottom: "1px solid var(--ent-border-2)" } }, h("span", { style: { fontSize: 13 } }, "This browser · Dubai, UAE"), h(Badge, { kind: "active" }, "Current")),
            h("div", { style: { display: "flex", justifyContent: "space-between", padding: "8px 0" } }, h("span", { style: { fontSize: 13, color: "var(--ent-muted)" } }, "Safari · iPhone"), h("span", { style: { fontSize: 12, color: "var(--ent-faint)" } }, "2 days ago")))),
        card("Login history", "Recent sign-in activity.",
          h("div", null, [["Today, 9:42 AM", "Dubai, UAE"], ["Yesterday, 8:03 AM", "Dubai, UAE"], ["July 4, 2026", "London, UK"]].map(function (r, i) {
            return h("div", { key: i, style: { display: "flex", justifyContent: "space-between", padding: "8px 0", borderBottom: i < 2 ? "1px solid var(--ent-border-2)" : "0", fontSize: 13 } }, h("span", null, r[0]), h("span", { style: { color: "var(--ent-muted)" } }, r[1]));
          }))));
    } else if (tab === "integrations") {
      var INTEG = [["Slack", "slack", true], ["Microsoft Teams", "team", false], ["Google Drive", "layers", false], ["Notion", "report", false], ["Email forwarding", "brief", true]];
      body = card("Integrations", "Connect Mira Enterprise to your team's tools.",
        h("div", null, INTEG.map(function (it, i) {
          return h("div", { key: it[0], style: { display: "flex", alignItems: "center", gap: 12, padding: "14px 0", borderBottom: i < INTEG.length - 1 ? "1px solid var(--ent-border-2)" : "0" } },
            h("span", { style: { width: 34, height: 34, borderRadius: 9, background: "var(--ent-surface-2)", border: "1px solid var(--ent-border-2)", display: "grid", placeItems: "center", flex: "none" } }, h(Ico, { name: it[1], size: 16 })),
            h("div", { style: { flex: 1 } }, h("div", { style: { fontSize: 13.5, fontWeight: 600 } }, it[0])),
            it[2] ? h("span", { style: { display: "inline-flex", gap: 8, alignItems: "center" } }, h(Badge, { kind: "active" }, "Connected"), h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", onClick: function () { toast(it[0] + " settings coming soon"); } }, "Manage"))
              : h("button", { className: "ent-btn ent-btn--sm", onClick: function () { toast(it[0] + " integration is coming soon"); } }, "Connect", h("span", { className: "ent-soon" }, "Soon")));
        })));
    } else if (tab === "api") {
      var _apiKey = "sk_live_" + "•".repeat(24);
      body = h("div", { style: { display: "flex", flexDirection: "column", gap: 16 } },
        card("API access", "Programmatic access to your monitors, signals and reports.",
          h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } }, h("span", { style: { fontSize: 13, color: "var(--ent-muted)" } }, "Status"), h("span", { className: "ent-soon" }, "Coming soon"))),
        card("API key", "Keep your key secret. It grants full access to your workspace.",
          h("div", null,
            h("div", { className: "ent-code-chip", style: { width: "100%", justifyContent: "space-between" } }, _apiKey, h("button", { className: "ent-menu-btn", "aria-label": "Copy key", disabled: true }, h(Ico, { name: "copy", size: 14 }))),
            h("button", { className: "ent-btn", style: { marginTop: 12 }, onClick: function () { toast("API access is coming soon for Mira Enterprise."); } }, "Generate API key"))),
        card("Webhook", "Receive signal events at your endpoint.",
          h("div", { className: "ent-field", style: { marginBottom: 0 } }, h("label", null, "Webhook URL"), h("input", { className: "ent-input", style: { width: "100%" }, placeholder: "https://your-app.com/webhooks/mira", disabled: true }),
            h("div", { className: "ent-field-hint" }, "API access is coming soon for Mira Enterprise."))));
    } else { // workspace
      var full = true; // preview demo: seats 5 / 5
      body = h("div", { style: { display: "flex", flexDirection: "column", gap: 16 } },
        card("Workspace", "Organisation-level settings.",
          h("div", null,
            h("div", { className: "ent-field" }, h("label", null, "Workspace name"), h("input", { className: "ent-input", style: { width: "100%" }, value: s.wsName, onChange: function (e) { setField("wsName", e.target.value); } })),
            h("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" } },
              h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Team seat limit", "teamSize", ["5 - 10", "10 - 25", "25 - 50", "50+"])),
              h("div", { style: { flex: 1, minWidth: 180 } }, fieldSelect("Data retention", "retention", ["90 days", "6 months", "1 year", "Unlimited"]))),
            h("div", { style: { display: "flex", gap: 8, marginTop: 4, flexWrap: "wrap" } },
              h("button", { className: "ent-btn ent-btn--primary", onClick: function () { toast("Workspace saved."); } }, "Save workspace"),
              h("button", { className: "ent-btn", onClick: function () { toast("Workspace export is coming soon"); } }, h(Ico, { name: "download", size: 14 }), "Export workspace data")))),
        // Team access code
        card("Team access code", "Members with a Globly account can join this workspace using your organisation code while seats are available.",
          h("div", null,
            h("div", { className: "ent-code-chip", style: { width: "100%", justifyContent: "space-between" } }, code, h("button", { className: "ent-menu-btn", "aria-label": "Copy code", onClick: function () { copyText(code); toast("Team code copied"); } }, h(Ico, { name: "copy", size: 14 }))),
            h("div", { className: "ent-rail-row", style: { marginTop: 10 } }, h("span", { className: "l" }, "Seats used"), h("span", { className: "v" }, "5 / 5")),
            h("div", { className: "ent-rail-row" }, h("span", { className: "l" }, "Status"), h(Badge, { kind: full ? "blocked" : "active" }, full ? "Full" : "Active")),
            full ? h("p", { style: { fontSize: 11.5, color: "var(--ent-med)", margin: "8px 0 0" } }, "This workspace has reached its team limit. New members cannot join unless seats are added.") : null,
            h("div", { style: { display: "flex", gap: 8, marginTop: 12 } },
              h("button", { className: "ent-btn ent-btn--sm", style: { flex: 1, justifyContent: "center" }, onClick: function () { copyText(code); toast("Team code copied"); } }, h(Ico, { name: "copy", size: 14 }), "Copy code"),
              h("button", { className: "ent-btn ent-btn--sm", style: { flex: 1, justifyContent: "center" }, onClick: regenCode }, "Regenerate code")),
            h("div", { className: "ent-demo-note", style: { marginTop: 10 } }, "Demo data"))),
        // Danger zone (also on workspace tab)
        h("div", { className: "ent-card", style: { borderColor: "var(--ent-hi-t)" } },
          h("div", { className: "ent-card-hd" }, h("div", null, h("h3", { style: { color: "var(--ent-hi)" } }, "Delete workspace"), h("div", { className: "ent-card-hd-sub" }, "Permanently remove this workspace and all its data."))),
          h("div", { className: "ent-card-pad" }, h("button", { className: "ent-btn", style: { borderColor: "var(--ent-hi)", color: "var(--ent-hi)" }, onClick: function () { setModal("delete"); } }, "Delete workspace"))));
    }

    var main = h("div", { className: "ent-col" },
      h(PageHead, { title: "Settings", sub: "Manage your account, preferences and workspace settings." }),
      h("div", { className: "ent-tabs", style: { overflowX: "auto", flexWrap: "nowrap" } }, TABS.map(function (t) { return h("button", { key: t[0], className: "ent-tab" + (tab === t[0] ? " is-active" : ""), style: { whiteSpace: "nowrap" }, onClick: function () { setTab(t[0]); } }, t[1]); })),
      body);

    var rail = h("div", { className: "ent-rail" },
      // Your Plan
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Your plan"),
        h("div", { style: { fontSize: 15, fontWeight: 700 } }, "Mira Enterprise Starter"),
        h("div", { className: "ent-land-price", style: { margin: "6px 0 2px" } }, h("span", { className: "amt", style: { fontSize: 26 } }, "$99"), h("span", { className: "per" }, "/ month")),
        h("div", { style: { fontSize: 12, color: "var(--ent-muted)" } }, "Per organisation"),
        h("div", { style: { margin: "10px 0" } }, h("span", { className: "ent-pill ent-pill--accent ent-pill--dot" }, "Preview plan")),
        h("div", { style: { display: "flex", flexDirection: "column", gap: 7, margin: "6px 0 12px" } }, PLAN_FEATURES.map(function (f, i) {
          return h("div", { key: i, style: { display: "flex", gap: 8, alignItems: "center", fontSize: 12.5, color: "var(--ent-body)" } }, h(Ico, { name: "check", size: 14 }), f);
        })),
        h("button", { className: "ent-btn ent-btn--sm", style: { width: "100%", justifyContent: "center" }, onClick: function () { setModal("plan"); } }, "View plan details")),
      // Account Activity
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Account activity"),
        ACCOUNT_ACTIVITY.map(function (a, i) {
          return h("div", { key: i, style: { display: "flex", gap: 10, padding: "8px 0", borderBottom: i < ACCOUNT_ACTIVITY.length - 1 ? "1px solid var(--ent-border-2)" : "0" } },
            h("span", { style: { flex: "none", width: 28, height: 28, borderRadius: 8, background: "var(--ent-surface-2)", border: "1px solid var(--ent-border-2)", display: "grid", placeItems: "center" } }, h(Ico, { name: a.icon, size: 13 })),
            h("div", { style: { flex: 1, minWidth: 0 } }, h("div", { style: { fontSize: 12.5, fontWeight: 600 } }, a.title), a.meta ? h("div", { style: { fontSize: 11.5, color: "var(--ent-muted)" } }, a.meta) : null, h("div", { style: { fontSize: 11, color: "var(--ent-faint)" } }, a.when)));
        }),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: 8 }, onClick: function () { toast("Full activity log is coming soon"); } }, "View all activity")),
      // Data & Usage
      h("div", { className: "ent-rail-card" }, h("div", { className: "ent-rail-title" }, "Data & usage"),
        h("div", { className: "ent-barlist" }, USAGE_ROWS.map(function (u, i) { return h("div", { key: i }, usageRow(u[0], u[1], u[2])); })),
        h("button", { className: "ent-btn ent-btn--ghost ent-btn--sm", style: { marginTop: 10 }, onClick: function () { setModal("usage"); } }, "View usage details")));

    return [R.cloneElement(main, { key: "main" }), R.cloneElement(rail, { key: "rail" }),
      modal === "profile" ? h(EditProfileModal, { key: "ep", s: s, onClose: function () { setModal(null); }, onSave: function (f) { persist(Object.assign({}, s, f)); setModal(null); toast("Profile updated."); } }) : null,
      modal === "workspace" ? h(EditWorkspaceModal, { key: "ew", s: s, onClose: function () { setModal(null); }, onSave: function (f) { persist(Object.assign({}, s, f)); setModal(null); toast("Workspace updated."); } }) : null,
      modal === "delete" ? h(DeleteWorkspaceModal, { key: "dw", onClose: function () { setModal(null); }, onConfirm: function () { setModal(null); toast("Workspace deletion is disabled in preview mode."); } }) : null,
      modal === "plan" ? h(PlanDetailsModal, { key: "pl", onClose: function () { setModal(null); } }) : null,
      modal === "usage" ? h(UsageDetailsModal, { key: "us", onClose: function () { setModal(null); } }) : null];
  }

  function EditProfileModal(props) {
    var _n = useState(props.s.fullName), name = _n[0], setName = _n[1];
    var _e = useState(props.s.email), email = _e[0], setEmail = _e[1];
    return h(Modal, { title: "Edit profile", onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"), h("button", { key: "s", className: "ent-btn ent-btn--primary", onClick: function () { props.onSave({ fullName: name.trim() || props.s.fullName, email: email.trim() || props.s.email }); } }, "Save")] },
      h("div", { className: "ent-field" }, h("label", null, "Full name"), h("input", { className: "ent-input", style: { width: "100%" }, value: name, onChange: function (e) { setName(e.target.value); } })),
      h("div", { className: "ent-field", style: { marginBottom: 0 } }, h("label", null, "Email address"), h("input", { className: "ent-input", type: "email", style: { width: "100%" }, value: email, onChange: function (e) { setEmail(e.target.value); } })));
  }

  function EditWorkspaceModal(props) {
    var _n = useState(props.s.wsName), name = _n[0], setName = _n[1];
    var _i = useState(props.s.industry), ind = _i[0], setInd = _i[1];
    var _t = useState(props.s.teamSize), size = _t[0], setSize = _t[1];
    return h(Modal, { title: "Edit workspace", onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"), h("button", { key: "s", className: "ent-btn ent-btn--primary", onClick: function () { props.onSave({ wsName: name.trim() || props.s.wsName, industry: ind, teamSize: size }); } }, "Save")] },
      h("div", { className: "ent-field" }, h("label", null, "Workspace name"), h("input", { className: "ent-input", style: { width: "100%" }, value: name, onChange: function (e) { setName(e.target.value); } })),
      h("div", { className: "ent-field" }, h("label", null, "Workspace ID"), h("input", { className: "ent-input", style: { width: "100%" }, value: props.s.wsId, disabled: true })),
      h("div", { className: "ent-field" }, h("label", null, "Industry"), h("select", { className: "ent-select", style: { width: "100%" }, value: ind, onChange: function (e) { setInd(e.target.value); } }, ["NGO / Development", "Government", "Research / Academia", "Media", "Private sector"].map(function (o) { return h("option", { key: o }, o); }))),
      h("div", { className: "ent-field", style: { marginBottom: 0 } }, h("label", null, "Team size"), h("select", { className: "ent-select", style: { width: "100%" }, value: size, onChange: function (e) { setSize(e.target.value); } }, ["5 - 10", "10 - 25", "25 - 50", "50+"].map(function (o) { return h("option", { key: o }, o); }))));
  }

  function DeleteWorkspaceModal(props) {
    return h(Modal, { title: "Delete workspace", onClose: props.onClose,
      foot: [h("button", { key: "c", className: "ent-btn ent-btn--ghost", onClick: props.onClose }, "Cancel"), h("button", { key: "d", className: "ent-btn", style: { background: "var(--ent-hi)", borderColor: "var(--ent-hi)", color: "#fff" }, onClick: props.onConfirm }, "Delete workspace")] },
      h("p", { style: { fontSize: 13.5, color: "var(--ent-body)", lineHeight: 1.6, margin: "0 0 12px" } }, "This will permanently delete ", h("strong", null, "Meridian Relief"), " and all associated monitors, signals, reports and member access. This action cannot be undone."),
      h("div", { className: "ent-gate-msg ent-gate-msg--err", style: { margin: 0 } }, "Preview mode: workspace deletion is disabled — nothing will be removed."));
  }

  function PlanDetailsModal(props) {
    return h(Modal, { title: "Mira Enterprise Starter", wide: true, onClose: props.onClose, foot: [h("button", { key: "d", className: "ent-btn ent-btn--primary", onClick: props.onClose }, "Done")] },
      h("div", { className: "ent-land-price", style: { margin: "0 0 14px" } }, h("span", { className: "amt" }, "$99"), h("span", { className: "per" }, "/ month per organisation")),
      h("p", { style: { fontSize: 13, color: "var(--ent-muted)", marginTop: 0 } }, "Early-access preview pricing. Everything your team needs to get started with source-grounded intelligence."),
      h("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, PLAN_FEATURES.map(function (f, i) {
        return h("div", { key: i, style: { display: "flex", gap: 8, alignItems: "center", fontSize: 13.5 } }, h(Ico, { name: "check", size: 15 }), f);
      })));
  }

  function UsageDetailsModal(props) {
    return h(Modal, { title: "Data & usage", wide: true, onClose: props.onClose, foot: [h("button", { key: "d", className: "ent-btn ent-btn--primary", onClick: props.onClose }, "Done")] },
      h("p", { style: { fontSize: 13, color: "var(--ent-muted)", marginTop: 0 } }, "Your workspace usage this billing period."),
      h("div", { className: "ent-barlist" }, USAGE_ROWS.map(function (u, i) { return h("div", { key: i }, usageRow(u[0], u[1], u[2])); })));
  }

  // ============================================================
  //  ACCESS GATE + JOIN + LANDING
  // ============================================================
  function GateTop() {
    return h("div", { className: "ent-gate-top" },
      h("div", { className: "ent-sb-logo" }, "G"),
      h("div", null, h("div", { style: { fontFamily: "Georgia,serif", fontSize: "17px", fontWeight: 600 } }, "Globly"), h("div", { className: "ent-sb-brand-sub" }, "Enterprise")),
      h("button", { className: "ent-btn ent-btn--ghost ent-gate-back", onClick: function () { window.location.hash = "#/"; } }, "← Back to Globly"));
  }

  function SignedOutLanding() {
    var _busy = useState(false), busy = _busy[0], setBusy = _busy[1];
    function signIn() {
      // Route to the main app's sign-in; return here after auth.
      try { sessionStorage.setItem("ent_return", "1"); } catch (e) {}
      window.location.hash = "#/";
      setTimeout(function () {
        var btn = Array.from(document.querySelectorAll("button")).find(function (b) { return /sign in|log in/i.test(b.textContent) && !/google/i.test(b.textContent); });
        if (btn) btn.click();
      }, 300);
    }
    return h("div", { className: "ent-gate" }, h(GateTop),
      h("div", { className: "ent-gate-body" },
        h("div", { className: "ent-gate-card ent-gate-card--wide" },
          h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "40px", alignItems: "center" } },
            h("div", null,
              h("div", { className: "ent-gate-eyebrow" }, "Mira Enterprise"),
              h("h1", { className: "ent-gate-title" }, "Source-grounded global intelligence for your team."),
              h("p", { className: "ent-gate-sub" }, "Daily team briefings, monitors, signals and reports — built on real reporting, not guesswork."),
              h("div", { className: "ent-land-price" }, h("span", { className: "amt" }, "$99"), h("span", { className: "per" }, "/ month per organisation")),
              h("div", { style: { display: "flex", gap: "10px", marginTop: "20px" } },
                h("button", { className: "ent-btn ent-btn--primary", onClick: signIn }, "Sign in to continue"),
                h("button", { className: "ent-btn", onClick: function () { window.location.hash = "#/business"; } }, "Learn more"))),
            h("div", { className: "ent-land-grid", style: { marginTop: 0 } },
              [["dashboard", "Team dashboard", "One brief: what changed, why it matters, who’s affected."], ["monitor", "Monitors", "Track the regions and topics that matter to you."], ["signal", "Signals", "Detected changes, ranked by priority."], ["report", "Reports", "Decision-ready weekly intelligence."]].map(function (f, i) {
                return h("div", { key: i, className: "ent-land-feat" }, h("div", { className: "ent-land-feat-ico" }, h(Ico, { name: f[0], size: 18 })), h("div", null, h("h4", null, f[1]), h("p", null, f[2])));
              }))))));
  }

  function JoinFlow(props) {
    var sess = props.session, onJoined = props.onJoined;
    var _mode = useState("choose"), mode = _mode[0], setMode = _mode[1];
    var _code = useState(""), code = _code[0], setCode = _code[1];
    var _org = useState(""), org = _org[0], setOrg = _org[1];
    var _err = useState(null), err = _err[0], setErr = _err[1];

    function submitJoin() {
      setErr(null);
      var r = joinByCode(sess.email, sess.name, code.trim());
      if (r.ok) { onJoined(); return; }
      if (r.reason === "full") setErr("This workspace has reached its team limit. Ask your organisation admin to add more seats.");
      else setErr("This code is not valid. Check the code and try again.");
    }
    function submitCreate() {
      var r = createWorkspace(sess.email, sess.name, org.trim() || "My Organisation");
      if (r.ok) onJoined();
    }

    return h("div", { className: "ent-gate" }, h(GateTop),
      h("div", { className: "ent-gate-body" },
        h("div", { className: "ent-gate-card" },
          mode === "choose" ? h("div", null,
            h("div", { className: "ent-gate-eyebrow" }, "Mira Enterprise"),
            h("h1", { className: "ent-gate-title" }, "Join your team"),
            h("p", { className: "ent-gate-sub" }, "You’re signed in as " + sess.email + ". Enter your organisation’s team code, or create a new workspace."),
            h("button", { className: "ent-btn ent-btn--primary", style: { width: "100%", justifyContent: "center", marginBottom: "10px" }, onClick: function () { setMode("join"); } }, "I have a team code"),
            h("button", { className: "ent-btn", style: { width: "100%", justifyContent: "center" }, onClick: function () { setMode("create"); } }, "Create a new workspace")
          ) : mode === "join" ? h("div", null,
            h("div", { className: "ent-gate-eyebrow" }, "Join workspace"),
            h("h1", { className: "ent-gate-title" }, "Enter team code"),
            h("p", { className: "ent-gate-sub" }, "Your admin can share a 12-character code from the Team page."),
            err ? h("div", { className: "ent-gate-msg ent-gate-msg--err" }, err) : null,
            h("input", { className: "ent-input ent-code-input", style: { width: "100%", marginBottom: "14px" }, placeholder: "XXXXXXXXXXXX", maxLength: 12, value: code, onChange: function (e) { setCode(e.target.value); setErr(null); } }),
            h("button", { className: "ent-btn ent-btn--primary", style: { width: "100%", justifyContent: "center" }, disabled: code.trim().length < 6, onClick: submitJoin }, "Join workspace"),
            h("button", { className: "ent-btn ent-btn--ghost", style: { width: "100%", justifyContent: "center", marginTop: "8px" }, onClick: function () { setMode("choose"); } }, "Back")
          ) : h("div", null,
            h("div", { className: "ent-gate-eyebrow" }, "New workspace"),
            h("h1", { className: "ent-gate-title" }, "Create your workspace"),
            h("p", { className: "ent-gate-sub" }, "You’ll be the Team Admin and get a code to invite your team."),
            h("div", { className: "ent-field" }, h("label", null, "Organisation name"), h("input", { className: "ent-input", style: { width: "100%" }, placeholder: "e.g. Meridian Relief", value: org, onChange: function (e) { setOrg(e.target.value); } })),
            h("button", { className: "ent-btn ent-btn--primary", style: { width: "100%", justifyContent: "center" }, onClick: submitCreate }, "Create workspace"),
            h("button", { className: "ent-btn ent-btn--ghost", style: { width: "100%", justifyContent: "center", marginTop: "8px" }, onClick: function () { setMode("choose"); } }, "Back")))));
  }

  // ============================================================
  //  SETUP GUIDE (onboarding) — skippable, resumable
  // ============================================================
  // TODO: persist onboarding state to the workspace database before launch.
  var ENT_PAGE_GUIDE = [
    ["Dashboard", "dashboard", "Your dashboard shows today's team brief, active monitors, important signals and recommended actions."],
    ["Monitors", "monitor", "Monitors are watchlists. Create monitors for the topics, regions and organisations your team wants Mira to track."],
    ["Briefings", "brief", "Briefings turn your monitors and signals into daily team intelligence summaries."],
    ["Sources", "source", "Sources are the trusted places Mira scans. Add sources, review reliability and track source health."],
    ["Signals", "signal", "Signals are important changes detected from your monitors and sources."],
    ["Reports", "report", "Reports turn signals and briefings into decision-ready documents for your team, donors or stakeholders."],
    ["Team", "team", "Invite members, manage roles and control who can access the workspace."],
    ["Billing", "billing", "Manage your plan, usage, invoices and payment settings."],
    ["Settings", "settings", "Control workspace details, briefing preferences, notifications, integrations and access codes."],
  ];
  function EnterpriseSetupGuide(props) {
    var ws = props.ws;
    var steps = setupSteps(ws);
    var doneCount = steps.filter(function (s) { return s.done; }).length;
    var pct = Math.round(doneCount / steps.length * 100);
    var _i = useState(function () { var idx = 0; for (var k = 0; k < steps.length; k++) { if (!steps[k].done) { idx = k; break; } } return idx; }), i = _i[0], setI = _i[1];
    var cur = steps[i];
    var scrim = { position: "fixed", inset: 0, background: "rgba(26,23,18,0.45)", zIndex: 100000, display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "40px 16px", overflowY: "auto" };
    var panel = { background: "#fff", width: "100%", maxWidth: 580, borderRadius: 16, boxShadow: "0 12px 48px rgba(26,23,18,.28)", overflow: "hidden", fontFamily: "var(--ent-font)" };
    return h("div", { style: scrim, onClick: props.onClose },
      h("div", { style: panel, onClick: function (e) { e.stopPropagation(); } },
        h("div", { style: { padding: "22px 24px 16px", borderBottom: "1px solid var(--ent-border-2)", position: "relative" } },
          h("div", { style: { fontSize: 11, fontWeight: 800, letterSpacing: ".14em", textTransform: "uppercase", color: "#7C3AED", marginBottom: 8 } }, "Getting started"),
          h("div", { style: { fontFamily: "var(--ent-serif)", fontSize: 22, fontWeight: 700, color: "var(--ent-ink)" } }, "Welcome to Mira Enterprise"),
          h("div", { style: { fontSize: 13, color: "var(--ent-muted)", marginTop: 6, lineHeight: 1.5, maxWidth: 460 } }, "Set up your team workspace to start receiving source-grounded development intelligence."),
          h("button", { onClick: props.onClose, "aria-label": "Close", style: { position: "absolute", top: 18, right: 18, border: "none", background: "none", fontSize: 22, lineHeight: 1, color: "var(--ent-muted)", cursor: "pointer" } }, "×"),
          h("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 12, color: "var(--ent-muted)", margin: "16px 0 6px", fontWeight: 600 } },
            h("span", null, doneCount + " of " + steps.length + " completed"), h("span", null, pct + "%")),
          h("div", { style: { height: 7, borderRadius: 999, background: "#EFEAE0", overflow: "hidden" } }, h("div", { style: { height: "100%", width: pct + "%", background: "#7C3AED", borderRadius: 999, transition: "width .3s" } }))),
        h("div", { style: { padding: "12px 16px", maxHeight: "34vh", overflowY: "auto" } },
          steps.map(function (s, k) {
            return h("div", { key: s.key, onClick: function () { setI(k); },
                style: { display: "flex", alignItems: "flex-start", gap: 12, padding: "11px 12px", borderRadius: 10, cursor: "pointer", background: k === i ? "var(--ent-accent-t)" : "transparent" } },
              h("span", { style: { width: 24, height: 24, borderRadius: 999, flex: "none", display: "grid", placeItems: "center", fontSize: 12, fontWeight: 700, background: s.done ? "#4F8A54" : "#EFEAE0", color: s.done ? "#fff" : "var(--ent-muted)" } }, s.done ? h(Ico, { name: "check", size: 14 }) : (k + 1)),
              h("span", { style: { flex: 1, minWidth: 0 } },
                h("span", { style: { display: "block", fontSize: 13.5, fontWeight: 700, color: "var(--ent-ink)", textDecoration: s.done ? "line-through" : "none", opacity: s.done ? 0.7 : 1 } }, s.title),
                h("span", { style: { display: "block", fontSize: 12, color: "var(--ent-muted)", marginTop: 2, lineHeight: 1.4 } }, s.desc)),
              h("button", { onClick: function (e) { e.stopPropagation(); props.onGo(s.route); }, className: "ent-btn ent-btn--ghost ent-btn--sm", style: { flex: "none" } }, s.done ? "Review" : "Go →"));
          })),
        h("div", { style: { padding: "12px 20px 4px", borderTop: "1px solid var(--ent-border-2)" } },
          h("div", { style: { fontSize: 11.5, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".06em", color: "var(--ent-faint)", marginBottom: 8 } }, "What each page does")),
        h("div", { style: { padding: "0 20px 8px", maxHeight: "22vh", overflowY: "auto" } },
          ENT_PAGE_GUIDE.map(function (pg) {
            return h("div", { key: pg[0], style: { display: "flex", gap: 10, alignItems: "flex-start", padding: "7px 0", fontSize: 12.5, color: "var(--ent-muted)", lineHeight: 1.45 } },
              h("span", { style: { width: 26, height: 26, borderRadius: 8, flex: "none", display: "grid", placeItems: "center", background: "var(--ent-accent-t)", color: "var(--ent-accent-d)" } }, h(Ico, { name: pg[1], size: 14 })),
              h("span", null, h("b", { style: { color: "var(--ent-ink)" } }, pg[0]), " — " + pg[2]));
          })),
        h("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "14px 20px", borderTop: "1px solid var(--ent-border-2)", background: "var(--ent-surface-2)", flexWrap: "wrap" } },
          h("button", { className: "ent-btn ent-btn--ghost", onClick: props.onSkip }, "Skip setup"),
          h("span", { style: { marginLeft: "auto" } }),
          h("button", { className: "ent-btn", disabled: i === 0, onClick: function () { setI(Math.max(0, i - 1)); } }, "Back"),
          i < steps.length - 1 ? h("button", { className: "ent-btn", onClick: function () { setI(i + 1); } }, "Next") : null,
          h("button", { className: "ent-btn ent-btn--primary", onClick: function () { props.onGo(cur.route); } }, cur.done ? "Review step" : "Start step"))));
  }

  // ============================================================
  //  ROOT
  // ============================================================
  function EnterpriseRoot() {
    var _hash = useState(window.location.hash), hash = _hash[0], setHash = _hash[1];
    var _sess = useState(currentSession()), sess = _sess[0], setSess = _sess[1];
    var _stories = useState([]), stories = _stories[0], setStories = _stories[1];
    var _ws = useState(null), ws = _ws[0], setWs = _ws[1];
    var _tick = useState(0), tick = _tick[0], setTick = _tick[1];
    var _guide = useState(false), guide = _guide[0], setGuide = _guide[1];
    var toastPair = useToast(); var toast = toastPair[0], toastNode = toastPair[1];

    useEffect(function () {
      clearLegacyDemo();
      var w = ensureWorkspace(currentSession() || { email: "preview@globly.news", name: "Preview" });
      var onb = Store.onboarding(w.id);
      if (!onb.skipped && !onb.dismissed && Store.monitors(w.id).length === 0) setGuide(true);
    }, []);
    useEffect(function () {
      function onHash() { setHash(window.location.hash); setSess(currentSession()); }
      window.addEventListener("hashchange", onHash);
      var iv = setInterval(function () { var s = currentSession(); setSess(function (p) { return (p && p.email) === (s && s.email) ? p : s; }); }, 1500);
      return function () { window.removeEventListener("hashchange", onHash); clearInterval(iv); };
    }, []);

    var active = /^#\/enterprise/.test(hash);
    useEffect(function () {
      if (active && stories.length === 0) loadStories().then(function (s) { setStories(s); });
    }, [active]);
    useEffect(function () {
      if (sess && sess.email) {
        var mem = Store.membership(sess.email);
        if (mem) { var w = Store.workspaces()[mem.wsId]; setWs(w ? Object.assign({}, w, { _role: mem.role }) : null); }
        else setWs(null);
      } else setWs(null);
    }, [sess && sess.email, tick, hash]);

    if (!active) return null;
    // lock body scroll behind overlay
    document.body.style.overflow = "hidden";

    // route parse
    var m = hash.match(/^#\/enterprise(?:\/([a-z]+))?/);
    var route = (m && m[1]) || "dashboard";
    var mMon = hash.match(/^#\/enterprise\/monitors\/([A-Za-z0-9_-]+)/);
    var monId = mMon && mMon[1];

    // TODO: require signed-in workspace access before launch.
    // Temporary preview mode — Enterprise is PUBLIC: no sign-in, subscription, or
    // team code required. Every user gets a real, EMPTY workspace (no demo data);
    // first access shows welcome/setup states until they configure it.
    // SignedOutLanding and JoinFlow remain defined above for when gating returns.
    var effSess = (sess && sess.email) ? sess : { email: "preview@globly.news", name: "Preview" };
    var effWs = ensureWorkspace(effSess);
    function refresh() { setTick(tick + 1); }

    var role = effWs._role || "Team Admin";
    var isAdmin = role === "Team Admin" || role === "Admin";
    function onWsChange(next) { setWs(Object.assign({}, next, { _role: role })); setTick(tick + 1); }

    var content;
    var props = { ws: effWs, session: effSess, stories: stories, role: role, monitors: Store.monitors(effWs.id), toast: toast, onWsChange: onWsChange, refresh: refresh, onGuide: function () { setGuide(true); } };
    if (route === "monitors" && monId) content = h(MonitorDetailPage, Object.assign({}, props, { monitorId: monId }));
    else if (route === "monitors") content = h(MonitorsPage, props);
    else if (route === "briefings") content = h(BriefingsPage, props);
    else if (route === "sources") content = h(SourcesPage, props);
    else if (route === "signals") content = h(SignalsPage, props);
    else if (route === "reports") content = h(ReportsPage, props);
    else if (route === "team") content = h(TeamPage, props);
    else if (route === "billing") content = isAdmin ? h(BillingPage, props) : h(NoAccess, { toast: toast });
    else if (route === "settings") content = h(SettingsPage, props);
    else content = (props.monitors && props.monitors.length) ? h(Dashboard, props) : h(dashboardFirstAccess, props);

    var withRail = { dashboard: 1, briefings: 1, sources: 1, team: 1, billing: 1, settings: 1, reports: 1 };
    return h("div", { className: "ent-root" },
      h(Shell, { ws: effWs, session: effSess, route: route, rail: !!withRail[route], onGuide: function () { setGuide(true); } }, content),
      guide ? h(EnterpriseSetupGuide, {
        ws: effWs, session: effSess,
        onClose: function () { Store.setOnboarding(effWs.id, { dismissed: true }); setGuide(false); },
        onSkip: function () { Store.setOnboarding(effWs.id, { skipped: true, dismissed: true }); setGuide(false); toast("Setup guide hidden — reopen it from Setup guide in the top bar"); },
        onGo: function (route) { Store.setOnboarding(effWs.id, { dismissed: true }); setGuide(false); go(route); },
      }) : null,
      toastNode);
  }
  function NoAccess(props) {
    return h("div", { className: "ent-col" }, h(PageHead, { title: "Billing", sub: "Only workspace admins can view billing." }),
      h("div", { className: "ent-card ent-card-pad" }, h(EmptyState, { icon: "shield", text: "You need an admin role to manage billing. Ask your Team Admin for access." })));
  }

  // ── mount ───────────────────────────────────────────────────────────────
  function mount() {
    var el = document.getElementById("ent-root");
    if (!el) { el = document.createElement("div"); el.id = "ent-root"; document.body.appendChild(el); }
    var root = window.ReactDOM.createRoot(el);
    root.render(h(EnterpriseRoot));
    // restore body scroll when leaving enterprise
    window.addEventListener("hashchange", function () {
      if (!/^#\/enterprise/.test(window.location.hash)) document.body.style.overflow = "";
    });
  }
  if (document.readyState !== "loading") mount();
  else document.addEventListener("DOMContentLoaded", mount);
})();
