/* Shared CROPR-idiom UI primitives — buttons, inputs, badges, cards, modal,
   tabs, toggles. Inline styles referencing the design-system tokens in
   styles.css, matching the ui_kits/app patterns. Attached to window. */

function Button({ variant = "secondary", size = "md", icon, iconRight, children, onClick, disabled, title, style = {}, full }) {
  const [hover, setHover] = React.useState(false);
  const [press, setPress] = React.useState(false);
  const pad = size === "sm" ? "6px 11px" : size === "lg" ? "11px 18px" : "9px 14px";
  const fs = size === "sm" ? 12.5 : size === "lg" ? 15 : 13.5;
  const palette = {
    // Leap primary = the signature sky→coral gradient; hover brightens, nothing moves.
    primary: { bg: "var(--gradient-core)", fg: "#fff", bd: "transparent", grad: true },
    secondary: { bg: "var(--surface)", fg: "var(--fg1)", bd: "var(--border-strong)", hbd: "var(--leap-teal)", hbg: "var(--surface)", pbg: "var(--bg-muted)" },
    ghost: { bg: "transparent", fg: "var(--fg2)", bd: "transparent", hbg: "var(--accent-weak)", pbg: "var(--accent-weak)" },
    danger: { bg: "var(--surface)", fg: "var(--danger)", bd: "var(--danger)", hbg: "var(--danger-bg)", pbg: "var(--danger-bg)" },
    brand: { bg: "var(--gradient-core)", fg: "#fff", bd: "transparent", grad: true },
  }[variant];
  const s = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7,
    padding: pad, fontSize: fs, fontWeight: 600, fontFamily: "inherit", cursor: disabled ? "not-allowed" : "pointer",
    borderRadius: 11, border: `1px solid ${(hover && palette.hbd) ? palette.hbd : palette.bd}`,
    background: disabled ? "var(--bg-muted)" : palette.grad ? palette.bg : press ? palette.pbg : hover ? palette.hbg : palette.bg,
    color: disabled ? "var(--fg4)" : palette.fg,
    boxShadow: "none",
    // Leap: press darkens, nothing scales; gradient buttons brighten on hover.
    filter: disabled ? "none" : palette.grad ? (press ? "brightness(0.96)" : hover ? "brightness(1.05)" : "none") : (press ? "brightness(0.97)" : "none"),
    transition: "background 160ms var(--ease-standard), border-color 160ms, filter 160ms, color 160ms",
    width: full ? "100%" : undefined, whiteSpace: "nowrap", ...style,
  };
  return (
    <button title={title} disabled={disabled} onClick={onClick} style={s}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}
      onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}>
      {icon && <Icon name={icon} size={size === "sm" ? 15 : 17} color={disabled ? "var(--fg4)" : palette.fg} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === "sm" ? 15 : 17} color={disabled ? "var(--fg4)" : palette.fg} />}
    </button>
  );
}

function Field({ label, hint, children, right }) {
  return (
    <label style={{ display: "block", marginBottom: 14 }}>
      {label && (
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
          <span style={{ fontSize: 12, fontWeight: 600, color: "var(--fg2)" }}>{label}</span>
          {right}
        </div>
      )}
      {children}
      {hint && <div style={{ fontSize: 11.5, color: "var(--fg3)", marginTop: 5 }}>{hint}</div>}
    </label>
  );
}

const inputBase = {
  width: "100%", boxSizing: "border-box", fontFamily: "inherit", fontSize: 13.5, color: "var(--fg1)",
  background: "var(--surface)", border: "1px solid var(--border-strong)", borderRadius: 10, padding: "9px 11px",
  outline: "none", transition: "border-color 140ms, box-shadow 140ms",
};
function useFocusRing() {
  const [f, setF] = React.useState(false);
  const style = f ? { border: "1px solid var(--accent)", boxShadow: "var(--ring-focus)" } : {};
  return [{ onFocus: () => setF(true), onBlur: () => setF(false) }, style];
}
function TextInput({ value, onChange, placeholder, style = {}, ...rest }) {
  const [h, ring] = useFocusRing();
  return <input value={value} placeholder={placeholder} onChange={(e) => onChange && onChange(e.target.value)}
    {...h} style={{ ...inputBase, ...ring, ...style }} {...rest} />;
}
function TextArea({ value, onChange, placeholder, rows = 4, style = {}, onKeyDown }) {
  const [h, ring] = useFocusRing();
  return <textarea value={value} placeholder={placeholder} rows={rows} onKeyDown={onKeyDown}
    onChange={(e) => onChange && onChange(e.target.value)} {...h}
    style={{ ...inputBase, resize: "vertical", lineHeight: 1.5, ...ring, ...style }} />;
}
function Select({ value, onChange, options, style = {} }) {
  const [h, ring] = useFocusRing();
  return (
    <select className="cropr-caret" value={value == null ? "" : value} onChange={(e) => onChange && onChange(e.target.value)} {...h}
      style={{ ...inputBase, appearance: "none", cursor: "pointer", ...ring, ...style }}>
      {options.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
    </select>
  );
}

function Badge({ color = "var(--fg3)", bg, children, dot, style = {} }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 11.5, fontWeight: 600,
      padding: "3px 9px", borderRadius: 999, color, background: bg || "var(--bg-muted)", whiteSpace: "nowrap", ...style }}>
      {dot && <span style={{ width: 7, height: 7, borderRadius: 999, background: color }} />}
      {children}
    </span>
  );
}
function StatusBadge({ status }) {
  const meta = window.CROPR_DATA.STATUS_MAP[status] || {};
  // Prefer the (editable) workflow's stage name so renamed / custom stages read right.
  var label = meta.label || status;
  try { if (window.CroprStore && window.CroprStore.stageLabel) label = window.CroprStore.stageLabel(status); } catch (e) { /* */ }
  const color = meta.color || "var(--fg3)";
  return <Badge color={color} bg={color + "18"} dot>{label}</Badge>;
}

function Card({ children, style = {}, pad = 20, onClick, hover }) {
  const [h, setH] = React.useState(false);
  return (
    <div onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{ background: "var(--surface)", border: `1px solid ${h && hover ? "var(--leap-teal)" : "var(--border)"}`, borderRadius: 22,
        padding: pad, boxShadow: h && hover ? "var(--shadow-brand)" : "none",
        transform: h && hover ? "translateY(-2px)" : "none",
        transition: "box-shadow 160ms var(--ease-standard), border-color 160ms, transform 160ms var(--ease-standard)", cursor: onClick ? "pointer" : "default", ...style }}>
      {children}
    </div>
  );
}

function SectionTitle({ children, icon, right }) {
  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", margin: "2px 0 12px" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        {icon && <Icon name={icon} size={17} color="var(--accent)" />}
        <span style={{ fontSize: 11, fontWeight: 700, letterSpacing: ".06em", textTransform: "uppercase", color: "var(--fg3)" }}>{children}</span>
      </div>
      {right}
    </div>
  );
}

function Modal({ open, title, subtitle, onClose, children, footer, width = 560 }) {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(20,20,30,0.42)", backdropFilter: "blur(2px)",
      display: "grid", placeItems: "center", zIndex: 60, padding: 24 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width, maxWidth: "100%", maxHeight: "88vh", overflow: "auto",
        background: "var(--surface)", borderRadius: 20, boxShadow: "var(--shadow-xl)", border: "1px solid var(--border)" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "20px 22px 0" }}>
          <div>
            <h3 style={{ fontSize: 18, fontWeight: 700, letterSpacing: "-.01em" }}>{title}</h3>
            {subtitle && <div style={{ fontSize: 13, color: "var(--fg3)", marginTop: 3 }}>{subtitle}</div>}
          </div>
          <button onClick={onClose} style={{ border: 0, background: "var(--bg-muted)", borderRadius: 10, width: 34, height: 34,
            cursor: "pointer", display: "grid", placeItems: "center" }}><Icon name="x" size={18} /></button>
        </div>
        <div style={{ padding: "16px 22px" }}>{children}</div>
        {footer && <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, padding: "14px 22px",
          borderTop: "1px solid var(--border)", background: "var(--bg-subtle)", borderRadius: "0 0 20px 20px" }}>{footer}</div>}
      </div>
    </div>
  );
}

// A reusable "are you sure?" dialog — replaces native confirm(), which some
// embedded/webview contexts silently suppress. Pass open + the labels + handlers.
function ConfirmDialog({ open, title, message, confirmLabel = "Delete", cancelLabel = "Cancel", danger = true, onConfirm, onCancel }) {
  return (
    <Modal open={open} title={title || "Are you sure?"} onClose={onCancel} width={440}
      footer={<React.Fragment>
        <Button variant="secondary" onClick={onCancel}>{cancelLabel}</Button>
        <Button variant={danger ? "danger" : "primary"} onClick={onConfirm}>{confirmLabel}</Button>
      </React.Fragment>}>
      <div style={{ fontSize: 13.5, color: "var(--fg2)", lineHeight: 1.55 }}>{message}</div>
    </Modal>
  );
}
window.ConfirmDialog = ConfirmDialog;

function Segmented({ value, onChange, options }) {
  return (
    <div style={{ display: "inline-flex", background: "var(--bg-muted)", borderRadius: 10, padding: 3, gap: 2 }}>
      {options.map((o) => {
        const on = o.value === value;
        return (
          <button key={o.value} onClick={() => onChange(o.value)} style={{ border: 0, cursor: "pointer",
            padding: "6px 12px", borderRadius: 8, fontSize: 12.5, fontWeight: 600, fontFamily: "inherit",
            background: on ? "var(--surface)" : "transparent", color: on ? "var(--fg1)" : "var(--fg3)",
            boxShadow: on ? "var(--shadow-xs)" : "none", transition: "all 140ms", display: "flex", alignItems: "center", gap: 6 }}>
            {o.iconNode ? o.iconNode : (o.icon && <Icon name={o.icon} size={15} color={on ? "var(--accent)" : "var(--fg3)"} />)}{o.label}
          </button>
        );
      })}
    </div>
  );
}

/* Official platform brand logos (X, LinkedIn, Telegram) — as attached. */
function PlatformLogo({ platform, size = 18, style = {} }) {
  const common = { width: size, height: size, viewBox: "0 0 24 24", style: { display: "block", ...style } };
  if (platform === "x") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#000" /><path fill="#fff" d="M17.53 5h2.2l-4.8 5.49L20.5 19h-4.4l-3.45-4.51L8.6 19H6.4l5.14-5.87L5.7 5h4.5l3.12 4.13L17.53 5zm-.77 12.6h1.22L9.3 6.32H8L16.76 17.6z" /></svg>);
  if (platform === "linkedin") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#0A66C2" /><path fill="#fff" d="M8.34 18.5H5.67V9.9h2.67v8.6zM7 8.73a1.55 1.55 0 1 1 0-3.1 1.55 1.55 0 0 1 0 3.1zM18.5 18.5h-2.67v-4.18c0-1-.02-2.28-1.39-2.28-1.39 0-1.6 1.08-1.6 2.2v4.26h-2.67V9.9h2.56v1.17h.04c.36-.68 1.23-1.39 2.53-1.39 2.7 0 3.2 1.78 3.2 4.1v4.71z" /></svg>);
  if (platform === "telegram") return (
    <svg {...common}><circle cx="12" cy="12" r="12" fill="#229ED9" /><path fill="#fff" d="M5.5 11.9 16.8 7.5c.53-.19 1 .13.82.94l-1.92 9.05c-.13.6-.5.75-1 .47l-2.75-2.03-1.33 1.28c-.15.15-.27.27-.55.27l.2-2.82 5.14-4.65c.22-.2-.05-.31-.34-.11L7.4 13.06l-2.72-.85c-.59-.19-.6-.6.14-.89z" /></svg>);
  if (platform === "facebook") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#1877F2" /><path fill="#fff" d="M13.5 21v-7h2.3l.4-2.75H13.5V9.4c0-.79.22-1.33 1.36-1.33h1.45V5.62c-.25-.03-1.11-.11-2.11-.11-2.09 0-3.52 1.28-3.52 3.62v2.02H8.4V14h2.28v7h2.82z" /></svg>);
  if (platform === "instagram") return (
    <svg {...common}><defs><linearGradient id="lp-ig" x1="2" y1="22" x2="22" y2="2" gradientUnits="userSpaceOnUse"><stop offset="0" stopColor="#FEDA75" /><stop offset=".28" stopColor="#FA7E1E" /><stop offset=".5" stopColor="#D62976" /><stop offset=".74" stopColor="#962FBF" /><stop offset="1" stopColor="#4F5BD5" /></linearGradient></defs><rect width="24" height="24" rx="5" fill="url(#lp-ig)" /><rect x="6" y="6" width="12" height="12" rx="3.6" fill="none" stroke="#fff" strokeWidth="1.6" /><circle cx="12" cy="12" r="3" fill="none" stroke="#fff" strokeWidth="1.6" /><circle cx="15.6" cy="8.4" r="1" fill="#fff" /></svg>);
  if (platform === "tiktok") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#010101" /><path fill="#fff" d="M15 5c.3 1.6 1.3 2.8 2.9 3v2.2c-1 .05-1.95-.22-2.9-.75v4.85a4.2 4.2 0 1 1-4.2-4.2c.2 0 .4.02.6.05v2.3a1.95 1.95 0 1 0 1.4 1.87V5H15z" /></svg>);
  if (platform === "pinterest") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#E60023" /><path fill="#fff" d="M12 5.5c-3.6 0-5.5 2.4-5.5 4.9 0 1.2.65 2.6 1.7 3 .16.06.24.03.28-.12l.12-.5c.04-.14.02-.2-.08-.32-.36-.43-.58-.98-.58-1.77 0-2.28 1.7-4.32 4.44-4.32 2.42 0 3.75 1.48 3.75 3.46 0 2.6-1.15 4.8-2.86 4.8-.95 0-1.65-.78-1.43-1.74.27-1.15.8-2.38.8-3.2 0-.74-.4-1.36-1.22-1.36-.97 0-1.75 1-1.75 2.35 0 .86.3 1.44.3 1.44l-1.16 4.9c-.28 1.2-.13 2.66-.06 3.05.02.09.13.11.19.04.09-.11 1.2-1.48 1.58-2.85.1-.39.6-2.36.6-2.36.3.56 1.16 1.05 2.07 1.05 2.73 0 4.58-2.49 4.58-5.82 0-2.52-2.13-4.7-5.37-4.7z" /></svg>);
  if (platform === "youtube") return (
    <svg {...common}><rect width="24" height="24" rx="5" fill="#FF0000" /><path fill="#fff" d="M10 8.3l6.2 3.7L10 15.7z" /></svg>);
  return null;
}

function Avatar({ color, initials, size = 40, src }) {
  return <span style={{ width: size, height: size, borderRadius: 999, background: color, color: "#fff", flex: "none",
    display: "grid", placeItems: "center", fontSize: size * 0.34, fontWeight: 700, overflow: "hidden" }}>
    {src ? <img src={src} alt="" style={{ width: size * 0.58, height: size * 0.58, display: "block" }} /> : initials}
  </span>;
}

// placeholder shown for posts that don't have a visual yet
const NO_VISUAL = "data:image/svg+xml;utf8," + encodeURIComponent(
  "<svg xmlns='http://www.w3.org/2000/svg' width='320' height='200'><rect width='320' height='200' fill='#EEF1F3'/><g stroke='#B6BEC6' stroke-width='2.5' fill='none' stroke-linejoin='round' stroke-linecap='round'><rect x='120' y='60' width='80' height='58' rx='7'/><circle cx='143' cy='80' r='7'/><path d='M126 112 L152 92 L168 104 L182 90 L194 112'/></g><text x='160' y='150' font-family='sans-serif' font-size='15' fill='#8A929B' text-anchor='middle' font-weight='600'>No visual yet</text></svg>");

// first attached image on a post (top-level media, else the first channel's media)
function postThumb(post) {
  if (!post) return null;
  if (post.media && post.media.url) return post.media.url;
  const c = (post.content || []).find((v) => v.media && v.media.length && v.media[0] && v.media[0].url);
  return c ? c.media[0].url : null;
}

// a small rounded thumbnail that reveals a large floating preview on hover.
// Rendered through a body portal so it's never clipped by list overflow.
function HoverImage({ src, alt, size = 38, radius = 8, label }) {
  const [rect, setRect] = React.useState(null);
  const ref = React.useRef(null);
  if (!src) return null;
  const show = () => { const el = ref.current; if (el) setRect(el.getBoundingClientRect()); };
  const hide = () => setRect(null);
  let pop = null;
  if (rect) {
    const PW = 300, PH = 300;
    let left = rect.right + 12;
    if (left + PW > window.innerWidth - 8) left = rect.left - PW - 12;
    left = Math.max(8, left);
    let top = rect.top + rect.height / 2 - PH / 2;
    top = Math.max(8, Math.min(top, window.innerHeight - PH - 8));
    pop = { left, top, PW, PH };
  }
  const overlay = pop && ReactDOM.createPortal(
    <div style={{ position: "fixed", left: pop.left, top: pop.top, zIndex: 90, width: pop.PW, background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 14, boxShadow: "var(--shadow-lg)", padding: 8, pointerEvents: "none" }}>
      <img src={src} alt={alt || ""} style={{ width: "100%", height: pop.PH - 16, objectFit: "cover", borderRadius: 8, display: "block" }} />
      {label && <div style={{ fontSize: 11.5, color: "var(--fg3)", padding: "7px 4px 2px", lineHeight: 1.35 }}>{label}</div>}
    </div>, document.body);
  return (
    <span ref={ref} onMouseEnter={show} onMouseLeave={hide} onClick={(e) => e.stopPropagation()}
      style={{ display: "inline-flex", flex: "none", lineHeight: 0 }}>
      <img src={src} alt={alt || ""} title="Hover to preview"
        style={{ width: size, height: size, objectFit: "cover", borderRadius: radius, border: "1px solid var(--border)", display: "block", cursor: "zoom-in", background: "var(--bg-muted)" }} />
      {overlay}
    </span>
  );
}

// Shared asset-library picker modal. Two modes:
//  · onToggle  → multi-select (tiles toggle, modal stays open, Done to close)
//  · onPick    → single pick (choosing a tile fires onPick then closes)
// selectedUrls highlights already-chosen assets. imagesOnly hides video assets.
function AssetPicker({ open, onClose, onToggle, onPick, selectedUrls, title, subtitle, imagesOnly }) {
  const S = window.CroprStore;
  const [q, setQ] = React.useState("");
  if (!open) return null;
  const sel = selectedUrls || [];
  let assets = S.getAssets();
  if (imagesOnly) assets = assets.filter((a) => a.kind !== "video");
  const ql = q.trim().toLowerCase();
  const list = assets.filter((a) => !ql || (a.name + " " + (a.keywords || []).join(" ")).toLowerCase().includes(ql));
  const handle = (a) => { if (onToggle) onToggle(a); else if (onPick) { onPick(a); onClose && onClose(); } };
  return (
    <Modal open={true} title={title || "Choose from Assets"} subtitle={subtitle || "Pick from this account's asset library."} width={720}
      onClose={onClose} footer={<Button variant="primary" icon="check" onClick={onClose}>Done</Button>}>
      <div style={{ position: "relative", marginBottom: 14 }}>
        <Icon name="search" size={16} color="var(--fg4)" style={{ position: "absolute", left: 11, top: "50%", transform: "translateY(-50%)" }} />
        <TextInput value={q} onChange={setQ} placeholder="Search name or keywords…" style={{ paddingLeft: 34 }} />
      </div>
      {list.length === 0 ? (
        <div style={{ textAlign: "center", padding: "34px 12px", color: "var(--fg3)" }}>
          <Icon name="image" size={28} color="var(--fg4)" />
          <div style={{ fontSize: 14, fontWeight: 700, marginTop: 8 }}>{assets.length ? "No assets match your search" : "Your asset library is empty"}</div>
          <div style={{ fontSize: 12.5, marginTop: 3 }}>{assets.length ? "Try a different term." : "Add assets in the Assets section, or upload one here."}</div>
        </div>
      ) : (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(140px,1fr))", gap: 12 }}>
          {list.map((a) => {
            const on = sel.includes(a.url);
            return (
              <button key={a.id} type="button" onClick={() => handle(a)}
                style={{ position: "relative", padding: 0, border: `2px solid ${on ? "var(--accent)" : "var(--border)"}`, borderRadius: 12, overflow: "hidden", cursor: "pointer", background: "var(--bg-subtle)", fontFamily: "inherit", textAlign: "left" }}>
                <div style={{ height: 96, background: "var(--gradient-core)", display: "grid", placeItems: "center", overflow: "hidden" }}>
                  {a.url ? (a.kind === "video" ? <video src={a.url} muted style={{ width: "100%", height: "100%", objectFit: "cover" }} /> : <img src={a.url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />) : <Icon name="image" size={22} color="#fff" />}
                  {on && <span style={{ position: "absolute", top: 6, right: 6, width: 22, height: 22, borderRadius: 999, background: "var(--accent)", display: "grid", placeItems: "center" }}><Icon name="check" size={14} color="#fff" /></span>}
                </div>
                <div style={{ padding: "7px 9px" }}>
                  <div style={{ fontSize: 12, fontWeight: 700, color: "var(--fg1)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.name}</div>
                  <div style={{ fontSize: 10.5, color: "var(--fg3)" }}>{a.category}</div>
                </div>
              </button>
            );
          })}
        </div>
      )}
    </Modal>
  );
}

// Emoji picker button — a small popover grid; onPick(emoji) fires per tap
// (stays open so several can be added). Pair it with a text field's onChange.
function EmojiPicker({ onPick, title = "Add emoji" }) {
  const [open, setOpen] = React.useState(false);
  const EMOJIS = ["😀", "😄", "😅", "😂", "🙂", "😊", "😍", "🤩", "😎", "🤗", "🤔", "🙌", "👏", "👍", "👋", "🙏", "💪", "🔥", "✨", "🎉", "🥳", "☕", "🍵", "🥤", "🌊", "🌿", "🍃", "🍂", "🌱", "🌟", "⭐", "❤️", "🧡", "💛", "💚", "💙", "💜", "☀️", "🌙", "⚡", "💡", "📈", "📊", "✅", "➡️", "🔗", "📌", "🎯", "🚀", "🏆", "💬", "📣", "🗓️", "⏰", "🎁", "🛒", "💯", "👀", "🤝", "📷", "🎬", "🎥", "🎨", "📝", "🙈", "😉", "😋", "🤤"];
  return (
    <div style={{ position: "relative", display: "inline-flex" }}>
      <button type="button" title={title} onClick={() => setOpen((o) => !o)}
        style={{ border: "1px solid var(--border-strong)", background: "var(--surface)", borderRadius: 8, width: 30, height: 30, cursor: "pointer", display: "grid", placeItems: "center", fontSize: 15, lineHeight: 1 }}>😊</button>
      {open && (
        <React.Fragment>
          <div onClick={() => setOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 60 }} />
          <div style={{ position: "absolute", top: 36, right: 0, zIndex: 61, width: 268, maxHeight: 208, overflowY: "auto", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 12, boxShadow: "var(--shadow-lg)", padding: 8, display: "grid", gridTemplateColumns: "repeat(8, 1fr)", gap: 2 }}>
            {EMOJIS.map((e, i) => (
              <button key={i} type="button" onClick={() => onPick(e)}
                style={{ border: 0, background: "transparent", cursor: "pointer", fontSize: 18, lineHeight: 1, height: 30, borderRadius: 7 }}
                onMouseEnter={(ev) => (ev.currentTarget.style.background = "var(--bg-muted)")} onMouseLeave={(ev) => (ev.currentTarget.style.background = "transparent")}>{e}</button>
            ))}
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

function Toast({ toast }) {
  if (!toast) return null;
  const good = toast.kind !== "error";
  return (
    <div style={{ position: "fixed", bottom: 22, left: "50%", transform: "translateX(-50%)", zIndex: 80,
      display: "flex", alignItems: "center", gap: 10, padding: "11px 16px", borderRadius: 12,
      background: "var(--fg1)", color: "#fff", boxShadow: "var(--shadow-lg)", fontSize: 13.5, fontWeight: 500, maxWidth: 520 }}>
      <Icon name={good ? "check-circle" : "alert-triangle"} size={18} color={good ? "#5CE9A6" : "#FFB4AC"} />
      {toast.msg}
    </div>
  );
}

Object.assign(window, { Button, Field, TextInput, TextArea, Select, Badge, StatusBadge, Card, SectionTitle, Modal, Segmented, PlatformLogo, Avatar, Toast, HoverImage, postThumb, AssetPicker, EmojiPicker, NO_VISUAL });
