// mailroom-theme.jsx — Mailroom · "warm-paper operator console"
// Token system (light=paper / dark=ink-blue console · density · accent),
// icon set, shared primitives.
// Exports to window: buildTokens, ThemeCtx, useT, hexA, Icon, Btn, IconBtn,
//   Chip, StatusChip, Toggle, Field, SearchBox, Card, Label, Mono, WarmBar, Marker.

const { createContext, useContext } = React;

function hexA(hex, a) {
  let h = hex.replace("#", "");
  if (h.length === 3) h = h.split("").map((c) => c + c).join("");
  const n = parseInt(h, 16);
  return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})`;
}

function buildTokens(mode, density, accent) {
  const dark = mode === "dark";
  const comf = density === "comfortable";
  const acc = accent || "#e0431f";

  const pal = dark
    ? {
        bg: "#0e1726", sunken: "#0a1120", card: "#15233a", card2: "#1b2c46", raise: "#22344f",
        border: "#283a54", borderStrong: "#3a4f6e",
        text: "#f3eee3", textSec: "#c3ccda", textMuted: "#8593a8",
        console: "#0a1120", consoleCard: "#15233a", consoleText: "#f3eee3", consoleMuted: "#8593a8",
      }
    : {
        bg: "#f5f1e8", sunken: "#ece5d6", card: "#faf7f0", card2: "#f5f1e8", raise: "#ffffff",
        border: "#ddd5c4", borderStrong: "#cabfa6",
        text: "#1c1814", textSec: "#4a4339", textMuted: "#897e6c",
        console: "#16233a", consoleCard: "#1d2d49", consoleText: "#f5f1e8", consoleMuted: "#8b97ac",
      };

  return {
    mode, density, dark, ...pal,
    accent: acc,
    accentHover: dark ? "#ef5a36" : "#c2371a",
    accentText: acc,
    accentTint: dark ? hexA(acc, 0.18) : "#fbe3da",
    accentBorder: dark ? hexA(acc, 0.5) : hexA(acc, 0.32),
    marker: "#f4d63f",
    markerTint: dark ? hexA("#f4d63f", 0.16) : "#fbf2c2",
    markerBorder: dark ? hexA("#f4d63f", 0.4) : "#e9d066",
    markerInk: dark ? "#f4d63f" : "#7a5e00",

    radius: 6, radiusSm: 4, radiusLg: 10, radiusPill: 999,
    fs: comf ? 14 : 13,
    pad: comf ? 22 : 17,
    padSm: comf ? 13 : 10,
    gap: comf ? 16 : 12,
    rowH: comf ? 48 : 40,
    ctrlH: comf ? 38 : 34,

    shadow: dark ? "none" : "0 1px 0 rgba(120,100,60,.04)",
    shadowMd: dark ? "0 8px 24px rgba(0,0,0,.45)" : "0 6px 18px rgba(90,72,40,.10)",
    shadowLg: dark ? "0 22px 60px rgba(0,0,0,.6)" : "0 20px 52px rgba(70,55,30,.18)",

    good: dark ? "#5fb877" : "#3c7d4e", goodTint: dark ? hexA("#5fb877", 0.16) : "#e2ecdc",
    warn: dark ? "#e0a83f" : "#b07818", warnTint: dark ? hexA("#e0a83f", 0.16) : "#f6e8cc",
    bad: dark ? "#e8675a" : "#c23b2e", badTint: dark ? hexA("#e8675a", 0.16) : "#f6dcd6",
    info: dark ? "#5b9fd6" : "#2f6690", infoTint: dark ? hexA("#5b9fd6", 0.16) : "#dde8f1",

    head: "'Space Grotesk', sans-serif",
    font: "'IBM Plex Sans', sans-serif",
    mono: "'Space Mono', monospace",
  };
}

const ThemeCtx = createContext(null);
const useT = () => useContext(ThemeCtx);

/* ---------------- Icons ---------------- */
const ICONS = {
  grid: <><rect x="3" y="3.5" width="8" height="8" rx="1"/><rect x="13" y="3.5" width="8" height="5" rx="1"/><rect x="13" y="11.5" width="8" height="9" rx="1"/><rect x="3" y="14.5" width="8" height="6" rx="1"/></>,
  campaigns: <><rect x="3" y="4" width="18" height="6" rx="1.5"/><rect x="3" y="13.5" width="11" height="6.5" rx="1.5"/><path d="M17 14h4M17 17.5h4"/></>,
  replies: <><path d="M9 7 4 12l5 5"/><path d="M4 12h10a6 6 0 0 1 6 6v1"/></>,
  ban: <><circle cx="12" cy="12" r="8.5"/><path d="m6 6 12 12"/></>,
  server: <><rect x="3" y="4" width="18" height="7" rx="1.5"/><rect x="3" y="13" width="18" height="7" rx="1.5"/><path d="M7 7.5h.01M7 16.5h.01"/></>,
  plug: <><path d="M9 2v6M15 2v6M7 8h10v3a5 5 0 0 1-10 0z"/><path d="M12 16v6"/></>,
  settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 0 1-4 0v-.1A1.6 1.6 0 0 0 7 19.4a1.6 1.6 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 2.6 14H2.5a2 2 0 0 1 0-4h.1A1.6 1.6 0 0 0 4.6 8a1.6 1.6 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 10 2.6h.1A2 2 0 0 1 14 2.6v.1a1.6 1.6 0 0 0 2.7 1.1l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0 1.1 2.7h.1a2 2 0 0 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1z"/></>,
  search: <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
  plus: <><path d="M12 5v14M5 12h14"/></>,
  sparkle: <><path d="M12 3l1.6 4.4L18 9l-4.4 1.6L12 15l-1.6-4.4L6 9l4.4-1.6z"/><path d="M18.5 14l.6 1.6 1.6.6-1.6.6-.6 1.6-.6-1.6-1.6-.6 1.6-.6z"/></>,
  mail: <><rect x="2.5" y="4.5" width="19" height="15" rx="1.5"/><path d="m3 6 9 6 9-6"/></>,
  clock: <><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></>,
  check: <><path d="M4 12.5l5 5 11-11"/></>,
  checkCircle: <><circle cx="12" cy="12" r="8.5"/><path d="M8.5 12l2.5 2.5 4.5-5"/></>,
  alert: <><path d="M12 3.5 22 20H2z"/><path d="M12 10v4M12 16.5v.4"/></>,
  alertCircle: <><circle cx="12" cy="12" r="8.5"/><path d="M12 8v4.5M12 16v.3"/></>,
  x: <><path d="M6 6l12 12M18 6 6 18"/></>,
  braces: <><path d="M7.5 4C6 4 5.5 5 5.5 6.4c0 1.6.2 2.6-1.3 2.6 1.5 0 1.3 1 1.3 2.6C5.5 13 6 14 7.5 14"/><path d="M16.5 4c1.5 0 2 1 2 2.4 0 1.6-.2 2.6 1.3 2.6-1.5 0-1.3 1-1.3 2.6 0 1.4-.5 2.4-2 2.4"/></>,
  eye: <><path d="M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12z"/><circle cx="12" cy="12" r="2.6"/></>,
  copy: <><rect x="8" y="8" width="12" height="12" rx="1.5"/><path d="M4 16V5a1 1 0 0 1 1-1h11"/></>,
  trash: <><path d="M4 7h16M9 7V5h6v2M6 7l1 13h10l1-13"/></>,
  arrowR: <><path d="M5 12h14M13 6l6 6-6 6"/></>,
  chevR: <><path d="m9 6 6 6-6 6"/></>,
  chevL: <><path d="m15 6-6 6 6 6"/></>,
  chevD: <><path d="m6 9 6 6 6-6"/></>,
  dot: <><circle cx="12" cy="12" r="3.5"/></>,
  upload: <><path d="M12 15V4M8 8l4-4 4 4"/><path d="M4 14v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4"/></>,
  send: <><path d="M21 4 3 11l6 2.5L12 20l3-7z"/><path d="M21 4 11 14"/></>,
  pause: <><rect x="7" y="5" width="3.5" height="14" rx="1"/><rect x="13.5" y="5" width="3.5" height="14" rx="1"/></>,
  play: <><path d="M7 5l11 7-11 7z"/></>,
  globe: <><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17M12 3.5c2.5 2.5 2.5 14.5 0 17M12 3.5c-2.5 2.5-2.5 14.5 0 17"/></>,
  shield: <><path d="M12 3 5 6v5c0 4.5 3 7.5 7 9 4-1.5 7-4.5 7-9V6z"/><path d="m9 12 2 2 4-4"/></>,
  calendar: <><rect x="3.5" y="5" width="17" height="15" rx="1.5"/><path d="M3.5 9.5h17M8 3v4M16 3v4"/></>,
  filter: <><path d="M3 5h18l-7 8v6l-4-2v-4z"/></>,
  more: <><circle cx="5" cy="12" r="1.4"/><circle cx="12" cy="12" r="1.4"/><circle cx="19" cy="12" r="1.4"/></>,
  external: <><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4"/></>,
  refresh: <><path d="M21 8a8 8 0 0 0-14.5-2.5L3 8M3 4v4h4"/><path d="M3 16a8 8 0 0 0 14.5 2.5L21 16M21 20v-4h-4"/></>,
  zap: <><path d="M13 3 4 14h7l-1 7 9-11h-7z"/></>,
  users: <><circle cx="9" cy="8" r="3.2"/><path d="M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6"/><path d="M16 5a3 3 0 0 1 0 6M21 20c0-2.8-1.6-5-4-5.7"/></>,
  target: <><circle cx="12" cy="12" r="8.5"/><circle cx="12" cy="12" r="4.8"/><circle cx="12" cy="12" r="1.3"/></>,
  trendUp: <><path d="M3 17l6-6 4 4 8-8"/><path d="M21 7v5h-5"/></>,
  trendDown: <><path d="M3 7l6 6 4-4 8 8"/><path d="M21 17v-5h-5"/></>,
  dollar: <><path d="M12 2v20M16.5 6.5C16 5 14.3 4 12 4 9.5 4 8 5.3 8 7c0 2 1.8 2.7 4 3.3 2.4.6 4 1.3 4 3.4 0 1.8-1.6 3.3-4 3.3-2.5 0-4.2-1-4.7-2.6"/></>,
  flame: <><path d="M12 22c4 0 7-2.7 7-6.5 0-3-1.5-4.5-3-6.5-.4 1.5-1.3 2-2 2 1-3-1-5.5-3-7 .3 3-1.8 4.7-3 6.3C6.6 11.4 5 13 5 15.5 5 19.3 8 22 12 22z"/></>,
  pencil: <><path d="M4 20h4l10.5-10.5a2 2 0 0 0-2.8-2.8L5 17v3z"/><path d="M13.5 6.5l3 3"/></>,
  flag: <><path d="M5 21V4M5 4h12l-2 4 2 4H5"/></>,
  link: <><path d="M10 13a4 4 0 0 0 5.66 0l2.5-2.5a4 4 0 1 0-5.66-5.66L11 6.34"/><path d="M14 11a4 4 0 0 0-5.66 0l-2.5 2.5a4 4 0 1 0 5.66 5.66L13 17.66"/></>,
  gauge: <><path d="M12 13.5 16 9"/><circle cx="12" cy="13.5" r="1.4"/><path d="M4.5 16.5a8.5 8.5 0 1 1 15 0"/></>,
  key: <><circle cx="8" cy="15" r="4"/><path d="m10.8 12.2 8.2-8.2M16 5l3 3M14 7l3 3"/></>,
  inbox: <><path d="M3 13l2.5-7.5A2 2 0 0 1 7.4 4h9.2a2 2 0 0 1 1.9 1.5L21 13v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M3 13h5l1.5 2.5h5L16 13h5"/></>,
  bolt: <><path d="M13 3 4 14h7l-1 7 9-11h-7z"/></>,
  building: <><rect x="4" y="3" width="16" height="18" rx="1.5"/><path d="M9 7h.01M15 7h.01M9 11h.01M15 11h.01M9 15h.01M15 15h.01M10 21v-3h4v3"/></>,
  rocket: <><path d="M12 3c3 1 6 4.5 6 9l-3 3H9l-3-3c0-4.5 3-8 6-9z"/><circle cx="12" cy="9" r="1.6"/><path d="M9 15c-2 1-2 4-2 4s3 0 4-2M15 15c2 1 2 4 2 4s-3 0-4-2"/></>,
  panelLeft: <><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M9 4v16"/></>,
  scissors: <><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><path d="M8 8l12 8M8 16 20 8"/></>,
  bounce: <><path d="M3 12h4l3-7 4 14 3-7h4"/></>,
  download: <><path d="M12 4v11M8 11l4 4 4-4"/><path d="M4 18v1a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-1"/></>,
  list: <><path d="M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01"/></>,
  sun: <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></>,
  moon: <><path d="M20 14.5A8 8 0 1 1 9.5 4 6.5 6.5 0 0 0 20 14.5z"/></>,
  arrowUpRight: <><path d="M7 17 17 7M8 7h9v9"/></>,
  analytics: <><path d="M4 20V4M4 20h16"/><rect x="7" y="11" width="3" height="6" rx="1"/><rect x="12" y="7" width="3" height="10" rx="1"/><rect x="17" y="13" width="3" height="4" rx="1"/></>,
};
function Icon({ name, size = 16, color = "currentColor", sw = 1.7, style }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
      strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"
      style={{ flex: "0 0 auto", display: "block", ...style }}>{ICONS[name] || ICONS.dot}</svg>
  );
}

/* ---------------- Primitives ---------------- */
function Btn({ kind = "soft", size, icon, iconR, children, onClick, style, title, full, disabled }) {
  const t = useT();
  const h = size === "sm" ? t.ctrlH - 4 : size === "lg" ? t.ctrlH + 8 : t.ctrlH;
  const base = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7,
    fontFamily: t.font, fontSize: size === "sm" ? 12.5 : 13.5, fontWeight: 600,
    cursor: disabled ? "not-allowed" : "pointer", border: "1px solid transparent", borderRadius: t.radiusSm,
    padding: `0 ${size === "sm" ? 11 : size === "lg" ? 18 : 14}px`, height: h, whiteSpace: "nowrap",
    lineHeight: 1, transition: "all .12s", width: full ? "100%" : "auto", opacity: disabled ? 0.5 : 1,
  };
  const kinds = {
    primary: { background: t.accent, color: "#fff", borderColor: t.accent },
    soft: { background: t.card, color: t.text, borderColor: t.borderStrong },
    ghost: { background: "transparent", color: t.textSec },
    accentSoft: { background: t.accentTint, color: t.accentText, borderColor: t.accentBorder },
    console: { background: t.consoleCard, color: t.consoleText, borderColor: hexA("#ffffff", 0.12) },
    danger: { background: t.badTint, color: t.bad, borderColor: hexA(t.bad, 0.3) },
    marker: { background: t.markerTint, color: t.markerInk, borderColor: t.markerBorder },
  };
  return (
    <button onClick={disabled ? undefined : onClick} title={title} style={{ ...base, ...kinds[kind], ...style }}>
      {icon && <Icon name={icon} size={size === "sm" ? 14 : 15} />}
      {children}
      {iconR && <Icon name={iconR} size={size === "sm" ? 14 : 15} />}
    </button>
  );
}
function IconBtn({ icon, size = 16, onClick, title, active, style }) {
  const t = useT();
  return (
    <button onClick={onClick} title={title} style={{
      width: t.ctrlH, height: t.ctrlH, borderRadius: t.radiusSm, flex: "0 0 auto",
      border: `1px solid ${active ? t.accentBorder : "transparent"}`, cursor: "pointer",
      background: active ? t.accentTint : "transparent", color: active ? t.accentText : t.textMuted,
      display: "flex", alignItems: "center", justifyContent: "center", transition: "all .12s", ...style,
    }}><Icon name={icon} size={size} /></button>
  );
}
// Chip — boxy label (radiusSm). Use for tags, metadata.
function Chip({ tone = "neutral", children, icon, mono, style }) {
  const t = useT();
  const map = {
    neutral: [t.dark ? t.sunken : t.bg, t.textMuted, t.border],
    accent: [t.accentTint, t.accentText, t.accentBorder],
    good: [t.goodTint, t.good, hexA(t.good, 0.32)],
    warn: [t.warnTint, t.warn, hexA(t.warn, 0.32)],
    bad: [t.badTint, t.bad, hexA(t.bad, 0.32)],
    info: [t.infoTint, t.info, hexA(t.info, 0.32)],
    marker: [t.markerTint, t.markerInk, t.markerBorder],
    console: [t.consoleCard, t.consoleText, hexA("#fff", 0.14)],
  };
  const [bg, fg, bd] = map[tone] || map.neutral;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5, background: bg, color: fg,
      border: `1px solid ${bd}`, borderRadius: t.radiusSm, padding: "2px 7px",
      fontSize: 11, fontWeight: 600, lineHeight: 1.45, letterSpacing: ".01em",
      fontFamily: mono ? t.mono : t.font, ...style,
    }}>{icon && <Icon name={icon} size={11} />}{children}</span>
  );
}
// StatusChip — the one rounded-pill exception (running/paused/awaiting).
function StatusChip({ tone = "neutral", children, dotPulse, style }) {
  const t = useT();
  const map = {
    neutral: [t.dark ? t.sunken : t.bg, t.textMuted, t.border, t.textMuted],
    good: [t.goodTint, t.good, hexA(t.good, 0.32), t.good],
    warn: [t.warnTint, t.warn, hexA(t.warn, 0.32), t.warn],
    bad: [t.badTint, t.bad, hexA(t.bad, 0.32), t.bad],
    accent: [t.accentTint, t.accentText, t.accentBorder, t.accent],
    marker: [t.markerTint, t.markerInk, t.markerBorder, "#c9a900"],
  };
  const [bg, fg, bd, dot] = map[tone] || map.neutral;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6, background: bg, color: fg,
      border: `1px solid ${bd}`, borderRadius: 999, padding: "3px 10px 3px 8px",
      fontSize: 11.5, fontWeight: 650, lineHeight: 1.3, fontFamily: t.font, ...style,
    }}>
      <span style={{ width: 6, height: 6, borderRadius: 999, background: dot, flex: "0 0 auto",
        animation: dotPulse ? "mrPulse 1.4s ease-in-out infinite" : "none" }} />
      {children}
    </span>
  );
}
function Toggle({ on, onClick, size = 1 }) {
  const t = useT();
  const w = 34 * size, h = 19 * size, k = h - 4;
  return (
    <span onClick={onClick} style={{
      width: w, height: h, borderRadius: 999, background: on ? t.accent : t.borderStrong,
      position: "relative", transition: "background .15s", flex: "0 0 auto", cursor: "pointer",
    }}>
      <span style={{ position: "absolute", top: 2, left: on ? w - k - 2 : 2, width: k, height: k,
        borderRadius: 999, background: "#fff", transition: "left .15s", boxShadow: "0 1px 2px rgba(0,0,0,.3)" }} />
    </span>
  );
}
function Field({ label, value, placeholder, mono, suffix, onChange, style, hint, area, rows = 4 }) {
  const t = useT();
  return (
    <label style={{ display: "block", ...style }}>
      {label && <Label style={{ marginBottom: 6 }}>{label}</Label>}
      {area ? (
        <textarea value={value} placeholder={placeholder} rows={rows}
          onChange={(e) => onChange && onChange(e.target.value)}
          style={{ width: "100%", border: `1px solid ${t.borderStrong}`, borderRadius: t.radiusSm,
            background: t.raise, padding: "10px 12px", outline: "none", resize: "vertical",
            font: "inherit", fontFamily: mono ? t.mono : t.font, fontSize: 13.5, color: t.text, lineHeight: 1.55 }} />
      ) : (
        <div style={{ display: "flex", alignItems: "center", gap: 8, height: t.ctrlH,
          border: `1px solid ${t.borderStrong}`, borderRadius: t.radiusSm, background: t.raise, padding: "0 11px" }}>
          <input value={value} placeholder={placeholder} onChange={(e) => onChange && onChange(e.target.value)}
            style={{ flex: 1, border: "none", outline: "none", background: "transparent",
              font: "inherit", fontFamily: mono ? t.mono : t.font, fontSize: 13.5, color: t.text, minWidth: 0 }} />
          {suffix && <span style={{ fontSize: 12, color: t.textMuted, fontFamily: t.mono }}>{suffix}</span>}
        </div>
      )}
      {hint && <div style={{ fontSize: 11.5, color: t.textMuted, marginTop: 5 }}>{hint}</div>}
    </label>
  );
}
function SearchBox({ placeholder = "Search", value, onChange, width }) {
  const t = useT();
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8, height: t.ctrlH, width,
      border: `1px solid ${t.border}`, borderRadius: t.radiusSm, background: t.dark ? t.sunken : t.bg, padding: "0 11px" }}>
      <Icon name="search" size={15} color={t.textMuted} />
      <input value={value} placeholder={placeholder} onChange={(e) => onChange && onChange(e.target.value)}
        style={{ flex: 1, border: "none", outline: "none", background: "transparent", font: "inherit",
          fontSize: 13, color: t.text, minWidth: 0 }} />
    </div>
  );
}
function Card({ children, pad = true, style, onClick, sunken }) {
  const t = useT();
  return (
    <div onClick={onClick} style={{
      background: sunken ? t.sunken : t.card, border: `1px solid ${t.border}`, borderRadius: t.radiusLg,
      boxShadow: sunken ? "none" : t.shadow, padding: pad ? t.pad : 0, cursor: onClick ? "pointer" : "default",
      transition: "border-color .12s", ...style,
    }}>{children}</div>
  );
}
function Label({ children, style }) {
  const t = useT();
  return <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: ".07em", textTransform: "uppercase",
    color: t.textMuted, fontFamily: t.font, ...style }}>{children}</div>;
}
function Mono({ children, style, color }) {
  const t = useT();
  return <span style={{ fontFamily: t.mono, color: color || t.text, ...style }}>{children}</span>;
}
// WarmBar — warmup heat 0..100, red→amber→green
function WarmBar({ val, h = 5, showLabel, t }) {
  const tt = t || useT();
  const color = val >= 80 ? tt.good : val >= 45 ? tt.warn : tt.bad;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8, width: "100%" }}>
      <div style={{ flex: 1, height: h, borderRadius: 2, background: tt.dark ? tt.sunken : "#e6ddc9", overflow: "hidden", minWidth: 36 }}>
        <div style={{ height: "100%", width: `${val}%`, background: color, borderRadius: 2, transition: "width .3s" }} />
      </div>
      {showLabel && <span style={{ fontFamily: tt.mono, fontSize: 11, color: tt.textMuted, width: 30, textAlign: "right" }}>{val}</span>}
    </div>
  );
}
// Marker — hand-drawn highlighter underline wrapper
function Marker({ children, style }) {
  const t = useT();
  return (
    <span style={{ position: "relative", display: "inline", ...style }}>
      <span style={{ position: "relative", zIndex: 1 }}>{children}</span>
      <span style={{ position: "absolute", left: -2, right: -2, bottom: 1, height: "42%",
        background: t.marker, opacity: t.dark ? 0.5 : 0.85, zIndex: 0, borderRadius: 1, transform: "rotate(-.6deg)" }} />
    </span>
  );
}

Object.assign(window, {
  buildTokens, ThemeCtx, useT, hexA, Icon, Btn, IconBtn, Chip, StatusChip,
  Toggle, Field, SearchBox, Card, Label, Mono, WarmBar, Marker,
});
