// PortalTable Dashboard — shadcn-pattern primitives, styled to PortalTable (light Stratum) tokens.
// Each component is portal/state-driven, accessible-ish, and reads CSS vars so it tracks the theme.
// Depends on: React (global), Ic + Logo (from pd-brand.jsx), DS Button/Avatar/Kbd (on window).

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

/* ========================================================================== */
/* Surface — the standard card/panel used everywhere                          */
/* ========================================================================== */
function Surface({ children, style = {}, pad = 0, hover = false, ...rest }) {
  const [h, setH] = useState(false);
  return (
    <div
      onMouseEnter={() => hover && setH(true)}
      onMouseLeave={() => hover && setH(false)}
      style={{
        background: "var(--ink-900)",
        border: `1px solid ${h ? "var(--line-3)" : "var(--line-2)"}`,
        borderRadius: 12,
        padding: pad,
        boxShadow: "var(--pd-shadow-xs)",
        transition: "border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out)",
        ...style,
      }}
      {...rest}
    >
      {children}
    </div>
  );
}

/* ========================================================================== */
/* Pill — light-tuned status tag (the DS Badge hardcodes dark-mode colors)     */
/* ========================================================================== */
const PILL_TONES = {
  neutral: { fg: "var(--fg-2)", bg: "var(--ink-800)", bd: "var(--line-2)" },
  green: { fg: "var(--green)", bg: "var(--green-soft)", bd: "rgba(21,147,94,0.28)" },
  amber: { fg: "var(--amber)", bg: "var(--amber-soft)", bd: "rgba(181,121,11,0.28)" },
  red: { fg: "var(--red)", bg: "var(--red-soft)", bd: "rgba(200,68,59,0.26)" },
  blue: { fg: "var(--blue)", bg: "var(--blue-soft)", bd: "rgba(45,111,224,0.26)" },
  teal: { fg: "var(--teal)", bg: "var(--teal-soft)", bd: "rgba(14,152,136,0.26)" },
  accent: { fg: "var(--accent-ink)", bg: "var(--accent-soft)", bd: "var(--accent-line)" },
};
function Pill({ tone = "neutral", children, dot = false, style = {} }) {
  const t = PILL_TONES[tone] || PILL_TONES.neutral;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6, height: 22, padding: "0 9px",
      borderRadius: 999, fontSize: 11.5, fontWeight: 500, lineHeight: 1, whiteSpace: "nowrap",
      color: t.fg, background: t.bg, border: `1px solid ${t.bd}`, ...style,
    }}>
      {dot && <span style={{ width: 6, height: 6, borderRadius: 999, background: t.fg, flexShrink: 0 }} />}
      {children}
    </span>
  );
}

/* ========================================================================== */
/* IconButton — square ghost control                                           */
/* ========================================================================== */
function IconButton({ icon, label, onClick, size = 32, active = false, style = {} }) {
  const [h, setH] = useState(false);
  return (
    <button type="button" onClick={onClick} aria-label={label} title={label}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        width: size, height: size, display: "grid", placeItems: "center", borderRadius: 8,
        background: active || h ? "var(--ink-800)" : "transparent",
        border: `1px solid ${active ? "var(--line-3)" : "transparent"}`,
        color: active || h ? "var(--fg-1)" : "var(--fg-3)", cursor: "pointer",
        transition: "background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out)",
        ...style,
      }}>
      <Ic name={icon} size={17} />
    </button>
  );
}

/* ========================================================================== */
/* Tabs — underline style                                                      */
/* ========================================================================== */
function Tabs({ tabs, value, onChange, style = {} }) {
  return (
    <div role="tablist" style={{ display: "flex", alignItems: "center", gap: 2, borderBottom: "1px solid var(--line-2)", maxWidth: "100%", overflowX: "auto", scrollbarWidth: "none", ...style }}>
      {tabs.map((t) => {
        const id = typeof t === "string" ? t : t.id;
        const label = typeof t === "string" ? t : t.label;
        const count = typeof t === "object" ? t.count : undefined;
        const active = value === id;
        return (
          <button key={id} role="tab" aria-selected={active} onClick={() => onChange(id)}
            style={{
              position: "relative", display: "inline-flex", alignItems: "center", gap: 7, flexShrink: 0, whiteSpace: "nowrap",
              padding: "0 12px", height: 38, background: "transparent", border: 0, cursor: "pointer",
              fontSize: 13.5, fontWeight: active ? 600 : 500, fontFamily: "inherit",
              color: active ? "var(--fg-1)" : "var(--fg-3)",
              transition: "color var(--dur-2) var(--ease-out)",
            }}
            onMouseEnter={(e) => { if (!active) e.currentTarget.style.color = "var(--fg-1)"; }}
            onMouseLeave={(e) => { if (!active) e.currentTarget.style.color = "var(--fg-3)"; }}>
            {label}
            {count !== undefined && (
              <span style={{
                fontSize: 11, fontFamily: "var(--font-mono)", padding: "1px 6px", borderRadius: 999,
                background: active ? "var(--accent-soft)" : "var(--ink-800)",
                color: active ? "var(--accent-ink)" : "var(--fg-3)", border: `1px solid ${active ? "var(--accent-line)" : "var(--line-2)"}`,
              }}>{count}</span>
            )}
            <span style={{
              position: "absolute", left: 6, right: 6, bottom: -1, height: 2, borderRadius: 2,
              background: active ? "var(--fg-1)" : "transparent",
              transition: "background var(--dur-2) var(--ease-out)",
            }} />
          </button>
        );
      })}
    </div>
  );
}

/* ========================================================================== */
/* SegmentedControl — for date ranges etc.                                     */
/* ========================================================================== */
function Segmented({ options, value, onChange, style = {} }) {
  return (
    <div style={{
      display: "inline-flex", padding: 3, gap: 2, borderRadius: 9,
      background: "var(--ink-800)", border: "1px solid var(--line-2)", ...style,
    }}>
      {options.map((o) => {
        const id = typeof o === "string" ? o : o.id;
        const label = typeof o === "string" ? o : o.label;
        const active = value === id;
        return (
          <button key={id} onClick={() => onChange(id)}
            style={{
              padding: "0 12px", height: 28, borderRadius: 7, border: 0, cursor: "pointer",
              fontSize: 12.5, fontWeight: 500, fontFamily: "inherit",
              background: active ? "var(--ink-900)" : "transparent",
              color: active ? "var(--fg-1)" : "var(--fg-3)",
              boxShadow: active ? "var(--pd-shadow-xs)" : "none",
              transition: "all var(--dur-2) var(--ease-out)",
            }}>
            {label}
          </button>
        );
      })}
    </div>
  );
}

/* ========================================================================== */
/* SearchInput                                                                  */
/* ========================================================================== */
function SearchInput({ value, onChange, placeholder = "Search…", style = {}, onFocus, width }) {
  const [focused, setFocused] = useState(false);
  return (
    <div style={{ position: "relative", width: width || "auto", ...style }}>
      <span style={{ position: "absolute", left: 11, top: "50%", transform: "translateY(-50%)", color: "var(--fg-3)", pointerEvents: "none" }}>
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></svg>
      </span>
      <input value={value} placeholder={placeholder}
        onChange={(e) => onChange && onChange(e.target.value)}
        onFocus={(e) => { setFocused(true); onFocus && onFocus(e); }} onBlur={() => setFocused(false)}
        style={{
          width: "100%", height: 34, padding: "0 11px 0 32px", boxSizing: "border-box",
          borderRadius: 8, fontSize: 13.5, background: "var(--ink-900)", color: "var(--fg-1)",
          border: `1px solid ${focused ? "var(--accent-press)" : "var(--line-3)"}`,
          boxShadow: focused ? "var(--focus-ring)" : "none", outline: "none",
          transition: "border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out)",
        }} />
    </div>
  );
}

/* ========================================================================== */
/* useFloating — popover positioning + outside-click + escape close            */
/* ========================================================================== */
function usePopover() {
  const [open, setOpen] = useState(false);
  const anchorRef = useRef(null);
  const popRef = useRef(null);
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (anchorRef.current && anchorRef.current.contains(e.target)) return;
      if (popRef.current && popRef.current.contains(e.target)) return;
      setOpen(false);
    };
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => { document.removeEventListener("mousedown", onDoc); document.removeEventListener("keydown", onKey); };
  }, [open]);
  return { open, setOpen, anchorRef, popRef };
}

/* ========================================================================== */
/* DropdownMenu — trigger + items, right- or left-aligned                      */
/* ========================================================================== */
function DropdownMenu({ trigger, items, align = "right", width = 200 }) {
  const { open, setOpen, anchorRef, popRef } = usePopover();
  return (
    <div style={{ position: "relative", display: "inline-flex" }}>
      <span ref={anchorRef} onClick={() => setOpen((o) => !o)}>{trigger(open)}</span>
      {open && (
        <div ref={popRef} role="menu"
          style={{
            position: "absolute", top: "calc(100% + 6px)", [align]: 0, width, zIndex: 60,
            background: "var(--ink-900)", border: "1px solid var(--line-2)", borderRadius: 11,
            boxShadow: "var(--pd-shadow-lg)", padding: 6,
            animation: "ddPop 140ms var(--ease-out)", transformOrigin: align === "right" ? "top right" : "top left",
          }}>
          {items.map((it, i) =>
            it.separator ? (
              <div key={i} style={{ height: 1, background: "var(--line-2)", margin: "5px 4px" }} />
            ) : it.label && it.header ? (
              <div key={i} style={{ padding: "6px 9px 4px", fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--fg-4)" }}>{it.label}</div>
            ) : (
              <MenuItem key={i} item={it} onClose={() => setOpen(false)} />
            )
          )}
        </div>
      )}
    </div>
  );
}
function MenuItem({ item, onClose }) {
  const [h, setH] = useState(false);
  const danger = item.tone === "danger";
  return (
    <button role="menuitem"
      onClick={() => { item.onClick && item.onClick(); onClose(); }}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        width: "100%", display: "flex", alignItems: "center", gap: 10, padding: "8px 9px",
        borderRadius: 7, border: 0, cursor: "pointer", textAlign: "left",
        fontSize: 13, fontWeight: 500, fontFamily: "inherit",
        background: h ? (danger ? "var(--red-soft)" : "var(--ink-800)") : "transparent",
        color: danger ? "var(--red)" : h ? "var(--fg-1)" : "var(--fg-2)",
        transition: "background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out)",
      }}>
      {item.icon && <Ic name={item.icon} size={15} style={{ opacity: 0.9 }} />}
      <span style={{ flex: 1 }}>{item.label}</span>
      {item.kbd && <Kbd>{item.kbd}</Kbd>}
      {item.trailing}
    </button>
  );
}

/* ========================================================================== */
/* Switch                                                                       */
/* ========================================================================== */
function Switch({ checked, onChange, id }) {
  return (
    <button id={id} role="switch" aria-checked={checked} onClick={() => onChange(!checked)}
      style={{
        width: 38, height: 22, borderRadius: 999, border: "1px solid",
        borderColor: checked ? "var(--accent-press)" : "var(--line-3)",
        background: checked ? "var(--accent)" : "var(--ink-800)",
        position: "relative", cursor: "pointer", padding: 0, flexShrink: 0,
        transition: "background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out)",
      }}>
      <span style={{
        position: "absolute", top: 2, left: checked ? 18 : 2, width: 16, height: 16, borderRadius: 999,
        background: checked ? "var(--fg-inverse)" : "#fff", boxShadow: "0 1px 2px rgba(16,18,22,0.25)",
        transition: "left var(--dur-2) var(--ease-out)",
      }} />
    </button>
  );
}

/* ========================================================================== */
/* DataTable — sortable columns, optional row selection + row click            */
/* columns: [{ key, header, width, align, sortable, render(row), sortVal(row) }]*/
/* ========================================================================== */
function DataTable({ columns, rows, getId = (r) => r.id, selectable = false, onRowClick, initialSort, dense = false }) {
  const [sort, setSort] = useState(initialSort || { key: null, dir: "asc" });
  const [selected, setSelected] = useState(() => new Set());

  const sorted = React.useMemo(() => {
    if (!sort.key) return rows;
    const col = columns.find((c) => c.key === sort.key);
    const val = col && col.sortVal ? col.sortVal : (r) => r[sort.key];
    const out = [...rows].sort((a, b) => {
      const av = val(a), bv = val(b);
      if (av < bv) return -1; if (av > bv) return 1; return 0;
    });
    return sort.dir === "desc" ? out.reverse() : out;
  }, [rows, sort, columns]);

  function toggleSort(key) {
    setSort((s) => s.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: "asc" });
  }
  const allSel = selectable && sorted.length > 0 && sorted.every((r) => selected.has(getId(r)));
  function toggleAll() {
    setSelected(() => allSel ? new Set() : new Set(sorted.map(getId)));
  }
  function toggleOne(id) {
    setSelected((prev) => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  }
  const rowH = dense ? 44 : 54;

  return (
    <div style={{ width: "100%", overflowX: "auto" }}>
      {selectable && selected.size > 0 && (
        <div style={{
          display: "flex", alignItems: "center", gap: 12, padding: "10px 16px", marginBottom: 0,
          background: "var(--accent-soft)", borderBottom: "1px solid var(--accent-line)",
        }}>
          <span style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-1)" }}>{selected.size} selected</span>
          <div style={{ display: "flex", gap: 8, marginLeft: "auto" }}>
            <Button variant="ghost" size="sm" onClick={() => setSelected(new Set())}>Clear</Button>
            <Button variant="secondary" size="sm" icon="message">Email</Button>
            <Button variant="secondary" size="sm" icon="upload">Export</Button>
          </div>
        </div>
      )}
      <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13.5 }}>
        <thead>
          <tr style={{ borderBottom: "1px solid var(--line-2)" }}>
            {selectable && (
              <th style={{ width: 44, padding: "0 0 0 16px", textAlign: "left" }}>
                <CheckSquare checked={allSel} indeterminate={selected.size > 0 && !allSel} onChange={toggleAll} />
              </th>
            )}
            {columns.map((c) => {
              const active = sort.key === c.key;
              return (
                <th key={c.key} style={{
                  padding: dense ? "9px 14px" : "11px 16px", textAlign: c.align || "left", width: c.width,
                  fontFamily: "var(--font-mono)", fontSize: 10.5, fontWeight: 500, letterSpacing: "0.07em",
                  textTransform: "uppercase", color: "var(--fg-3)", whiteSpace: "nowrap",
                  userSelect: "none", cursor: c.sortable ? "pointer" : "default",
                }}
                  onClick={c.sortable ? () => toggleSort(c.key) : undefined}>
                  <span style={{ display: "inline-flex", alignItems: "center", gap: 5, justifyContent: c.align === "right" ? "flex-end" : "flex-start" }}>
                    {c.header}
                    {c.sortable && (
                      <span style={{ display: "inline-flex", flexDirection: "column", lineHeight: 0, color: active ? "var(--fg-1)" : "var(--fg-4)" }}>
                        <svg width="8" height="11" viewBox="0 0 8 11" fill="none">
                          <path d="M4 0L7 4H1L4 0Z" fill={active && sort.dir === "asc" ? "currentColor" : "var(--line-4)"} />
                          <path d="M4 11L1 7H7L4 11Z" fill={active && sort.dir === "desc" ? "currentColor" : "var(--line-4)"} />
                        </svg>
                      </span>
                    )}
                  </span>
                </th>
              );
            })}
          </tr>
        </thead>
        <tbody>
          {sorted.map((row) => {
            const id = getId(row);
            const sel = selected.has(id);
            return (
              <Row key={id} height={rowH} clickable={!!onRowClick} selected={sel} onClick={onRowClick ? () => onRowClick(row) : undefined}>
                {selectable && (
                  <td style={{ padding: "0 0 0 16px" }} onClick={(e) => e.stopPropagation()}>
                    <CheckSquare checked={sel} onChange={() => toggleOne(id)} />
                  </td>
                )}
                {columns.map((c) => (
                  <td key={c.key} style={{ padding: dense ? "0 14px" : "0 16px", textAlign: c.align || "left", color: "var(--fg-2)", verticalAlign: "middle" }}>
                    {c.render ? c.render(row) : row[c.key]}
                  </td>
                ))}
              </Row>
            );
          })}
          {sorted.length === 0 && (
            <tr><td colSpan={columns.length + (selectable ? 1 : 0)} style={{ padding: "48px 16px", textAlign: "center", color: "var(--fg-3)", fontSize: 13.5 }}>No results.</td></tr>
          )}
        </tbody>
      </table>
    </div>
  );
}
function Row({ children, height, clickable, selected, onClick }) {
  const [h, setH] = useState(false);
  return (
    <tr onClick={onClick}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        height, borderBottom: "1px solid var(--line-1)", cursor: clickable ? "pointer" : "default",
        background: selected ? "var(--accent-soft)" : h && clickable ? "var(--ink-800)" : "transparent",
        transition: "background var(--dur-1) var(--ease-out)",
      }}>
      {children}
    </tr>
  );
}
function CheckSquare({ checked, indeterminate = false, onChange }) {
  return (
    <button onClick={(e) => { e.stopPropagation(); onChange(); }} role="checkbox" aria-checked={checked}
      style={{
        width: 18, height: 18, borderRadius: 5, display: "grid", placeItems: "center", padding: 0, cursor: "pointer",
        background: checked || indeterminate ? "var(--accent)" : "var(--ink-900)",
        border: `1px solid ${checked || indeterminate ? "var(--accent-press)" : "var(--line-3)"}`,
        color: "var(--fg-inverse)", transition: "all var(--dur-1) var(--ease-out)",
      }}>
      {checked && <Ic name="check" size={12} strokeWidth={2.6} />}
      {indeterminate && !checked && <span style={{ width: 8, height: 2, borderRadius: 2, background: "var(--fg-inverse)" }} />}
    </button>
  );
}

/* ========================================================================== */
/* Modal primitive (center dialog) + Sheet (right drawer)                      */
/* ========================================================================== */
function Overlay({ onClose, children, justify = "center", padding = 24 }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <div onMouseDown={onClose}
      style={{
        position: "fixed", inset: 0, zIndex: 90, background: "rgba(16,18,22,0.34)",
        backdropFilter: "blur(4px)", display: "flex", alignItems: justify === "center" ? "center" : "stretch",
        justifyContent: justify === "right" ? "flex-end" : "center", padding: justify === "right" ? 0 : padding,
        animation: "pdFade 160ms var(--ease-out)",
      }}>
      {children}
    </div>
  );
}
function Dialog({ open, onClose, title, eyebrow, children, footer, width = 460 }) {
  if (!open) return null;
  return (
    <Overlay onClose={onClose}>
      <div onMouseDown={(e) => e.stopPropagation()}
        style={{
          width: "100%", maxWidth: width, background: "var(--ink-900)", border: "1px solid var(--line-2)",
          borderRadius: 16, boxShadow: "var(--pd-shadow-lg)", animation: "pdPop 200ms var(--ease-out)", overflow: "hidden",
        }}>
        <div style={{ padding: "22px 24px 0", position: "relative" }}>
          <button onClick={onClose} aria-label="Close" style={closeBtnStyle}>
            <Ic name="x" size={16} />
          </button>
          {eyebrow && <div className="pd-eyebrow" style={{ marginBottom: 8 }}>{eyebrow}</div>}
          {title && <h3 style={{ fontSize: 19, color: "var(--fg-1)", letterSpacing: "-0.02em", margin: 0, fontWeight: 600 }}>{title}</h3>}
        </div>
        <div style={{ padding: "16px 24px 22px" }}>{children}</div>
        {footer && (
          <div style={{ padding: "14px 24px", borderTop: "1px solid var(--line-2)", background: "var(--ink-950)", display: "flex", justifyContent: "flex-end", gap: 10 }}>
            {footer}
          </div>
        )}
      </div>
    </Overlay>
  );
}
function Sheet({ open, onClose, title, eyebrow, children, footer, width = 460 }) {
  if (!open) return null;
  return (
    <Overlay onClose={onClose} justify="right" padding={0}>
      <div onMouseDown={(e) => e.stopPropagation()}
        style={{
          width: "100%", maxWidth: width, height: "100%", background: "var(--ink-900)",
          borderLeft: "1px solid var(--line-2)", boxShadow: "var(--pd-shadow-lg)",
          display: "flex", flexDirection: "column", animation: "sheetIn 240ms var(--ease-out)",
        }}>
        <div style={{ padding: "20px 24px", borderBottom: "1px solid var(--line-2)", position: "relative", flexShrink: 0 }}>
          <button onClick={onClose} aria-label="Close" style={closeBtnStyle}><Ic name="x" size={16} /></button>
          {eyebrow && <div className="pd-eyebrow" style={{ marginBottom: 7 }}>{eyebrow}</div>}
          {title && <h3 style={{ fontSize: 18, color: "var(--fg-1)", letterSpacing: "-0.02em", margin: 0, fontWeight: 600 }}>{title}</h3>}
        </div>
        <div style={{ flex: 1, overflowY: "auto", padding: 24 }}>{children}</div>
        {footer && (
          <div style={{ padding: "14px 24px", borderTop: "1px solid var(--line-2)", background: "var(--ink-950)", display: "flex", justifyContent: "flex-end", gap: 10, flexShrink: 0 }}>
            {footer}
          </div>
        )}
      </div>
    </Overlay>
  );
}
const closeBtnStyle = {
  position: "absolute", top: 16, right: 16, width: 30, height: 30, display: "grid", placeItems: "center",
  borderRadius: 8, background: "transparent", border: "1px solid transparent", color: "var(--fg-3)", cursor: "pointer",
};

/* ========================================================================== */
/* Toasts — global host + emit helper                                          */
/* ========================================================================== */
function toast(opts) {
  window.dispatchEvent(new CustomEvent("pd-toast", { detail: typeof opts === "string" ? { title: opts } : opts }));
}
window.pdToast = toast;
function ToastHost() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const onToast = (e) => {
      const id = Math.random().toString(36).slice(2);
      const t = { id, tone: "neutral", ...e.detail };
      setItems((prev) => [...prev, t]);
      setTimeout(() => setItems((prev) => prev.filter((x) => x.id !== id)), t.duration || 3800);
    };
    window.addEventListener("pd-toast", onToast);
    return () => window.removeEventListener("pd-toast", onToast);
  }, []);
  const ic = { success: "check", error: "x", info: "sparkle", neutral: "check" };
  const col = { success: "var(--green)", error: "var(--red)", info: "var(--teal)", neutral: "var(--fg-1)" };
  return (
    <div style={{ position: "fixed", bottom: 22, right: 22, zIndex: 120, display: "flex", flexDirection: "column", gap: 10, pointerEvents: "none" }}>
      {items.map((t) => (
        <div key={t.id} style={{
          minWidth: 300, maxWidth: 380, display: "flex", alignItems: "flex-start", gap: 12, padding: "13px 15px",
          background: "var(--ink-900)", border: "1px solid var(--line-2)", borderRadius: 12,
          boxShadow: "var(--pd-shadow-lg)", animation: "toastIn 260ms var(--ease-out)", pointerEvents: "auto",
        }}>
          <span style={{ flexShrink: 0, marginTop: 1, width: 22, height: 22, borderRadius: 7, display: "grid", placeItems: "center", background: t.tone === "neutral" ? "var(--accent)" : "transparent", color: t.tone === "neutral" ? "var(--fg-inverse)" : col[t.tone] }}>
            <Ic name={ic[t.tone] || "check"} size={t.tone === "neutral" ? 13 : 18} strokeWidth={2.2} />
          </span>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-1)" }}>{t.title}</div>
            {t.body && <div style={{ fontSize: 12.5, color: "var(--fg-2)", marginTop: 3, lineHeight: 1.5 }}>{t.body}</div>}
          </div>
        </div>
      ))}
    </div>
  );
}

/* ========================================================================== */
/* Progress bar                                                                 */
/* ========================================================================== */
function Progress({ value, tone = "accent", height = 6 }) {
  const colors = { accent: "var(--accent-press)", green: "var(--green)", amber: "var(--amber)", blue: "var(--blue)", teal: "var(--teal)" };
  return (
    <div style={{ width: "100%", height, borderRadius: 999, background: "var(--ink-800)", overflow: "hidden" }}>
      <div style={{ width: `${Math.max(0, Math.min(100, value))}%`, height: "100%", borderRadius: 999, background: colors[tone], transition: "width var(--dur-4) var(--ease-out)" }} />
    </div>
  );
}

/* ========================================================================== */
/* DemoSwitch — Agency ↔ Client perspective toggle, shown in the sidebar.      */
/* Tells the parent /demo page which iframe to show (postMessage); falls back  */
/* to a direct page navigation when opened standalone.                        */
/* ========================================================================== */
function pdDemoSwitchTo(side) {
  try {
    if (window.parent && window.parent !== window) {
      // Same-origin parent (the /demo page) — restrict delivery to our origin.
      window.parent.postMessage({ type: "pd-demo-switch", side }, window.location.origin);
      return;
    }
  } catch (e) { /* cross-origin parent — fall through */ }
  window.location.href = side === "client" ? "client-portal.html" : "dashboard.html";
}
function DemoSwitchIcon({ side }) {
  return side === "agency" ? (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="9" rx="1" /><rect x="14" y="3" width="7" height="5" rx="1" /><rect x="14" y="12" width="7" height="9" rx="1" /><rect x="3" y="16" width="7" height="5" rx="1" /></svg>
  ) : (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z" /><circle cx="12" cy="12" r="2.5" /></svg>
  );
}
function DemoSwitch({ current }) {
  const items = [
    { id: "agency", label: "Agency", title: "The console you manage" },
    { id: "client", label: "Client", title: "What your client sees" },
  ];
  return (
    <div style={{ padding: "12px 12px 6px" }}>
      <div style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, fontWeight: 600, letterSpacing: "0.12em", color: "var(--fg-4)", padding: "0 2px 7px" }}>DEMO · VIEWING AS</div>
      <div style={{ display: "flex", gap: 3, padding: 3, borderRadius: 10, background: "var(--ink-800)", border: "1px solid var(--line-2)" }}>
        {items.map((it) => {
          const active = it.id === current;
          return (
            <button key={it.id} type="button" title={it.title} aria-pressed={active}
              onClick={() => { if (!active) pdDemoSwitchTo(it.id); }}
              style={{
                flex: 1, display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7,
                height: 32, borderRadius: 7, border: 0, cursor: active ? "default" : "pointer",
                fontFamily: "inherit", fontSize: 12.5, fontWeight: 600,
                background: active ? "var(--accent)" : "transparent",
                color: active ? "var(--accent-ink)" : "var(--fg-3)",
                transition: "background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out)",
              }}>
              <DemoSwitchIcon side={it.id} />{it.label}
            </button>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, {
  Surface, Pill, IconButton, Tabs, Segmented, SearchInput, usePopover,
  DropdownMenu, Switch, DataTable, CheckSquare, Dialog, Sheet, Overlay, ToastHost, toast, Progress,
  DemoSwitch, pdDemoSwitchTo,
});
