// components.jsx — Shared UI primitives + layout shells
const { useState, useEffect, useRef, useCallback } = React;

// ─── ICONS ────────────────────────────────────────────────────────────────────
const Icon = {
  Dashboard:    () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="1" y="1" width="6" height="6" rx="1.5" fill="currentColor" opacity="0.9"/><rect x="9" y="1" width="6" height="6" rx="1.5" fill="currentColor" opacity="0.4"/><rect x="1" y="9" width="6" height="6" rx="1.5" fill="currentColor" opacity="0.4"/><rect x="9" y="9" width="6" height="6" rx="1.5" fill="currentColor" opacity="0.9"/></svg>,
  Tracking:     () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.2" opacity="0.35"/><circle cx="8" cy="8" r="4" stroke="currentColor" strokeWidth="1.2" opacity="0.65"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><line x1="8" y1="1" x2="8" y2="3" stroke="currentColor" strokeWidth="1.2"/><line x1="8" y1="13" x2="8" y2="15" stroke="currentColor" strokeWidth="1.2"/><line x1="1" y1="8" x2="3" y2="8" stroke="currentColor" strokeWidth="1.2"/><line x1="13" y1="8" x2="15" y2="8" stroke="currentColor" strokeWidth="1.2"/></svg>,
  Analytics:    () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="1" y="9" width="3" height="6" rx="1" fill="currentColor" opacity="0.5"/><rect x="5.5" y="6" width="3" height="9" rx="1" fill="currentColor" opacity="0.75"/><rect x="10" y="3" width="3" height="12" rx="1" fill="currentColor"/></svg>,
  Alerts:       () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 1.5a5 5 0 0 1 5 5v3l1 2H2l1-2V6.5a5 5 0 0 1 5-5z" stroke="currentColor" strokeWidth="1.2"/><path d="M6.5 12.5a1.5 1.5 0 0 0 3 0" stroke="currentColor" strokeWidth="1.2"/></svg>,
  Pricing:      () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 1.5L9.8 5.6L14.3 6.1L11.1 9.1L12 13.5L8 11.3L4 13.5L4.9 9.1L1.7 6.1L6.2 5.6Z" stroke="currentColor" strokeWidth="1.2" fill="none"/></svg>,
  Settings:     () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="2.5" stroke="currentColor" strokeWidth="1.2"/><path d="M8 1v1.5M8 13.5V15M1 8h1.5M13.5 8H15M2.93 2.93l1.06 1.06M12.01 12.01l1.06 1.06M13.07 2.93l-1.06 1.06M3.99 12.01l-1.06 1.06" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></svg>,
  User:         () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="5.5" r="3" stroke="currentColor" strokeWidth="1.2"/><path d="M2 14c0-3.314 2.686-5 6-5s6 1.686 6 5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Group:        () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="5.5" cy="5" r="2.5" stroke="currentColor" strokeWidth="1.2"/><circle cx="10.5" cy="5" r="2.5" stroke="currentColor" strokeWidth="1.2"/><path d="M1 14c0-2.761 2.015-4.5 4.5-4.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/><path d="M15 14c0-2.761-2.015-4.5-4.5-4.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Plus:         () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 1v12M1 7h12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  Minus:        () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M1 7h12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  Close:        () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  Trash:        () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 3.5h10M5 3.5V2h4v1.5M5.5 6v4.5M8.5 6v4.5M3 3.5l.7 8h6.6l.7-8" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Bell:         () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 1.5a5 5 0 0 1 5 5v3l1 2H2l1-2V6.5a5 5 0 0 1 5-5z" stroke="currentColor" strokeWidth="1.2"/><path d="M6.5 12.5a1.5 1.5 0 0 0 3 0" stroke="currentColor" strokeWidth="1.2"/></svg>,
  Logout:       () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M6 2H3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/><path d="M10.5 11L14 8l-3.5-3M14 8H6" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Copy:         () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="4" y="4" width="8" height="8" rx="1.5" stroke="currentColor" strokeWidth="1.2"/><path d="M10 4V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h1" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Eye:          () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M1 7s2.5-4.5 6-4.5S13 7 13 7s-2.5 4.5-6 4.5S1 7 1 7z" stroke="currentColor" strokeWidth="1.2"/><circle cx="7" cy="7" r="1.8" stroke="currentColor" strokeWidth="1.2"/></svg>,
  Shield:       () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 1.5L2 4v4c0 3.5 2.5 6.3 6 7.5 3.5-1.2 6-4 6-7.5V4L8 1.5z" stroke="currentColor" strokeWidth="1.2" fill="none"/><path d="M5.5 8l1.5 1.5L10.5 6" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Discord:      () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M13.5 2.5A13 13 0 0 0 10.3 1.5a9 9 0 0 0-.4.8A12 12 0 0 0 6.1 2.3a9 9 0 0 0-.4-.8 13 13 0 0 0-3.2 1 13.7 13.7 0 0 0-2.4 9.3 13 13 0 0 0 4 2 9.7 9.7 0 0 0 .8-1.3A8.5 8.5 0 0 1 3.5 12l.3.2a9.5 9.5 0 0 0 8.4 0l.3-.2a8.5 8.5 0 0 1-1.4.7 9.7 9.7 0 0 0 .8 1.3 13 13 0 0 0 4-2 13.7 13.7 0 0 0-2.4-9.5z" fill="currentColor" opacity="0.9"/><circle cx="5.8" cy="9" r="1.3" fill="var(--bg0)"/><circle cx="10.2" cy="9" r="1.3" fill="var(--bg0)"/></svg>,
  Check:        () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 6l3 3 5-5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ArrowRight:   () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M3 7h8M8 4l3 3-3 3" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ChevronRight: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  ChevronDown:  () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 4l4 4 4-4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Refresh:      () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M12 7A5 5 0 1 1 7 2a5 5 0 0 1 3.5 1.4L13 2" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><path d="M13 2v3h-3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Search:       () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="currentColor" strokeWidth="1.3"/><path d="M9.5 9.5L13 13" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>,
  Key:          () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="6" cy="7" r="3.5" stroke="currentColor" strokeWidth="1.2"/><path d="M8.5 9.5L13 14M11 11.5l1.5 1.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  Bolt:         () => <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 1L4 9h5l-2 6 7-8H9l2-6z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round"/></svg>,
  Flag:         () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 1v12M2 2h8l-2 3.5L10 9H2" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Clock:        () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5.5" stroke="currentColor" strokeWidth="1.2"/><path d="M7 4v3.5L9.5 9" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Game:         () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="1" y="4" width="12" height="7" rx="2" stroke="currentColor" strokeWidth="1.2"/><path d="M4 7.5h2M5 6.5v2" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/><circle cx="9" cy="7" r="0.7" fill="currentColor"/><circle cx="10.5" cy="8.2" r="0.7" fill="currentColor"/></svg>,
  ExternalLink: () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M5 2H2a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/><path d="M8 1h3v3M11 1L6 6" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Sort:         () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 3h8M3 6h6M4 9h4" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/></svg>,
  SortUp:       () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M6 9V3M3 6l3-3 3 3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  SortDown:     () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M6 3v6M3 6l3 3 3-3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  Filter:       () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M1 3h12M3 7h8M5 11h4" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></svg>,
  Cmd:          () => <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M4 2a2 2 0 1 0 0 4h4a2 2 0 1 0 0-4H4zM4 6H2a2 2 0 1 0 4 0V6zM8 6h2a2 2 0 1 1-4 0V6z" stroke="currentColor" strokeWidth="1.1" fill="none"/></svg>,
};

// ─── BUTTON ───────────────────────────────────────────────────────────────────
const Btn = ({ children, variant = 'primary', size = 'md', onClick, disabled, style = {}, icon }) => {
  const sizes = {
    sm: { padding: '6px 13px', fontSize: 13 },
    md: { padding: '9px 18px', fontSize: 14 },
    lg: { padding: '11px 22px', fontSize: 15 },
    xl: { padding: '14px 30px', fontSize: 16 },
  };
  const variants = {
    primary:   { background: 'var(--p5)', color: '#fff', border: '1px solid transparent', boxShadow: '0 1px 2px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.06) inset' },
    secondary: { background: 'var(--bg3)', color: 'var(--t1)', border: '1px solid var(--border2)' },
    ghost:     { background: 'transparent', color: 'var(--t2)', border: '1px solid var(--border)' },
    danger:    { background: 'var(--red-dim)', color: 'var(--red)', border: '1px solid rgba(248,113,113,0.2)' },
    outline:   { background: 'transparent', color: 'var(--p4)', border: '1px solid var(--border-bright)' },
  };
  const hovers = {
    primary:   { filter: 'brightness(1.12)', boxShadow: '0 4px 16px rgba(99,102,241,0.4), 0 0 0 1px rgba(255,255,255,0.06) inset' },
    secondary: { background: 'var(--bg4)', borderColor: 'var(--border2)' },
    ghost:     { background: 'rgba(255,255,255,0.04)', color: 'var(--t1)' },
    danger:    { background: 'rgba(248,113,113,0.14)' },
    outline:   { background: 'var(--p-dim)', color: 'var(--p3)' },
  };
  const [hov, setHov] = useState(false);
  return (
    <button onClick={onClick} disabled={disabled}
      onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 7,
        cursor: disabled ? 'not-allowed' : 'pointer', border: 'none',
        fontFamily: 'var(--font)', fontWeight: 600, letterSpacing: '-0.01em',
        transition: 'all 0.18s var(--ease-out-expo)', borderRadius: 'var(--r2)',
        whiteSpace: 'nowrap', opacity: disabled ? 0.45 : 1,
        ...sizes[size], ...variants[variant], ...(hov && !disabled ? hovers[variant] : {}), ...style,
      }}>
      {icon && icon}{children}
    </button>
  );
};

// ─── BADGE ────────────────────────────────────────────────────────────────────
const Badge = ({ children, color = 'purple', size = 'sm' }) => {
  const colors = {
    purple: { bg: 'var(--p-dim)', color: 'var(--p4)', border: 'rgba(99,102,241,0.25)' },
    green:  { bg: 'var(--green-dim)', color: 'var(--green)', border: 'rgba(52,211,153,0.2)' },
    red:    { bg: 'var(--red-dim)', color: 'var(--red)', border: 'rgba(248,113,113,0.2)' },
    amber:  { bg: 'var(--amber-dim)', color: 'var(--amber)', border: 'rgba(251,191,36,0.2)' },
    blue:   { bg: 'var(--blue-dim)', color: 'var(--blue)', border: 'rgba(96,165,250,0.2)' },
    gray:   { bg: 'rgba(255,255,255,0.05)', color: 'var(--t3)', border: 'rgba(255,255,255,0.08)' },
  };
  const c = colors[color] || colors.gray;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: size === 'xs' ? '2px 6px' : '3px 8px',
      fontSize: size === 'xs' ? 10 : 11, fontWeight: 500,
      letterSpacing: '0.02em', borderRadius: 5,
      background: c.bg, color: c.color, border: `1px solid ${c.border}`,
      fontFamily: 'var(--font)',
    }}>
      {children}
    </span>
  );
};

// ─── STATUS DOTS ──────────────────────────────────────────────────────────────
const GlowDot = ({ status, size = 8 }) => {
  const map = {
    online:    { color: 'var(--green)',  anim: 'glow-ring-green 2.4s ease-in-out infinite' },
    'in-game': { color: 'var(--amber)',  anim: 'glow-ring-amber 2.4s ease-in-out infinite' },
    invisible: { color: 'var(--blue)',   anim: 'glow-ring-purple 2.4s ease-in-out infinite' },
    offline:   { color: 'var(--t4)',     anim: 'none' },
  };
  const s = map[status] || map.offline;
  return <span style={{ width: size, height: size, borderRadius: '50%', background: s.color, flexShrink: 0, display: 'inline-block', animation: s.anim }} />;
};

const StatusDot = ({ status }) => {
  const map = {
    online:    { color: 'var(--green)', anim: 'pulse-dot 2s ease-in-out infinite',   label: 'Online' },
    'in-game': { color: 'var(--amber)', anim: 'pulse-amber 2s ease-in-out infinite', label: 'In-Game' },
    invisible: { color: 'var(--blue)',  anim: 'none',                                label: 'Invisible' },
    offline:   { color: 'var(--t4)',    anim: 'none',                                label: 'Offline' },
  };
  const s = map[status] || map.offline;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap' }}>
      <GlowDot status={status} size={7} />
      <span style={{ fontSize: 12, color: s.color }}>{s.label}</span>
    </span>
  );
};

// ─── AVATAR (Roblox-style) ───────────────────────────────────────────────────
// Stable username → Roblox user ID map so each user maps to the same avatar.
const ROBLOX_IDS = {
  'admin':            '1',
  'xShadowReaper':    '285113055',
  'FrostClan_Leader': '398412773',
  'VelocityX99':      '104561190',
  'Phantom_Wolf':     '776523400',
  'DarkMatter_X':     '13365322',
  'NightOwl_99':      '2470023',
  'ShadowRift_7':     '261',
  'ClanLord_V':       '156',
  'GhostRunner':      '1894058',
  'AzureFrost':       '48103520',
  'VortexGaming':     '168',
  'RedShift_99':      '1494',
};

const _hashName = (s) => { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0; return h; };
const ROBLOX_SKIN  = ['#F8C471','#F3B700','#E8A33D','#D9A066','#C68642','#A0613B','#FDD9A0'];
const ROBLOX_SHIRT = ['#4F46E5','#16A34A','#DC2626','#2563EB','#7C3AED','#0891B2','#EA580C','#DB2777'];

// classic Roblox blocky headshot, rendered locally (always works, no network)
const RobloxAvatarSVG = ({ name, size }) => {
  const h = _hashName(name);
  const skin = ROBLOX_SKIN[h % ROBLOX_SKIN.length];
  const shirt = ROBLOX_SHIRT[(h >> 4) % ROBLOX_SHIRT.length];
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{ display: 'block' }}>
      <rect width="40" height="40" fill="#15161A" />
      {/* shoulders / shirt */}
      <rect x="5" y="31" width="30" height="11" rx="4" fill={shirt} />
      <rect x="5" y="31" width="30" height="4" rx="2" fill="rgba(255,255,255,0.12)" />
      {/* neck */}
      <rect x="16.5" y="25" width="7" height="7" fill={skin} />
      <rect x="16.5" y="25" width="7" height="7" fill="rgba(0,0,0,0.12)" />
      {/* head */}
      <rect x="9" y="6.5" width="22" height="20.5" rx="4.5" fill={skin} />
      {/* eyes */}
      <rect x="14" y="13.5" width="3.2" height="4.4" rx="1.4" fill="#222" />
      <rect x="22.8" y="13.5" width="3.2" height="4.4" rx="1.4" fill="#222" />
      {/* classic smile */}
      <path d="M14.5 20.5 Q20 24.8 25.5 20.5" stroke="#222" strokeWidth="1.7" fill="none" strokeLinecap="round" />
    </svg>
  );
};

// global cache for real Roblox headshots — proxied through our API to avoid CORS
const _rbxCache = {};
const _API = 'https://api.rostealth.site';
function fetchRobloxHeadshot(id) {
  if (!id) return Promise.resolve(null);
  if (_rbxCache[id]) return _rbxCache[id];
  _rbxCache[id] = fetch(`${_API}/api/roblox/avatar?id=${id}`)
    .then(r => r.json())
    .then(j => j.avatarUrl || null)
    .catch(() => null);
  return _rbxCache[id];
}

const Avatar = ({ name = '?', size = 32, color, status, robloxId }) => {
  const rid = robloxId || ROBLOX_IDS[name];
  const [realUrl, setRealUrl] = useState(null);
  useEffect(() => {
    let alive = true;
    setRealUrl(null);
    if (rid) fetchRobloxHeadshot(rid).then(url => { if (alive && url) setRealUrl(url); });
    return () => { alive = false; };
  }, [rid]);
  const ringGlows = {
    online:    '0 0 0 2px var(--bg2), 0 0 0 3.5px #34D399, 0 0 10px rgba(52,211,153,0.4)',
    'in-game': '0 0 0 2px var(--bg2), 0 0 0 3.5px #FBBF24, 0 0 10px rgba(251,191,36,0.4)',
    invisible: '0 0 0 2px var(--bg2), 0 0 0 3.5px #60A5FA, 0 0 10px rgba(96,165,250,0.3)',
    offline:   'none',
  };
  return (
    <div style={{
      width: size, height: size, borderRadius: size * 0.28,
      position: 'relative', flexShrink: 0, overflow: 'hidden',
      border: '1.5px solid rgba(255,255,255,0.08)',
      boxShadow: status ? (ringGlows[status] || 'none') : 'none',
      transition: 'box-shadow 0.3s var(--ease-out-expo)',
    }}>
      {/* always-present Roblox-style base */}
      <RobloxAvatarSVG name={name} size={size} />
      {/* upgrade to real headshot if reachable */}
      {realUrl && (
        <img src={realUrl} alt={name} onError={() => setRealUrl(null)}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block', background: '#15161A' }} />
      )}
    </div>
  );
};

// ─── CARD ─────────────────────────────────────────────────────────────────────
const Card = ({ children, style = {}, hover = false, glow = false }) => {
  const [hov, setHov] = useState(false);
  return (
    <div onMouseEnter={() => hover && setHov(true)} onMouseLeave={() => hover && setHov(false)}
      style={{
        padding: 20,
        background: 'var(--bg2)',
        border: `1px solid ${hov ? 'rgba(99,102,241,0.25)' : 'var(--border)'}`,
        borderRadius: 'var(--r3)',
        transition: 'border-color 0.2s, box-shadow 0.2s',
        boxShadow: glow ? '0 0 40px rgba(99,102,241,0.06)' : (hov ? '0 8px 32px rgba(0,0,0,0.3)' : 'none'),
        ...style,
      }}>
      {children}
    </div>
  );
};

// ─── INPUT ────────────────────────────────────────────────────────────────────
const Input = ({ value, onChange, placeholder, type = 'text', icon, style = {}, onKeyDown, autoFocus }) => {
  const [focus, setFocus] = useState(false);
  return (
    <div style={{ position: 'relative' }}>
      {icon && <span style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: focus ? 'var(--p4)' : 'var(--t3)', pointerEvents: 'none', transition: 'color 0.15s' }}>{icon}</span>}
      <input type={type} value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder}
        onKeyDown={onKeyDown} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} autoFocus={autoFocus}
        style={{
          width: '100%', padding: icon ? '10px 14px 10px 36px' : '10px 14px',
          background: 'var(--bg3)', border: `1px solid ${focus ? 'var(--border-bright)' : 'var(--border)'}`,
          borderRadius: 'var(--r2)', color: 'var(--t1)', fontSize: 14, fontFamily: 'var(--font)', outline: 'none',
          boxShadow: focus ? '0 0 0 3px rgba(99,102,241,0.12)' : 'none',
          transition: 'all 0.18s', ...style,
        }} />
    </div>
  );
};

// ─── DRAWER ───────────────────────────────────────────────────────────────────
const Drawer = ({ open, onClose, children, width = 440 }) => {
  const [visible, setVisible] = useState(open);
  const [animOut, setAnimOut] = useState(false);
  useEffect(() => {
    if (open) { setVisible(true); setAnimOut(false); }
    else if (visible) {
      setAnimOut(true);
      const t = setTimeout(() => setVisible(false), 260);
      return () => clearTimeout(t);
    }
  }, [open]);
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    if (visible) window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [visible, onClose]);
  if (!visible) return null;
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 500, display: 'flex', justifyContent: 'flex-end', animation: animOut ? 'overlay-out 0.26s ease both' : 'overlay-in 0.22s ease both' }}>
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(4,5,10,0.7)', backdropFilter: 'blur(6px)' }} onClick={onClose} />
      <div style={{ position: 'relative', width, maxWidth: '92vw', height: '100%', background: 'var(--bg1)', borderLeft: '1px solid var(--border)', display: 'flex', flexDirection: 'column', overflowY: 'auto', animation: animOut ? 'drawer-out 0.26s var(--ease-out-expo) both' : 'drawer-in 0.3s var(--ease-out-expo) both' }}>
        {children}
      </div>
    </div>
  );
};

// ─── CMD-K MODAL ─────────────────────────────────────────────────────────────
const CmdKModal = ({ open, onClose, trackedUsers, setPage, onOpenUser }) => {
  const [query, setQuery] = useState('');
  const [idx, setIdx] = useState(0);
  useEffect(() => { if (!open) setQuery(''); }, [open]);
  const results = query.trim()
    ? trackedUsers.filter(u => u.username.toLowerCase().includes(query.toLowerCase()) || u.robloxId.includes(query))
    : trackedUsers;
  const nav = [
    { label: 'Dashboard',  icon: 'Dashboard',  action: () => { setPage('dashboard'); onClose(); } },
    { label: 'Tracking',   icon: 'Tracking',   action: () => { setPage('tracking');  onClose(); } },
    { label: 'Analytics',  icon: 'Analytics',  action: () => { setPage('analytics'); onClose(); } },
    { label: 'Alerts',     icon: 'Alerts',     action: () => { setPage('alerts');    onClose(); } },
    { label: 'Settings',   icon: 'Settings',   action: () => { setPage('settings');  onClose(); } },
  ];
  const items = query.trim()
    ? results.map(u => ({ type: 'user', data: u, label: u.username, sub: u.status, action: () => { onOpenUser(u); onClose(); } }))
    : [...nav.map(n => ({ type: 'nav', label: n.label, icon: n.icon, action: n.action })),
       ...trackedUsers.slice(0, 3).map(u => ({ type: 'user', data: u, label: u.username, sub: u.status, action: () => { onOpenUser(u); onClose(); } }))];
  useEffect(() => { setIdx(0); }, [query]);
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') { onClose(); return; }
      if (e.key === 'ArrowDown') { e.preventDefault(); setIdx(i => Math.min(i + 1, items.length - 1)); }
      if (e.key === 'ArrowUp')   { e.preventDefault(); setIdx(i => Math.max(i - 1, 0)); }
      if (e.key === 'Enter' && items[idx]) { items[idx].action(); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, idx, items]);
  if (!open) return null;
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 900, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: '14vh', animation: 'overlay-in 0.15s ease both' }}>
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(4,5,10,0.8)', backdropFilter: 'blur(8px)' }} onClick={onClose} />
      <div style={{ position: 'relative', width: '100%', maxWidth: 520, background: 'var(--bg2)', border: '1px solid var(--border2)', borderRadius: 'var(--r4)', overflow: 'hidden', boxShadow: '0 0 0 1px rgba(255,255,255,0.04) inset, 0 32px 80px rgba(0,0,0,0.7)', animation: 'cmdk-in 0.22s var(--ease-out-expo) both' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 16px', borderBottom: '1px solid var(--border)' }}>
          <span style={{ color: 'var(--t3)', flexShrink: 0 }}><Icon.Search /></span>
          <input autoFocus value={query} onChange={e => setQuery(e.target.value)} placeholder="Search users, navigate..."
            style={{ flex: 1, background: 'none', border: 'none', outline: 'none', color: 'var(--t1)', fontSize: 14.5, fontFamily: 'var(--font)' }} />
          <kbd style={{ fontSize: 10.5, color: 'var(--t4)', background: 'var(--bg3)', border: '1px solid var(--border)', borderRadius: 5, padding: '2px 6px', fontFamily: 'var(--mono)' }}>ESC</kbd>
        </div>
        <div style={{ maxHeight: 320, overflowY: 'auto' }}>
          {items.length === 0 ? (
            <div style={{ padding: '28px 16px', textAlign: 'center', fontSize: 13.5, color: 'var(--t3)' }}>No results for "{query}"</div>
          ) : items.map((item, i) => {
            const active = i === idx;
            const I = item.icon ? Icon[item.icon] : null;
            return (
              <div key={item.label + i} onClick={item.action} onMouseEnter={() => setIdx(i)}
                style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px 14px', cursor: 'pointer', background: active ? 'var(--p-dim)' : 'transparent', borderLeft: `2px solid ${active ? 'var(--p5)' : 'transparent'}`, transition: 'all 0.1s' }}>
                {item.type === 'user' ? (
                  <><Avatar name={item.label} size={26} status={item.data.status} />
                    <div style={{ flex: 1 }}><div style={{ fontSize: 13.5, fontWeight: 500, color: active ? 'var(--t1)' : 'var(--t2)' }}>{item.label}</div></div>
                    <GlowDot status={item.sub} size={6} /><span style={{ fontSize: 11, color: 'var(--t4)' }}>{item.sub}</span></>
                ) : (
                  <><span style={{ color: active ? 'var(--p4)' : 'var(--t4)', width: 20 }}>{I && <I />}</span>
                    <div style={{ flex: 1, fontSize: 13.5, fontWeight: 500, color: active ? 'var(--t1)' : 'var(--t2)' }}>{item.label}</div>
                    <span style={{ fontSize: 11, color: 'var(--t4)' }}>page</span></>
                )}
              </div>
            );
          })}
        </div>
        <div style={{ display: 'flex', gap: 14, padding: '9px 14px', borderTop: '1px solid var(--border)', background: 'rgba(255,255,255,0.015)' }}>
          {[['↑↓','navigate'],['↵','select'],['esc','close']].map(([k,l]) => (
            <span key={k} style={{ display: 'flex', alignItems: 'center', gap: 5, fontSize: 11, color: 'var(--t4)' }}>
              <kbd style={{ background: 'var(--bg3)', border: '1px solid var(--border)', borderRadius: 4, padding: '1px 5px', fontFamily: 'var(--mono)', fontSize: 10.5 }}>{k}</kbd> {l}
            </span>
          ))}
        </div>
      </div>
    </div>
  );
};

// ─── TOAST ────────────────────────────────────────────────────────────────────
const ToastContainer = ({ toasts, removeToast }) => (
  <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 800, display: 'flex', flexDirection: 'column', gap: 8, pointerEvents: 'none' }}>
    {toasts.map(t => (
      <div key={t.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', background: 'var(--bg3)', border: `1px solid ${t.type === 'success' ? 'rgba(52,211,153,0.25)' : t.type === 'error' ? 'rgba(248,113,113,0.25)' : 'var(--border)'}`, borderRadius: 'var(--r3)', boxShadow: '0 8px 32px rgba(0,0,0,0.5)', fontSize: 13.5, color: 'var(--t1)', pointerEvents: 'auto', animation: t.out ? 'toast-out 0.22s var(--ease-out-expo) both' : 'toast-in 0.3s var(--ease-out-expo) both', minWidth: 220, maxWidth: 320 }}>
        <span style={{ color: t.type === 'success' ? 'var(--green)' : t.type === 'error' ? 'var(--red)' : 'var(--p4)', flexShrink: 0 }}>{t.type === 'success' ? <Icon.Check /> : t.type === 'error' ? <Icon.Close /> : <Icon.Bolt />}</span>
        <span style={{ flex: 1 }}>{t.msg}</span>
        <button onClick={() => removeToast(t.id)} style={{ background: 'none', border: 'none', color: 'var(--t4)', cursor: 'pointer', padding: 2, display: 'flex' }}><Icon.Close /></button>
      </div>
    ))}
  </div>
);

// ─── NOTIFICATION DROPDOWN ────────────────────────────────────────────────────
const NotifDropdown = ({ alerts, onClear, onClose }) => {
  const ref = useRef(null);
  useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    setTimeout(() => document.addEventListener('mousedown', handler), 0);
    return () => document.removeEventListener('mousedown', handler);
  }, []);
  return (
    <div ref={ref} style={{ position: 'absolute', top: '100%', right: 0, width: 300, background: 'var(--bg2)', border: '1px solid var(--border2)', borderRadius: 'var(--r4)', boxShadow: '0 24px 60px rgba(0,0,0,0.6)', zIndex: 600, animation: 'cmdk-in 0.2s var(--ease-out-expo) both', overflow: 'hidden', marginTop: 8 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 14px', borderBottom: '1px solid var(--border)' }}>
        <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--t1)' }}>Alerts</span>
        {alerts.length > 0 && <button onClick={onClear} style={{ fontSize: 12, color: 'var(--p4)', background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'var(--font)' }}>Clear all</button>}
      </div>
      {alerts.length === 0
        ? <div style={{ padding: '24px 14px', textAlign: 'center', fontSize: 13, color: 'var(--t3)' }}>No recent alerts</div>
        : alerts.slice(0, 6).map((a, i) => (
          <div key={a.id} style={{ display: 'flex', gap: 10, padding: '10px 14px', borderBottom: i < 5 ? '1px solid rgba(255,255,255,0.04)' : 'none', animation: 'fadein-up 0.3s var(--ease-out-expo) both', animationDelay: `${i * 35}ms` }}>
            <GlowDot status={a.type === 'online' ? 'online' : a.type === 'game' ? 'in-game' : 'offline'} size={7} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12.5, color: 'var(--t1)' }}><b>{a.user}</b> {a.event}</div>
              <div style={{ fontSize: 11, color: 'var(--t4)', marginTop: 2 }}>{a.time}</div>
            </div>
          </div>
        ))}
    </div>
  );
};

// ─── LOGO GLYPH (vector copy of brand mark: arrows + rings + pin + nodes) ─────
const LogoGlyph = ({ size = 18, glow = true }) => (
  <svg width={size} height={size} viewBox="0 0 48 48" fill="none"
    style={{ display: 'block', overflow: 'visible', filter: glow ? 'drop-shadow(0 0 3px rgba(34,211,238,0.45))' : 'none' }}>
    {/* paper-plane / send arrows behind */}
    <path d="M30 6.5 L43.5 12 L33.5 22 Z" fill="#0E3A42" stroke="#2DD4BF" strokeWidth="1" strokeLinejoin="round" opacity="0.95" />
    <path d="M18 41.5 L6.5 36 L16.5 26.5 Z" fill="#0E3A42" stroke="#2DD4BF" strokeWidth="1" strokeLinejoin="round" opacity="0.78" />
    {/* orbital rings */}
    <circle cx="24" cy="24" r="15" stroke="#5EEAD4" strokeWidth="1.6" opacity="0.55" />
    <circle cx="24" cy="24" r="11" stroke="#22D3EE" strokeWidth="1.6" opacity="0.9" />
    {/* location pin */}
    <path d="M24 12.2c-4.6 0-8.3 3.5-8.3 7.9 0 5.95 8.3 13.5 8.3 13.5s8.3-7.55 8.3-13.5c0-4.4-3.7-7.9-8.3-7.9z"
      fill="#0B4A52" stroke="#67E8F9" strokeWidth="1.5" strokeLinejoin="round" />
    <circle cx="24" cy="20.2" r="3" fill="#CFFAFE" />
    {/* network nodes (on outer ring) */}
    {[[13,13],[35,13],[13,35],[35,35]].map(([x,y],i) => (
      <circle key={i} cx={x} cy={y} r="3.6" fill="#0E3A42" stroke="#22D3EE" strokeWidth="1.5" />
    ))}
  </svg>
);

const LogoMark = ({ size = 28, plain = false }) => {
  if (plain) return <LogoGlyph size={size} />;
  return (
    <div style={{
      width: size, height: size, borderRadius: size * 0.26, flexShrink: 0,
      background: 'linear-gradient(150deg, #0B2A30 0%, #05161A 100%)',
      border: '1px solid rgba(34,211,238,0.32)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: '0 0 0 1px rgba(34,211,238,0.06) inset, 0 0 14px rgba(6,182,212,0.35)',
      overflow: 'hidden',
    }}>
      <LogoGlyph size={size * 0.66} glow={false} />
    </div>
  );
};

// ─── SIDEBAR ──────────────────────────────────────────────────────────────────
const NAV_ITEMS = [
  { id: 'dashboard', label: 'Dashboard', icon: 'Dashboard' },
  { id: 'tracking',  label: 'Tracking',  icon: 'Tracking'  },
  { id: 'analytics', label: 'Analytics', icon: 'Analytics' },
  { id: 'alerts',    label: 'Alerts',    icon: 'Alerts'     },
  { id: 'pricing',   label: 'Pricing',   icon: 'Pricing'   },
  { id: 'settings',  label: 'Settings',  icon: 'Settings'  },
];

const ADMIN_CLERK_USER_ID = 'user_3F7kNkUoyAB2qYly99EqxUv0vIF';

const Sidebar = ({ page, setPage, collapsed, user, alertCount = 0 }) => {
  const isAdmin = user && user.id && ADMIN_CLERK_USER_ID && user.id === ADMIN_CLERK_USER_ID;
  const w = collapsed ? 58 : 220;
  return (
    <aside style={{ width: w, minHeight: '100%', background: 'var(--bg0)', borderRight: '1px solid var(--border)', display: 'flex', flexDirection: 'column', flexShrink: 0, transition: 'width 0.28s var(--ease-out-expo)', overflow: 'hidden' }}>
      <div style={{ padding: collapsed ? '16px 0' : '15px 16px', display: 'flex', alignItems: 'center', justifyContent: collapsed ? 'center' : 'flex-start', gap: 11, borderBottom: '1px solid var(--border)', minHeight: 58, flexShrink: 0 }}>
        <LogoMark size={30} />
        {!collapsed && <div><div style={{ fontSize: 14, fontWeight: 700, letterSpacing: '-0.02em', color: 'var(--t1)', lineHeight: 1 }}>RoStealth</div><div style={{ fontSize: 10, color: 'var(--t4)', marginTop: 2 }}>rostealth.site</div></div>}
      </div>
      <nav style={{ flex: 1, padding: '10px 7px', display: 'flex', flexDirection: 'column', gap: 2 }}>
        {[...NAV_ITEMS, ...(isAdmin ? [{ id:'admin', label:'Admin', icon:'Shield' }] : [])].map(item => {
          const active = page === item.id;
          const I = Icon[item.icon];
          const showBadge = item.id === 'alerts' && alertCount > 0;
          const isAdminItem = item.id === 'admin';
          return (
            <button key={item.id} onClick={() => setPage(item.id)}
              style={{ display: 'flex', alignItems: 'center', gap: 10, padding: collapsed ? '10px 0' : '9px 12px', justifyContent: collapsed ? 'center' : 'flex-start', background: active ? (isAdminItem?'rgba(248,113,113,0.07)':'var(--p-dim)') : 'transparent', border: `1px solid ${active ? (isAdminItem?'rgba(248,113,113,0.2)':'rgba(99,102,241,0.2)') : 'transparent'}`, borderRadius: 'var(--r2)', cursor: 'pointer', color: active ? (isAdminItem?'var(--red)':'var(--p4)') : 'var(--t3)', fontFamily: 'var(--font)', fontSize: 14, fontWeight: 500, transition: 'all 0.14s', width: '100%', position: 'relative' }}
              onMouseEnter={e => { if (!active) { e.currentTarget.style.background = isAdminItem?'rgba(248,113,113,0.05)':'rgba(255,255,255,0.04)'; e.currentTarget.style.color = isAdminItem?'var(--red)':'var(--t2)'; }}}
              onMouseLeave={e => { if (!active) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--t3)'; }}}
            >
              <I />
              {!collapsed && item.label}
              {showBadge && <span style={{ marginLeft: 'auto', minWidth: 18, height: 18, borderRadius: 9, background: 'var(--p5)', color: '#fff', fontSize: 10.5, display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 600 }}>{alertCount}</span>}
            </button>
          );
        })}
      </nav>
      <div style={{ padding: collapsed ? '12px 0' : '11px 14px', borderTop: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 10, justifyContent: collapsed ? 'center' : 'flex-start' }}>
        <Avatar name={user.username} size={28} />
        {!collapsed && <div style={{ flex: 1, minWidth: 0 }}><div style={{ fontSize: 13, fontWeight: 600, color: 'var(--t1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{user.username}</div><div style={{ fontSize: 11, color: 'var(--p4)', marginTop: 1 }}>Pro</div></div>}
      </div>
    </aside>
  );
};

// ─── TOPBAR ───────────────────────────────────────────────────────────────────
const TopBar = ({ page, collapsed, setCollapsed, onLogout, user, alertCount, alerts, onClearAlerts, onCmdK }) => {
  const labels = { dashboard: 'Dashboard', tracking: 'Tracking', analytics: 'Analytics', alerts: 'Alerts', pricing: 'Pricing', settings: 'Settings', admin: 'Admin' };
  const [showNotif, setShowNotif] = useState(false);
  return (
    <header style={{ height: 56, background: 'var(--bg0)', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', padding: '0 18px', gap: 10, flexShrink: 0 }}>
      <button onClick={() => setCollapsed(!collapsed)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--t3)', padding: 6, borderRadius: 6, display: 'flex', alignItems: 'center', transition: 'color 0.15s' }} onMouseEnter={e => e.currentTarget.style.color='var(--t1)'} onMouseLeave={e => e.currentTarget.style.color='var(--t3)'}>
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
      </button>
      <span style={{ fontSize: 14.5, fontWeight: 600, color: 'var(--t1)', letterSpacing: '-0.01em', flex: 1 }}>{labels[page] || 'Dashboard'}</span>
      <button onClick={onCmdK} style={{ display: 'flex', alignItems: 'center', gap: 7, padding: '5px 11px', background: 'var(--bg3)', border: '1px solid var(--border)', borderRadius: 8, cursor: 'pointer', color: 'var(--t3)', fontSize: 13, fontFamily: 'var(--font)', transition: 'all 0.15s' }} onMouseEnter={e => { e.currentTarget.style.borderColor='var(--border2)'; e.currentTarget.style.color='var(--t1)'; }} onMouseLeave={e => { e.currentTarget.style.borderColor='var(--border)'; e.currentTarget.style.color='var(--t3)'; }}>
        <Icon.Search /> Search <kbd style={{ fontSize: 10, background: 'var(--bg4)', border: '1px solid var(--border)', borderRadius: 4, padding: '1px 4px', fontFamily: 'var(--mono)' }}>⌘K</kbd>
      </button>
      <div style={{ position: 'relative' }}>
        <button onClick={() => setShowNotif(v => !v)} style={{ position: 'relative', background: showNotif ? 'var(--p-dim)' : 'none', border: `1px solid ${showNotif ? 'var(--border-bright)' : 'transparent'}`, cursor: 'pointer', color: showNotif ? 'var(--p4)' : 'var(--t3)', padding: 7, borderRadius: 7, display: 'flex', alignItems: 'center', transition: 'all 0.15s' }} onMouseEnter={e => { if (!showNotif) { e.currentTarget.style.color='var(--t1)'; }}} onMouseLeave={e => { if (!showNotif) { e.currentTarget.style.color='var(--t3)'; }}}>
          <Icon.Bell />
          {alertCount > 0 && <span style={{ position: 'absolute', top: 5, right: 5, width: 7, height: 7, background: 'var(--p5)', borderRadius: '50%', border: '1.5px solid var(--bg0)' }} />}
        </button>
        {showNotif && <NotifDropdown alerts={alerts} onClear={onClearAlerts} onClose={() => setShowNotif(false)} />}
      </div>
      <button onClick={onLogout} style={{ display: 'flex', alignItems: 'center', gap: 6, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--t3)', fontSize: 13, fontFamily: 'var(--font)', padding: '6px 10px', borderRadius: 6, transition: 'all 0.15s' }} onMouseEnter={e => { e.currentTarget.style.color='var(--red)'; e.currentTarget.style.background='var(--red-dim)'; }} onMouseLeave={e => { e.currentTarget.style.color='var(--t3)'; e.currentTarget.style.background='none'; }}>
        <Icon.Logout />
      </button>
    </header>
  );
};

// ─── UPGRADE NUDGE ────────────────────────────────────────────────────────────
const UpgradeBanner = ({ onUpgrade }) => (
  <div style={{ border: '1px solid var(--border)', borderRadius: 'var(--r2)', padding: '13px 15px', background: 'var(--bg2)' }}>
    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--t1)', marginBottom: 5 }}>You're on Free</div>
    <div style={{ fontSize: 12, color: 'var(--t3)', lineHeight: 1.55, marginBottom: 12 }}>Unlimited tracking, real-time updates &amp; Discord alerts on Pro.</div>
    <button onClick={onUpgrade} style={{ width: '100%', padding: '8px 0', borderRadius: 'var(--r2)', cursor: 'pointer', background: 'var(--p5)', color: '#fff', border: 'none', fontFamily: 'var(--font)', fontSize: 13, fontWeight: 600, transition: 'filter 0.15s' }} onMouseEnter={e => e.currentTarget.style.filter='brightness(1.1)'} onMouseLeave={e => e.currentTarget.style.filter='none'}>
      Upgrade to Pro
    </button>
  </div>
);

const StatCard = ({ label, value, sub, accent }) => (
  <div style={{ padding: '2px 0' }}>
    <div style={{ fontSize: 10.5, color: 'var(--t3)', fontWeight: 500, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 10 }}>{label}</div>
    <div style={{ fontSize: 32, fontWeight: 700, color: accent || 'var(--t1)', letterSpacing: '-0.04em', lineHeight: 1 }}>{value}</div>
    {sub && <div style={{ fontSize: 12.5, color: 'var(--t3)', marginTop: 8 }}>{sub}</div>}
  </div>
);

Object.assign(window, { Icon, Btn, Badge, GlowDot, StatusDot, Avatar, Card, Input, Drawer, CmdKModal, ToastContainer, NotifDropdown, LogoMark, LogoGlyph, Sidebar, TopBar, UpgradeBanner, StatCard });
