/* ============================================================
   Sidebar — icon rail by default, expands on hover (overlays)
   ============================================================ */
const { useState: useStateSB, useRef: useRefSB, useEffect: useEffectSB, useCallback: useCallbackSB } = React;

// ── Settings Modal ───────────────────────────────────────
const PALETTES = [
  { label: 'Teal', colors: ['#27f0a3', '#4fe4ff', '#ff4d8d'] },
  { label: 'Cyan', colors: ['#4fe4ff', '#7c5cff', '#27f0a3'] },
  { label: 'Amber', colors: ['#ffb648', '#ff4d8d', '#4fe4ff'] },
  { label: 'Gold', colors: ['#d4af37', '#caa86b', '#27f0a3'] },
];

function Toggle({ value, onChange }) {
  return (
    <div
      onClick={() => onChange(!value)}
      style={{
        width: 42, height: 24, borderRadius: 999, cursor: 'pointer',
        background: value ? 'var(--acc)' : 'rgba(255,255,255,0.12)',
        border: `1px solid ${value ? 'var(--acc)' : 'rgba(255,255,255,0.18)'}`,
        position: 'relative', transition: 'background .2s, border-color .2s', flexShrink: 0,
        boxShadow: value ? '0 0 10px -2px var(--acc)' : 'none',
      }}>
      <div style={{
        position: 'absolute', top: 3, left: value ? 20 : 3,
        width: 16, height: 16, borderRadius: '50%',
        background: value ? '#05080f' : 'rgba(255,255,255,0.55)',
        transition: 'left .2s',
      }} />
    </div>
  );
}

function SettingsModal({ open, onClose }) {
  const [prefs, setPrefs] = useStateSB(() => window.__fm_getPrefs ? window.__fm_getPrefs() : {});

  const set = useCallbackSB((key, val) => {
    const next = window.__fm_setPrefs ? window.__fm_setPrefs({ [key]: val }) : { ...prefs, [key]: val };
    setPrefs(next);
    // Live-apply palette
    if (key === 'palette' && window.__fm_applyPalette) window.__fm_applyPalette(val);
  }, [prefs]);

  if (!open) return null;

  const soundEnabled = prefs.soundEnabled !== false;
  const soundVolume = typeof prefs.soundVolume === 'number' ? prefs.soundVolume : 0.15;
  const currentPalette = prefs.palette || ['#27f0a3', '#4fe4ff', '#ff4d8d'];

  const row = (label, hint, control) => (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
      <div>
        <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--fg)' }}>{label}</div>
        {hint && <div style={{ fontSize: 11, color: 'var(--fg-muted)', marginTop: 2 }}>{hint}</div>}
      </div>
      {control}
    </div>
  );

  return (
    <div
      onClick={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{
        position: 'fixed', inset: 0, zIndex: 200,
        background: 'rgba(0,0,0,0.55)', backdropFilter: 'blur(4px)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
      <div style={{
        width: 400, maxWidth: '92vw', maxHeight: '85vh', overflowY: 'auto',
        borderRadius: 20,
        background: 'linear-gradient(165deg, rgba(22,32,56,0.98), rgba(10,16,30,0.99))',
        border: '1px solid rgba(255,255,255,0.10)',
        boxShadow: '0 32px 80px -16px rgba(0,0,0,0.9), inset 0 1px 0 rgba(255,255,255,0.08)',
        padding: '20px 24px 24px',
      }}>
        {/* header */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 18 }}>
          <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--fg)' }}>Settings</div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--fg-muted)', fontSize: 20, cursor: 'pointer', lineHeight: 1, padding: 4 }}>✕</button>
        </div>

        {/* section: Notifications */}
        <div className="mono" style={{ fontSize: 9.5, letterSpacing: '0.12em', color: 'var(--fg-muted)', marginBottom: 2 }}>THÔNG BÁO</div>

        {row('Âm thanh surebet mới', 'Phát beep khi xuất hiện surebet mới',
          <Toggle value={soundEnabled} onChange={v => set('soundEnabled', v)} />
        )}

        {row('Âm lượng',
          `${Math.round(soundVolume * 100)}%`,
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <input type="range" min="0" max="1" step="0.05"
              value={soundVolume}
              onChange={e => set('soundVolume', parseFloat(e.target.value))}
              disabled={!soundEnabled}
              style={{ width: 100, accentColor: 'var(--acc)', opacity: soundEnabled ? 1 : 0.35 }} />
            <span className="mono" style={{ fontSize: 11, color: 'var(--fg-muted)', minWidth: 32, textAlign: 'right' }}>
              {Math.round(soundVolume * 100)}%
            </span>
          </div>
        )}

        <button
          onClick={() => { if (soundEnabled) window.__fm_playBeep?.(); }}
          disabled={!soundEnabled}
          style={{
            marginTop: 4, marginBottom: 8,
            padding: '7px 16px', borderRadius: 8, border: '1px solid var(--bd)',
            background: 'rgba(255,255,255,0.05)', color: soundEnabled ? 'var(--fg)' : 'var(--fg-muted)',
            fontSize: 12, cursor: soundEnabled ? 'pointer' : 'not-allowed',
          }}>
          🔔 Test âm thanh
        </button>

        {/* section: Appearance */}
        <div className="mono" style={{ fontSize: 9.5, letterSpacing: '0.12em', color: 'var(--fg-muted)', marginTop: 14, marginBottom: 8 }}>GIAO DIỆN</div>

        <div style={{ borderBottom: '1px solid rgba(255,255,255,0.06)', paddingBottom: 14 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--fg)', marginBottom: 10 }}>Màu accent</div>
          <div style={{ display: 'flex', gap: 10 }}>
            {PALETTES.map(p => {
              const active = p.colors[0] === currentPalette[0];
              return (
                <button
                  key={p.label}
                  onClick={() => set('palette', p.colors)}
                  title={p.label}
                  style={{
                    width: 38, height: 38, borderRadius: 10, cursor: 'pointer',
                    border: active ? `2px solid ${p.colors[0]}` : '2px solid transparent',
                    background: `linear-gradient(135deg, ${p.colors[0]}, ${p.colors[1]})`,
                    boxShadow: active ? `0 0 14px -2px ${p.colors[0]}` : 'none',
                    transition: 'border-color .18s, box-shadow .18s',
                    outline: 'none',
                  }} />
              );
            })}
          </div>
        </div>

        {/* section: Dashboard */}
        <div className="mono" style={{ fontSize: 9.5, letterSpacing: '0.12em', color: 'var(--fg-muted)', marginTop: 14, marginBottom: 2 }}>DASHBOARD</div>

        {row('ROI tối thiểu mặc định', 'Áp dụng khi mở trang',
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <input type="number" min="0" max="20" step="0.5"
              value={prefs.defaultRoiMin || 0}
              onChange={e => set('defaultRoiMin', parseFloat(e.target.value) || 0)}
              style={{
                width: 64, padding: '5px 8px', borderRadius: 7, border: '1px solid var(--bd)',
                background: 'rgba(255,255,255,0.06)', color: 'var(--fg)', fontSize: 13, textAlign: 'center',
              }} />
            <span style={{ fontSize: 12, color: 'var(--fg-muted)' }}>%</span>
          </div>
        )}

        {row('Chế độ mặc định', 'Live hoặc Prematch khi mở app',
          <select
            value={prefs.defaultDataMode || 'live'}
            onChange={e => set('defaultDataMode', e.target.value)}
            style={{
              padding: '6px 10px', borderRadius: 7, border: '1px solid var(--bd)',
              background: 'rgba(255,255,255,0.06)', color: 'var(--fg)', fontSize: 13, cursor: 'pointer',
            }}>
            <option value="live">Live</option>
            <option value="prematch">Prematch</option>
          </select>
        )}

        {/* close */}
        <button
          onClick={onClose}
          style={{
            marginTop: 20, width: '100%', padding: '12px', borderRadius: 10, border: 'none',
            background: 'linear-gradient(135deg, var(--acc), var(--acc-2))',
            color: '#05080f', fontWeight: 700, fontSize: 13, cursor: 'pointer',
          }}>
          Lưu & Đóng
        </button>
      </div>
    </div>
  );
}

function SBIcon({ name }) {
  const stroke = 'currentColor';
  const common = { fill: 'none', stroke, strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'dashboard':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M12 3v18" /><path d="M5 7h14" /><path d="M5 7l-2 5a3 3 0 006 0L7 7" /><path d="M19 7l-2 5a3 3 0 006 0l-2-5" /><path d="M8 21h8" /></svg>;
    case 'smartbets':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" fill="currentColor" fillOpacity="0.08" /></svg>;
    case 'analytics':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M3 17l5-5 4 3 4-6 5 8" /><circle cx="3" cy="17" r="1" fill={stroke} /><circle cx="8" cy="12" r="1" fill={stroke} /><circle cx="12" cy="15" r="1" fill={stroke} /><circle cx="16" cy="9" r="1" fill={stroke} /><circle cx="21" cy="17" r="1" fill={stroke} /></svg>;
    case 'profits':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="12" r="9" /><path d="M9 14c.5 1.2 1.8 2 3 2 1.7 0 3-1 3-2.3 0-2.8-6-1.6-6-4.4C9 8 10.3 7 12 7c1.2 0 2.5.8 3 2" /><path d="M12 5v2M12 17v2" /></svg>;
    case 'tips':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M4 4h10a4 4 0 014 4v12H8a4 4 0 01-4-4z" /><path d="M4 4v16" /><path d="M8 9h6M8 13h6" /></svg>;
    case 'calc':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><rect x="4" y="3" width="16" height="18" rx="2" /><rect x="7" y="6" width="10" height="3" rx=".5" /><circle cx="9" cy="13" r=".8" fill={stroke} /><circle cx="12" cy="13" r=".8" fill={stroke} /><circle cx="15" cy="13" r=".8" fill={stroke} /><circle cx="9" cy="17" r=".8" fill={stroke} /><circle cx="12" cy="17" r=".8" fill={stroke} /><circle cx="15" cy="17" r=".8" fill={stroke} /></svg>;
    case 'tickets':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M3 8a2 2 0 012-2h14a2 2 0 012 2v2a2 2 0 100 4v2a2 2 0 01-2 2H5a2 2 0 01-2-2v-2a2 2 0 100-4z" /><path d="M10 6v12" strokeDasharray="2 2" /></svg>;
    case 'grid':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" /><rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" /></svg>;
    case 'payment':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><rect x="2.5" y="6" width="19" height="13" rx="2" /><path d="M2.5 10h19" /><path d="M6 15h3" /></svg>;
    case 'admin':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.7 1.7 0 00.3 1.8l.1.1a2 2 0 11-2.8 2.8l-.1-.1a1.7 1.7 0 00-1.8-.3 1.7 1.7 0 00-1 1.5V21a2 2 0 11-4 0v-.1a1.7 1.7 0 00-1-1.5 1.7 1.7 0 00-1.8.3l-.1.1a2 2 0 11-2.8-2.8l.1-.1a1.7 1.7 0 00.3-1.8 1.7 1.7 0 00-1.5-1H3a2 2 0 110-4h.1a1.7 1.7 0 001.5-1 1.7 1.7 0 00-.3-1.8l-.1-.1a2 2 0 112.8-2.8l.1.1a1.7 1.7 0 001.8.3h.1a1.7 1.7 0 001-1.5V3a2 2 0 114 0v.1a1.7 1.7 0 001 1.5h.1a1.7 1.7 0 001.8-.3l.1-.1a2 2 0 112.8 2.8l-.1.1a1.7 1.7 0 00-.3 1.8v.1a1.7 1.7 0 001.5 1H21a2 2 0 110 4h-.1a1.7 1.7 0 00-1.5 1z" /></svg>;
    case 'profile':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="8" r="4" /><path d="M4 20c0-4 4-6 8-6s8 2 8 6" /></svg>;
    case 'help':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="12" r="9" /><path d="M9.5 9a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 3.5" /><circle cx="12" cy="16.5" r=".7" fill={stroke} /></svg>;
    case 'logout':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><path d="M14 4h4a2 2 0 012 2v12a2 2 0 01-2 2h-4" /><path d="M9 8l-4 4 4 4" /><path d="M5 12h11" /></svg>;
    case 'pin':
      return <svg viewBox="0 0 24 24" width="14" height="14" {...common}><path d="M12 2v8" /><path d="M8 10l4-2 4 2v4l-4 8-4-8z" /></svg>;
    case 'telegram':
      return <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M21.5 4.2L18.7 19c-.2 1-.8 1.3-1.7.8l-4.6-3.4-2.2 2.1c-.3.3-.5.5-1 .5l.3-4.7 8.6-7.7c.4-.3-.1-.5-.6-.2L7 11.9 2.6 10.5c-1-.3-1-1 .2-1.5L20.3 3c.8-.3 1.5.2 1.2 1.2z" /></svg>;
    case 'sigma':
      return <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 5h12l-7 7 7 7H6" /></svg>;
    case 'settings':
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.7 1.7 0 00.3 1.8l.1.1a2 2 0 11-2.8 2.8l-.1-.1a1.7 1.7 0 00-1.8-.3 1.7 1.7 0 00-1 1.5V21a2 2 0 11-4 0v-.1a1.7 1.7 0 00-1-1.5 1.7 1.7 0 00-1.8.3l-.1.1a2 2 0 11-2.8-2.8l.1-.1a1.7 1.7 0 00.3-1.8 1.7 1.7 0 00-1.5-1H3a2 2 0 110-4h.1a1.7 1.7 0 001.5-1 1.7 1.7 0 00-.3-1.8l-.1-.1a2 2 0 112.8-2.8l.1.1a1.7 1.7 0 001.8.3h.1a1.7 1.7 0 001-1.5V3a2 2 0 114 0v.1a1.7 1.7 0 001 1.5h.1a1.7 1.7 0 001.8-.3l.1-.1a2 2 0 112.8 2.8l-.1.1a1.7 1.7 0 00-.3 1.8v.1a1.7 1.7 0 001.5 1H21a2 2 0 110 4h-.1a1.7 1.7 0 00-1.5 1z" /></svg>;
    case 'logo':
      return (
        <svg viewBox="0 0 32 32" width="22" height="22" fill="none">
          <defs>
            <linearGradient id="logo-g" x1="0" x2="1" y1="0" y2="1">
              <stop offset="0" stopColor="var(--acc)" />
              <stop offset="1" stopColor="var(--acc-2)" />
            </linearGradient>
            <linearGradient id="logo-coin" x1="0" x2="0" y1="0" y2="1">
              <stop offset="0" stopColor="var(--acc-2)" />
              <stop offset="1" stopColor="var(--acc)" />
            </linearGradient>
            <radialGradient id="logo-glow" cx="50%" cy="50%" r="50%">
              <stop offset="0" stopColor="var(--acc)" stopOpacity="0.35"/>
              <stop offset="1" stopColor="var(--acc)" stopOpacity="0"/>
            </radialGradient>
          </defs>
          {/* hexagon frame + soft glow */}
          <circle cx="16" cy="16" r="14" fill="url(#logo-glow)" />
          <path d="M16 2.5l11.3 6.6v13.8L16 29.5 4.7 22.9V9.1z" stroke="url(#logo-g)" strokeWidth="1.6" strokeLinejoin="round" />
          {/* crypto coin "0" — outer edge, inner ring (filled), top highlight, edge ticks */}
          <circle cx="16" cy="17" r="5.4" stroke="url(#logo-coin)" strokeWidth="1.5" />
          <circle cx="16" cy="17" r="3.4" stroke="url(#logo-coin)" strokeWidth="1.1" fill="color-mix(in srgb, var(--acc) 12%, transparent)" />
          {/* tiny tick marks around the coin edge (crypto-style serrations) */}
          <g stroke="url(#logo-coin)" strokeWidth="1.1" strokeLinecap="round">
            <line x1="16" y1="10.6" x2="16" y2="12" />
            <line x1="16" y1="22"   x2="16" y2="23.4" />
            <line x1="9.6" y1="17"  x2="11" y2="17" />
            <line x1="21" y1="17"   x2="22.4" y2="17" />
          </g>
          {/* highlight sparkle on top-left of coin */}
          <circle cx="13.2" cy="14.4" r="0.85" fill="var(--acc-2)" opacity="0.9" style={{ filter: 'drop-shadow(0 0 3px var(--acc-2))' }} />
          {/* top crown dot (kept from previous design) */}
          <circle cx="16" cy="8.4" r="1.4" fill="var(--acc)" style={{ filter: 'drop-shadow(0 0 4px var(--acc))' }} />
        </svg>);

    default:
      return <svg viewBox="0 0 24 24" width="20" height="20" {...common}><circle cx="12" cy="12" r="3" /></svg>;
  }
}

const RAIL_W = 64;
const PANEL_W = 244;
const BOTTOM_NAV_H = 58;

// Shared mobile breakpoint hook — used by Sidebar, Topbar, App
function useIsMobile(bp = 768) {
  const [mob, setMob] = useStateSB(() => typeof window !== 'undefined' && window.innerWidth < bp);
  useEffectSB(() => {
    const h = () => setMob(window.innerWidth < bp);
    window.addEventListener('resize', h, { passive: true });
    return () => window.removeEventListener('resize', h);
  }, [bp]);
  return mob;
}
window.__fm_useIsMobile = useIsMobile; // expose for other files

// ── Bottom Navigation (mobile only) ──────────────────────
function BottomNav({ active, onNav, settingsOpen, onSettings, onSignOut }) {
  const [sheetOpen, setSheetOpen] = useStateSB(false);

  const primary = [
    { id: 'dashboard', label: 'Feed',       icon: 'dashboard' },
    { id: 'payment',   label: 'Plan',       icon: 'payment'   },
    { id: 'profile',   label: 'Profile',    icon: 'profile'   },
    { id: '__more',    label: 'More',       icon: 'grid'      },
  ];

  const sheetItems = [
    { id: 'analytics', label: 'Analytics',  icon: 'analytics' },
    { id: 'tips',      label: 'Tips',        icon: 'tips'      },
    { id: 'about',     label: 'About',       icon: 'help'      },
    { id: '__tg',      label: 'Telegram',    icon: 'telegram', tint: '#29b6f6' },
    { id: '__settings',label: 'Settings',    icon: 'settings'  },
    { id: '__logout',  label: 'Sign Out',    icon: 'logout',   tint: '#ff5f5f' },
  ];

  const handleNav = (id) => {
    setSheetOpen(false);
    if (id === '__more') { setSheetOpen(o => !o); return; }
    if (id === '__tg') { window.open('https://t.me/+5KnH6203C_BkZGU1', '_blank', 'noopener,noreferrer'); return; }
    if (id === '__settings') { onSettings?.(); return; }
    if (id === '__logout') { onSignOut?.(); return; }
    onNav?.(id);
  };

  return (
    <>
      {/* sheet overlay */}
      {sheetOpen && (
        <div
          onClick={() => setSheetOpen(false)}
          style={{ position: 'fixed', inset: 0, zIndex: 89, background: 'rgba(0,0,0,0.45)', backdropFilter: 'blur(4px)' }} />
      )}

      {/* more sheet */}
      {sheetOpen && (
        <div style={{
          position: 'fixed', bottom: BOTTOM_NAV_H, left: 0, right: 0, zIndex: 90,
          padding: '12px 16px 16px',
          background: 'linear-gradient(180deg, rgba(10,16,30,0.97), rgba(8,12,24,0.99))',
          backdropFilter: 'blur(24px)', WebkitBackdropFilter: 'blur(24px)',
          borderTop: '1px solid var(--bd)',
          borderRadius: '20px 20px 0 0',
          boxShadow: '0 -16px 48px rgba(0,0,0,0.6)',
          animation: 'slide-up .25s cubic-bezier(.22,1,.36,1)',
        }}>
          <div style={{ width: 36, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.18)', margin: '0 auto 16px' }} />
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
            {sheetItems.map(item => {
              const isActive = active === item.id;
              const col = item.tint || (isActive ? 'var(--acc)' : 'var(--fg-muted)');
              return (
                <button key={item.id} onClick={() => handleNav(item.id)} style={{
                  display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
                  padding: '12px 8px', borderRadius: 14, border: 'none', cursor: 'pointer',
                  background: isActive ? 'color-mix(in srgb, var(--acc) 12%, transparent)' : 'rgba(255,255,255,0.04)',
                  color: col,
                }}>
                  <SBIcon name={item.icon} />
                  <span style={{ fontSize: 11, fontWeight: 600 }}>{item.label}</span>
                </button>
              );
            })}
          </div>
        </div>
      )}

      {/* bar */}
      <div style={{
        position: 'fixed', bottom: 0, left: 0, right: 0, height: BOTTOM_NAV_H,
        zIndex: 95,
        display: 'flex', alignItems: 'center',
        background: 'linear-gradient(180deg, rgba(8,12,22,0.92), rgba(6,10,20,0.97))',
        backdropFilter: 'blur(24px) saturate(1.5)', WebkitBackdropFilter: 'blur(24px) saturate(1.5)',
        borderTop: '1px solid var(--bd)',
        paddingBottom: 'env(safe-area-inset-bottom, 0px)',
      }}>
        {primary.map(item => {
          const isActive = item.id === '__more' ? sheetOpen : active === item.id;
          return (
            <button key={item.id} onClick={() => handleNav(item.id)} style={{
              flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
              padding: '6px 4px', border: 'none', background: 'transparent', cursor: 'pointer',
              color: isActive ? 'var(--acc)' : 'var(--fg-muted)',
              transition: 'color .18s',
            }}>
              <span style={{
                width: 34, height: 34, borderRadius: 10, display: 'grid', placeItems: 'center',
                background: isActive ? 'color-mix(in srgb, var(--acc) 16%, transparent)' : 'transparent',
                border: isActive ? '1px solid color-mix(in srgb, var(--acc) 40%, transparent)' : '1px solid transparent',
                boxShadow: isActive ? '0 0 12px -2px var(--acc)' : 'none',
                transition: 'background .18s, border-color .18s, box-shadow .18s',
              }}>
                <SBIcon name={item.icon} />
              </span>
              <span style={{ fontSize: 9.5, fontWeight: 600, letterSpacing: '0.03em', lineHeight: 1 }}>{item.label}</span>
            </button>
          );
        })}
      </div>

      <style>{`
        @keyframes slide-up {
          from { transform: translateY(100%); opacity: 0; }
          to   { transform: translateY(0);    opacity: 1; }
        }
      `}</style>
    </>
  );
}

function Sidebar({ active = 'dashboard', onNav, pinned, onTogglePin }) {
  const isMobile = useIsMobile();
  const [hover, setHover] = useStateSB(false);
  const [userRole, setUserRole] = useStateSB(() => window.__fm_user?.role || 'free');
  const [settingsOpen, setSettingsOpen] = useStateSB(false);
  const open = hover || pinned;

  // api-connector calls window.__fm_setUserRole after loadUser() completes
  useEffectSB(() => {
    window.__fm_setUserRole = (role) => setUserRole(role || 'free');
    if (window.__fm_user) setUserRole(window.__fm_user.role || 'free');
    return () => { delete window.__fm_setUserRole; };
  }, []);

  // Expose global so other components can open settings
  useEffectSB(() => {
    window.__fm_openSettings = () => setSettingsOpen(true);
    return () => { delete window.__fm_openSettings; };
  }, []);

  const isAdmin = userRole === 'admin';

  const sections = [
    { group: 'TRADING', items: [
      { id: 'dashboard',  label: 'Surebet Feed',   icon: 'dashboard' },
    ]},
    { group: 'INSIGHTS', items: [
      { id: 'analytics',  label: 'Analytics',      icon: 'analytics' },
      { id: 'tips',       label: 'Tips & Notes',   icon: 'tips',    dot: 'var(--acc)' },
    ]},
    { group: 'ACCOUNT', items: [
      ...(isAdmin ? [{ id: 'admin', label: 'Admin Panel', icon: 'admin', tint: '#ffb648' }] : []),
      { id: 'profile',    label: 'Profile',        icon: 'profile' },
      { id: 'payment',    label: 'Subscription',   icon: 'payment' },
    ]},
    { group: 'INFO', items: [
      { id: 'about',      label: 'About',          icon: 'help' },
      { id: 'contact',    label: 'Contact',        icon: 'tips' },
    ]},
  ];


  // ── Mobile: render bottom nav instead of sidebar ──────────
  if (isMobile) {
    return (
      <>
        <BottomNav
          active={active}
          onNav={onNav}
          settingsOpen={settingsOpen}
          onSettings={() => setSettingsOpen(true)}
          onSignOut={() => {
            localStorage.removeItem('fm_token');
            localStorage.removeItem('fm_settings');
            localStorage.removeItem('fm_filters');
            window.location.href = '/login.html';
          }} />
        <SettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} />
      </>
    );
  }

  return (
    <>
      {/* spacer in the document flow so main content gets a permanent left gutter */}
      <div style={{ width: RAIL_W, flexShrink: 0 }} aria-hidden="true" />

      {/* the actual sidebar overlays */}
      <aside
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
        style={{
          position: 'fixed',
          top: 0, left: 0, height: '100vh',
          width: open ? PANEL_W : RAIL_W,
          transition: 'width .28s cubic-bezier(.22,1,.36,1)',
          padding: '14px 10px 14px',
          borderRight: '1px solid var(--bd)',
          background: open ?
          'linear-gradient(180deg, rgba(8,12,22,0.92), rgba(6,10,20,0.96))' :
          'linear-gradient(180deg, rgba(8,12,22,0.78), rgba(6,10,20,0.88))',
          backdropFilter: 'blur(24px) saturate(1.5)',
          WebkitBackdropFilter: 'blur(24px) saturate(1.5)',
          display: 'flex', flexDirection: 'column',
          gap: 8,
          zIndex: 50,
          boxShadow: open ? '12px 0 40px -20px rgba(0,0,0,0.85)' : 'none',
          overflow: 'hidden'
        }}>

        {/* brand */}
        <div style={{
          display: 'flex', alignItems: 'center',
          gap: open ? 12 : 0,
          padding: open ? '6px 8px 12px' : '6px 0 12px',
          justifyContent: open ? 'flex-start' : 'center',
          position: 'relative',
          borderBottom: '1px solid var(--bd)',
          marginBottom: 6,
          transition: 'padding .22s, gap .22s'
        }}>
          <div style={{
            width: 38, height: 38, borderRadius: 10,
            display: 'grid', placeItems: 'center',
            background: 'linear-gradient(135deg, color-mix(in srgb, var(--acc) 30%, transparent), rgba(12,18,32,0.6))',
            border: '1px solid color-mix(in srgb, var(--acc) 40%, transparent)',
            boxShadow: '0 0 18px -4px var(--acc), inset 0 1px 0 rgba(255,255,255,0.25)',
            flexShrink: 0
          }}>
            <SBIcon name="logo" />
          </div>
          <div style={{
            overflow: 'hidden', minWidth: 0, flex: 1,
            opacity: open ? 1 : 0,
            transform: open ? 'translateX(0)' : 'translateX(-8px)',
            transition: 'opacity .22s, transform .22s',
            whiteSpace: 'nowrap',
            pointerEvents: open ? 'auto' : 'none'
          }}>
            <div style={{ fontSize: 15, fontWeight: 700, letterSpacing: '-0.01em' }}>FreeM<span style={{ color: 'var(--acc)' }}>0</span>ney</div>
            <div className="cap" style={{ fontSize: 8.5 }}>LIQUID ARB TERMINAL</div>
          </div>
        </div>

        {/* nav sections */}
        <div style={{ flex: 1, overflowY: open ? 'auto' : 'hidden', overflowX: 'hidden', display: 'flex', flexDirection: 'column', gap: 14, paddingRight: 2 }}>
          {sections.map((sec, si) =>
          <div key={sec.group}>
              <div className="cap" style={{
              padding: '0 12px 6px', fontSize: 9,
              opacity: open ? 1 : 0,
              height: open ? 'auto' : 0,
              overflow: 'hidden',
              transition: 'opacity .22s'
            }}>{sec.group}</div>
              {/* rail divider between sections when collapsed */}
              {!open && si > 0 &&
            <div style={{ width: 24, height: 1, margin: '0 auto 10px', background: 'var(--bd)' }} />
            }
              <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                {sec.items.map((it) =>
              <NavItem
                key={it.id}
                item={it}
                active={active === it.id}
                open={open}
                onClick={() => onNav?.(it.id)} />

              )}
              </div>
            </div>
          )}
        </div>

        {/* bottom */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingTop: 10, borderTop: '1px solid var(--bd)' }}>
          <NavItem
            item={{ id: '__telegram', label: 'Telegram', icon: 'telegram', tint: '#29b6f6' }}
            active={false} open={open}
            onClick={() => window.open('https://t.me/+5KnH6203C_BkZGU1', '_blank', 'noopener,noreferrer')} />

          <NavItem
            item={{ id: '__settings', label: 'Settings', icon: 'settings' }}
            active={settingsOpen} open={open}
            onClick={() => setSettingsOpen(true)} />

          <NavItem
            item={{ id: '__help', label: 'Help & Docs', icon: 'help' }}
            active={active === 'about'} open={open}
            onClick={() => onNav?.('about')} />

          <NavItem
            item={{ id: '__logout', label: 'Sign Out', icon: 'logout', tint: '#ff5f5f' }}
            active={false} open={open}
            onClick={() => {
              localStorage.removeItem('fm_token');
              localStorage.removeItem('fm_settings');
              localStorage.removeItem('fm_filters');
              window.location.href = '/login.html';
            }} />
        </div>
      </aside>

      <SettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} />
    </>);

}

function NavItem({ item, active, open, onClick }) {
  const [hovered, setHovered] = useStateSB(false);
  const tileSize = 38;
  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      title={!open ? item.label : undefined}
      style={{
        display: 'flex', alignItems: 'center',
        gap: open ? 12 : 0,
        padding: open ? '4px 8px' : '4px 0',
        justifyContent: open ? 'flex-start' : 'center',
        borderRadius: 10,
        background: open && active ?
        'linear-gradient(90deg, color-mix(in srgb, var(--acc) 14%, transparent), transparent)' :
        'transparent',
        border: '1px solid transparent',
        color: active ? 'var(--fg)' : 'var(--fg-muted)',
        cursor: 'pointer',
        position: 'relative',
        textAlign: 'left',
        transition: 'background .18s, color .18s, padding .22s, gap .22s',
        width: '100%',
        whiteSpace: 'nowrap'
      }}>
      
      {/* left accent bar when active (open mode only) */}
      {active && open &&
      <span style={{
        position: 'absolute', left: -10, top: '50%', transform: 'translateY(-50%)',
        width: 3, height: 22, borderRadius: 4,
        background: 'var(--acc)',
        boxShadow: '0 0 12px var(--acc)'
      }} />
      }
      {/* right indicator bar (orange) when active in rail mode */}
      {active && !open &&
      <span style={{
        position: 'absolute', right: -8, top: '50%', transform: 'translateY(-50%)',
        width: 3, height: 22, borderRadius: 4,
        background: 'var(--acc-warn, #ffb648)',
        boxShadow: '0 0 10px var(--acc-warn, #ffb648)'
      }} />
      }

      {/* icon tile — same size for ALL items (matches brand box) */}
      <span style={{
        width: tileSize, height: tileSize, borderRadius: 10,
        display: 'grid', placeItems: 'center',
        flexShrink: 0, position: 'relative',
        background: active ?
        'linear-gradient(135deg, color-mix(in srgb, var(--acc) 30%, transparent), rgba(12,18,32,0.6))' :
        hovered ? 'rgba(255,255,255,0.05)' : 'transparent',
        border: active ?
        '1px solid color-mix(in srgb, var(--acc) 45%, transparent)' :
        hovered ? '1px solid var(--bd)' : '1px solid transparent',
        boxShadow: active ?
        '0 0 16px -4px var(--acc), inset 0 1px 0 rgba(255,255,255,0.18)' :
        'none',
        color: active ? 'var(--acc)' : item.tint && hovered ? item.tint : hovered ? 'var(--fg)' : 'currentColor',
        transition: 'background .18s, border-color .18s, box-shadow .18s, color .18s'
      }}>
        <SBIcon name={item.icon} />
        {/* notification dot on icon */}
        {item.dot &&
        <span style={{
          position: 'absolute', top: 4, right: 4,
          width: 7, height: 7, borderRadius: '50%',
          background: item.dot,
          boxShadow: `0 0 6px ${item.dot}, 0 0 0 2px rgba(8,12,22,0.95)`
        }} />
        }
      </span>

      <span style={{
        fontSize: 13.5, fontWeight: 500, flex: 1,
        opacity: open ? 1 : 0,
        transform: open ? 'translateX(0)' : 'translateX(-6px)',
        transition: 'opacity .22s, transform .22s',
        overflow: 'hidden',
        pointerEvents: open ? 'auto' : 'none'
      }}>{item.label}</span>

      {open && item.badge &&
      <span className="mono" style={{
        fontSize: 9, padding: '2px 6px', borderRadius: 999,
        background: 'color-mix(in srgb, var(--acc-3) 22%, transparent)',
        color: 'var(--acc-3)', fontWeight: 700, letterSpacing: '0.06em',
        border: '1px solid color-mix(in srgb, var(--acc-3) 35%, transparent)'
      }}>{item.badge}</span>
      }
    </button>);

}

Object.assign(window, { Sidebar, SBIcon });