/* =====================================================================
   AI-COS — Shared UI primitives + icon set  →  window.*
   ===================================================================== */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------------- Icons (Lucide-style line set) --------------------- */
const ICONS = {
  grid: 'M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z',
  calendar: 'M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z',
  briefcase: 'M4 7h16a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zM8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 12h18',
  receipt: 'M5 3v18l2-1.5L9 21l2-1.5L13 21l2-1.5L17 21l2-1.5V3l-2 1.5L15 3l-2 1.5L11 3 9 4.5 7 3zM8 8h8M8 12h8M8 16h5',
  workflow: 'M4 4h6v6H4zM14 14h6v6h-6zM7 10v4a2 2 0 0 0 2 2h4M17 10v4',
  shield: 'M12 2l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V5z',
  cylinder: 'M12 3c-3 0-5 1-5 2.5S9 8 12 8s5-1 5-2.5S15 3 12 3zM7 5.5v13C7 20 9 21 12 21s5-1 5-2.5v-13',
  cpu: 'M6 6h12v12H6zM9 9h6v6H9M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3',
  certificate: 'M4 4h16v11H4zM4 15l3 5 2-2 2 2M12 8h5M7 8h2M7 11h8',
  'check-shield': 'M12 2l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V5zM9 11l2 2 4-4',
  documents: 'M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7zM14 2v5h5M9 13h6M9 17h6',
  users: 'M16 11a4 4 0 1 0-4-4M17 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  helmet: 'M3 14a9 9 0 0 1 18 0M2 14h20v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2zM12 5v4M8 6.5l1 3M16 6.5l-1 3',
  chat: 'M21 11.5a8.38 8.38 0 0 1-8.5 8.5 8.5 8.5 0 0 1-3.8-.9L3 21l1.9-5.7a8.5 8.5 0 0 1-.9-3.8A8.38 8.38 0 0 1 11.5 3a8.38 8.38 0 0 1 9.5 8.5z',
  box: 'M21 8l-9-5-9 5 9 5 9-5zM3 8v8l9 5 9-5V8M12 13v8',
  wrench: 'M14.7 6.3a4 4 0 0 0-5.4 5.4L3 18l3 3 6.3-6.3a4 4 0 0 0 5.4-5.4l-2.5 2.5-2.3-.6-.6-2.3z',
  truck: 'M1 6h13v10H1zM14 9h4l3 3v4h-7M5.5 19a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM17.5 19a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',
  chart: 'M3 3v18h18M8 15v3M13 11v7M18 7v11',
  sparkles: 'M12 3l1.8 4.7L18 9.5l-4.2 1.8L12 16l-1.8-4.7L6 9.5l4.2-1.8zM5 16l.9 2.1L8 19l-2.1.9L5 22l-.9-2.1L2 19l2.1-.9zM19 14l.6 1.6L21 16l-1.4.4L19 18l-.6-1.6L17 16l1.4-.4z',
  settings: 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-2.82 1.17V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 7 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 2.6 14H2.5a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4 8.6a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6V4.5a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 2.82 1.17l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9v.09a2 2 0 0 1 0 4h-.09',
  search: 'M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.3-4.3',
  bell: 'M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0',
  check: 'M20 6L9 17l-5-5',
  'check-circle': 'M22 11.1V12a10 10 0 1 1-5.9-9.1M22 4L12 14.01l-3-3',
  x: 'M18 6L6 18M6 6l12 12',
  'x-circle': 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM15 9l-6 6M9 9l6 6',
  alert: 'M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0zM12 9v4M12 17h.01',
  clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2',
  lock: 'M5 11h14v10H5zM8 11V7a4 4 0 0 1 8 0v4',
  chevR: 'M9 18l6-6-6-6',
  chevL: 'M15 18l-6-6 6-6',
  chevD: 'M6 9l6 6 6-6',
  plus: 'M12 5v14M5 12h14',
  arrowUp: 'M12 19V5M5 12l7-7 7 7',
  arrowDown: 'M12 5v14M5 12l7 7 7-7',
  arrowR: 'M5 12h14M12 5l7 7-7 7',
  ext: 'M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3',
  download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3',
  qr: 'M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h3v3h-3zM20 14v3M14 20h3M20 20h1',
  filter: 'M22 3H2l8 9.5V19l4 2v-8.5z',
  dots: 'M12 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM19 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM5 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z',
  eye: 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  pin: 'M12 21s-7-6.5-7-11a7 7 0 0 1 14 0c0 4.5-7 11-7 11zM12 12a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z',
  thermometer: 'M14 14.76V5a2 2 0 1 0-4 0v9.76a4 4 0 1 0 4 0z',
  droplet: 'M12 2.7l5.3 5.3a7.5 7.5 0 1 1-10.6 0z',
  gauge: 'M12 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20M12 12l4-3M8 13a4 4 0 0 1 8 0',
  signature: 'M3 17c3 0 4-9 6-9s2 6 4 6 2-3 3-3 2 1 4 1M3 21h18',
  flask: 'M9 3h6M10 3v6l-5 9a2 2 0 0 0 1.8 3h10.4a2 2 0 0 0 1.8-3l-5-9V3M7.5 14h9',
  history: 'M3 3v6h6M3 9a9 9 0 1 1 1 6M12 7v5l3 2',
  link: 'M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1',
  logout: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9',
  star: 'M12 2l3 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.9 21l1.2-6.8-5-4.9 6.9-1z',
  trend: 'M22 7l-8.5 8.5-4-4L2 19M16 7h6v6',
  building: 'M3 21h18M5 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16M9 7h2M9 11h2M9 15h2M15 21V11h4v10',
  phone: 'M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3-8.6A2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.4 1.8.7 2.7a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.4-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.7.7a2 2 0 0 1 1.7 2z',
  refresh: 'M21 2v6h-6M3 22v-6h6M3.5 9a9 9 0 0 1 14.8-3.4L21 8M20.5 15a9 9 0 0 1-14.8 3.4L3 16',
  flag: 'M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7',
  menu: 'M3 12h18M3 6h18M3 18h18',
};

function Icon({ name, size = 18, sw = 1.9, fill = false, style, className }) {
  const d = ICONS[name] || ICONS.grid;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill ? 'currentColor' : 'none'}
         stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
         style={style} className={className} aria-hidden="true">
      {d.split('M').filter(Boolean).map((seg, i) => <path key={i} d={'M' + seg} />)}
    </svg>
  );
}

/* ---------------- Badge ------------------- */
function Badge({ kind = 'neutral', children, dot, icon, style }) {
  return (
    <span className={`badge b-${kind}`} style={style}>
      {dot && <span className="dot" />}
      {icon && <Icon name={icon} size={12} />}
      {children}
    </span>
  );
}
const STATUS_KIND = {
  'Valid': 'ok', 'Active': 'ok', 'Pass': 'ok', 'Paid': 'ok', 'Satisfactory': 'ok', 'Published': 'ok', 'Approved': 'ok', 'OK': 'ok', 'Closed': 'ok', 'Dispatched': 'ok',
  'Due soon': 'warn', 'Renewal due': 'warn', 'Low pressure': 'warn', 'Low': 'warn', 'In review': 'warn', 'Sent': 'warn', 'Questionable': 'warn', 'In validation': 'warn', 'Draft': 'neutral', 'In progress': 'info', 'In calibration': 'info', 'Review': 'info', 'Assigned': 'info', 'Received': 'neutral', 'Open': 'info',
  'Overdue': 'bad', 'Expired': 'bad', 'Fail': 'bad', 'Superseded': 'neutral', 'Withdrawn': 'bad',
  'Scheduled': 'info', 'Planned': 'neutral', 'Resolved': 'ok', 'Actions open': 'warn', 'Logged': 'neutral', 'Action taken': 'info', 'Investigation': 'warn', 'Review due': 'warn',
};
function StatusBadge({ status }) {
  const kind = STATUS_KIND[status] || 'neutral';
  return <Badge kind={kind} dot>{status}</Badge>;
}

/* ---------------- Avatar ------------------ */
function Avatar({ id, size = 'm' }) {
  const s = window.DB.staffById(id) || { initials: '?', color: '#94a3b8' };
  const cls = size === 'sm' ? 'avatar avatar-sm' : size === 'lg' ? 'avatar avatar-lg' : 'avatar';
  return <span className={cls} style={{ background: s.color }} title={s.name}>{s.initials}</span>;
}
function CustChip({ id, sub }) {
  const c = window.DB.custById(id);
  if (!c) return null;
  return (
    <div className="row" style={{ gap: 9 }}>
      <span className="avatar avatar-sm" style={{ background: c.color, borderRadius: 7 }}>{c.short}</span>
      <div className="col" style={{ gap: 0 }}>
        <span className="cell-strong" style={{ fontSize: 13 }}>{c.name}</span>
        {sub && <span className="cell-sub">{c.site}</span>}
      </div>
    </div>
  );
}

/* ---------------- Button ------------------ */
function Btn({ variant = 'ghost', size, icon, iconR, children, onClick, disabled, style }) {
  const sz = size === 'sm' ? ' btn-sm' : size === 'lg' ? ' btn-lg' : '';
  return (
    <button className={`btn btn-${variant}${sz}`} onClick={onClick} disabled={disabled} style={style}>
      {icon && <Icon name={icon} size={size === 'sm' ? 13 : 15} />}
      {children}
      {iconR && <Icon name={iconR} size={size === 'sm' ? 13 : 15} />}
    </button>
  );
}

/* ---------------- KPI card ----------------- */
function Kpi({ label, value, unit, icon, tone = 'info', delta, deltaDir, sub }) {
  const toneBg = { info: 'var(--info-bg)', ok: 'var(--ok-bg)', warn: 'var(--warn-bg)', bad: 'var(--bad-bg)', ai: 'var(--ai-bg)' }[tone];
  const toneFg = { info: 'var(--primary-600)', ok: 'var(--ok)', warn: 'var(--warn)', bad: 'var(--bad)', ai: 'var(--ai)' }[tone];
  return (
    <div className="kpi hover-lift">
      <div className="row" style={{ justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <span className="kpi-label">{label}</span>
        {icon && <span className="kpi-ico" style={{ background: toneBg, color: toneFg }}><Icon name={icon} size={17} /></span>}
      </div>
      <div className="kpi-val">{value}{unit && <span style={{ fontSize: 15, fontWeight: 700, color: 'var(--text-2)', marginLeft: 3 }}>{unit}</span>}</div>
      {(delta || sub) && (
        <div className="kpi-delta" style={{ color: deltaDir === 'up' ? 'var(--ok)' : deltaDir === 'down' ? 'var(--bad)' : 'var(--text-3)' }}>
          {deltaDir && <Icon name={deltaDir === 'up' ? 'arrowUp' : 'arrowDown'} size={13} />}
          {delta}{sub && <span style={{ color: 'var(--text-3)', fontWeight: 500 }}>{sub}</span>}
        </div>
      )}
    </div>
  );
}

/* ---------------- AI note ------------------ */
function AINote({ title, children, action, onAction, clause }) {
  return (
    <div className="ai-note">
      <span className="ai-badge-ico"><Icon name="sparkles" size={15} fill /></span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div className="row" style={{ gap: 8 }}>
          <span className="ai-label">AI · advisory</span>
          {clause && <span className="gate-clause" style={{ color: 'var(--ai)' }}>{clause}</span>}
        </div>
        <div style={{ fontWeight: 700, fontSize: 13, marginTop: 3 }}>{title}</div>
        {children && <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>{children}</div>}
        {action && <button className="btn btn-ai btn-sm" style={{ marginTop: 9 }} onClick={onAction}>{action}<Icon name="arrowR" size={13} /></button>}
      </div>
    </div>
  );
}

/* ---------------- Gate chip ---------------- */
function Gate({ gate }) {
  const map = { pass: ['pass', 'check-circle', 'var(--ok)', 'var(--ok-bg)'], block: ['block', 'x-circle', 'var(--bad)', 'var(--bad-bg)'], warn: ['warn', 'alert', 'var(--warn)', 'var(--warn-bg)'], pending: ['pending', 'lock', 'var(--text-3)', '#eef1f6'] };
  const [cls, ico, fg, bg] = map[gate.state] || map.pending;
  return (
    <div className={`gate ${cls}`}>
      <span className="gate-ico" style={{ background: bg, color: fg }}><Icon name={ico} size={18} /></span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div className="row" style={{ gap: 8 }}>
          <span className="gate-title">{gate.title}</span>
          <span className="gate-clause">{gate.clause}</span>
          <span style={{ marginLeft: 'auto' }}>
            {gate.state === 'pass' && <Badge kind="ok">Passed</Badge>}
            {gate.state === 'block' && <Badge kind="bad">Blocked</Badge>}
            {gate.state === 'pending' && <Badge kind="neutral">On submit</Badge>}
          </span>
        </div>
        <div className="gate-desc">{gate.desc}</div>
      </div>
    </div>
  );
}

/* ---------------- Section header ----------- */
function SectionHead({ title, sub, right }) {
  return (
    <div className="row" style={{ justifyContent: 'space-between', marginBottom: 14 }}>
      <div>
        <div className="h-sec">{title}</div>
        {sub && <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>{sub}</div>}
      </div>
      {right}
    </div>
  );
}

/* ---------------- Progress / ring ---------- */
function Bar({ pct, color = 'var(--primary-600)' }) {
  return <div className="progress"><i style={{ width: `${Math.max(0, Math.min(100, pct))}%`, background: color }} /></div>;
}
function Ring({ value, size = 132, stroke = 12, color = 'var(--primary-600)', track = '#eaeef4', children }) {
  const r = (size - stroke) / 2, c = 2 * Math.PI * r, off = c - (value / 100) * c;
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} className="ring">
        <circle cx={size / 2} cy={size / 2} r={r} stroke={track} strokeWidth={stroke} />
        <circle cx={size / 2} cy={size / 2} r={r} stroke={color} strokeWidth={stroke}
                strokeDasharray={c} strokeDashoffset={off} style={{ transition: 'stroke-dashoffset 1s cubic-bezier(.3,1,.4,1)' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', textAlign: 'center' }}>{children}</div>
    </div>
  );
}

/* ---------------- Drawer ------------------- */
function Drawer({ open, onClose, children, width }) {
  useEffect(() => {
    const h = (e) => e.key === 'Escape' && onClose();
    if (open) window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [open]);
  if (!open) return null;
  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="drawer" style={width ? { width } : null}>{children}</div>
    </React.Fragment>
  );
}

/* ---------------- Empty / placeholder module ---------------- */
function ModulePlaceholder({ icon, title, phase, desc, points }) {
  return (
    <div className="card" style={{ padding: '40px 36px', textAlign: 'center', maxWidth: 720, margin: '20px auto' }}>
      <div style={{ width: 60, height: 60, borderRadius: 16, background: 'var(--primary-50)', color: 'var(--primary-600)', display: 'grid', placeItems: 'center', margin: '0 auto 16px' }}>
        <Icon name={icon} size={28} />
      </div>
      <div className="row" style={{ justifyContent: 'center', gap: 8 }}>
        <span className="h-sec" style={{ fontSize: 18 }}>{title}</span>
        {phase && <Badge kind="neutral">Phase {phase.replace('P', '')}</Badge>}
      </div>
      <p className="muted" style={{ maxWidth: 460, margin: '8px auto 18px', fontSize: 13.5 }}>{desc}</p>
      {points && (
        <div style={{ display: 'inline-flex', flexDirection: 'column', gap: 8, textAlign: 'left' }}>
          {points.map((p, i) => (
            <div key={i} className="row" style={{ gap: 9, fontSize: 13 }}>
              <Icon name="check" size={15} style={{ color: 'var(--ok)' }} />{p}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ---------------- Toast system ---------------- */
let _toastListeners = [];
function pushToast(msg, kind = 'ok') { _toastListeners.forEach((l) => l(msg, kind)); }
function ToastHost() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const l = (msg, kind) => {
      const id = Math.random().toString(36).slice(2);
      setItems((s) => [...s, { id, msg, kind }]);
      setTimeout(() => setItems((s) => s.filter((i) => i.id !== id)), 3000);
    };
    _toastListeners.push(l);
    return () => { _toastListeners = _toastListeners.filter((x) => x !== l); };
  }, []);
  const map = { ok: ['check', 'var(--ok)'], info: ['bell', 'var(--primary-500)'], warn: ['alert', 'var(--warn)'], ai: ['sparkles', 'var(--ai)'] };
  return (
    <div className="toast-host">
      {items.map((it) => {
        const [ico, col] = map[it.kind] || map.ok;
        return (
          <div key={it.id} className="toast">
            <span className="t-ico" style={{ background: col }}><Icon name={ico} size={14} style={{ color: '#fff' }} /></span>
            <span>{it.msg}</span>
          </div>
        );
      })}
    </div>
  );
}

/* ---------------- Generic create/form modal ---------------- */
function FormModal({ title, sub, icon = 'plus', fields = [], submitLabel = 'Create', onClose, onSubmit, wide }) {
  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="modal" style={wide ? { width: 640 } : null}>
        <div style={{ padding: '18px 22px', borderBottom: '1px solid var(--border)' }} className="row">
          <span className="kpi-ico" style={{ background: 'var(--primary-50)', color: 'var(--primary-600)', width: 36, height: 36 }}><Icon name={icon} size={18} /></span>
          <div style={{ flex: 1 }}><div style={{ fontWeight: 750, fontSize: 16 }}>{title}</div>{sub && <div className="faint" style={{ fontSize: 12 }}>{sub}</div>}</div>
          <button className="icon-btn" onClick={onClose}><Icon name="x" size={17} /></button>
        </div>
        <div style={{ padding: 22, display: 'grid', gridTemplateColumns: wide ? '1fr 1fr' : '1fr', gap: 14, maxHeight: '60vh', overflowY: 'auto' }}>
          {fields.map((f, i) => (
            <div key={i} className="field" style={f.full ? { gridColumn: '1 / -1' } : null}>
              <label>{f.label}</label>
              {f.type === 'select' ? (
                <select defaultValue={f.value}>{(f.options || []).map((o) => <option key={o}>{o}</option>)}</select>
              ) : f.type === 'textarea' ? (
                <textarea rows="3" placeholder={f.placeholder} defaultValue={f.value} />
              ) : (
                <input type={f.type || 'text'} placeholder={f.placeholder} defaultValue={f.value} />
              )}
            </div>
          ))}
        </div>
        <div className="row" style={{ gap: 10, padding: '0 22px 22px' }}>
          <Btn variant="ghost" onClick={onClose} style={{ flex: 1 }}>Cancel</Btn>
          <Btn variant="primary" icon="check" onClick={onSubmit} style={{ flex: 2 }}>{submitLabel}</Btn>
        </div>
      </div>
    </React.Fragment>
  );
}

/* ---------------- Filter popover ---------------- */
function FilterMenu({ options, onPick, onClose, label = 'Filter by' }) {
  const ref = useRef(null);
  useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    setTimeout(() => document.addEventListener('mousedown', h), 0);
    return () => document.removeEventListener('mousedown', h);
  }, []);
  return (
    <div className="popover" style={{ right: 0, top: 'calc(100% + 6px)' }} ref={ref}>
      <div className="eyebrow" style={{ fontSize: 9.5, padding: '4px 10px 6px' }}>{label}</div>
      {options.map((o) => (
        <div key={o} className="pop-item" onClick={() => { onPick(o); onClose(); }}>
          <Icon name="filter" size={13} style={{ color: 'var(--text-3)' }} />{o}
        </div>
      ))}
    </div>
  );
}

/* ---------------- Global create-form host ---------------- */
let _formListener = null;
function openForm(cfg) { if (_formListener) _formListener(cfg); }
function FormHost() {
  const [cfg, setCfg] = useState(null);
  useEffect(() => { _formListener = (c) => setCfg(c); return () => { _formListener = null; }; }, []);
  if (!cfg) return null;
  return <FormModal {...cfg} wide={cfg.wide !== false} onClose={() => setCfg(null)} onSubmit={() => { setCfg(null); pushToast(cfg.done || 'Saved'); }} />;
}

Object.assign(window, {
  Icon, Badge, StatusBadge, Avatar, CustChip, Btn, Kpi, AINote, Gate,
  SectionHead, Bar, Ring, Drawer, ModulePlaceholder, ICONS,
  ToastHost, toast: pushToast, FormModal, FilterMenu, FormHost, openForm,
});
