// CyberX Battle Pass — Прототип v0.3
// + Анимации (orbs, section enter, stagger, pulse, shimmer, count-up)
// + Полноценный раздел «Настройки» с модалками (Steam/Faceit/Email/Password/Avatar)

const { useState, useEffect, useCallback, useRef, useMemo } = React;
const W = window;

// ────────────────────────────────────────────────────────────
// УТИЛИТЫ И ХУКИ
// ────────────────────────────────────────────────────────────

function useDragScroll() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let isDown = false, moved = false, startX = 0, scrollLeft = 0;
    const down = (e) => {
      if (e.button !== undefined && e.button !== 0) return;
      isDown = true; moved = false;
      el.style.cursor = 'grabbing';
      startX = e.pageX - el.offsetLeft;
      scrollLeft = el.scrollLeft;
    };
    const up = () => { isDown = false; el.style.cursor = 'grab'; };
    const move = (e) => {
      if (!isDown) return;
      const x = e.pageX - el.offsetLeft;
      const dx = x - startX;
      if (Math.abs(dx) > 4) moved = true;
      if (moved) { e.preventDefault(); el.scrollLeft = scrollLeft - dx * 1.5; }
    };
    const click = (e) => { if (moved) { e.preventDefault(); e.stopPropagation(); } };
    const wheel = (e) => {
      if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        el.scrollLeft += e.deltaY; e.preventDefault();
      }
    };
    el.style.cursor = 'grab';
    el.addEventListener('mousedown', down);
    el.addEventListener('mouseleave', up);
    el.addEventListener('mouseup', up);
    el.addEventListener('mousemove', move);
    el.addEventListener('click', click, true);
    el.addEventListener('wheel', wheel, { passive: false });
    return () => {
      el.removeEventListener('mousedown', down);
      el.removeEventListener('mouseleave', up);
      el.removeEventListener('mouseup', up);
      el.removeEventListener('mousemove', move);
      el.removeEventListener('click', click, true);
      el.removeEventListener('wheel', wheel);
    };
  }, []);
  return ref;
}

function useCountUp(target, duration = 700, deps = []) {
  const [val, setVal] = useState(0);
  useEffect(() => {
    let start = null, raf;
    const tick = (t) => {
      if (start === null) start = t;
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(Math.round(target * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
    // eslint-disable-next-line
  }, deps);
  return val;
}

function useBodyScrollLock(active) {
  useEffect(() => {
    if (!active) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [active]);
}

function ScrollButtons({ targetRef, step = 220 }) {
  const scroll = (dir) => {
    const el = targetRef.current;
    if (el) el.scrollBy({ left: dir * step, behavior: 'smooth' });
  };
  return (
    <>
      <button type="button" className="scroll-arrow scroll-arrow-left" onClick={() => scroll(-1)}>‹</button>
      <button type="button" className="scroll-arrow scroll-arrow-right" onClick={() => scroll(1)}>›</button>
    </>
  );
}

// Хук для случая, когда scrollable элемент находится ВНУТРИ обёртки
// (например, WebRewardTrack из web-dashboard.jsx — его внутренний div имеет
// overflowX:auto, а у нас обёртка снаружи). Ищем внутренний скроллящийся
// элемент. Drag-handlers вешаем на ВНЕШНИЙ wrapper (events туда точно
// долетают через bubbling), scroll-мутации применяем к ВНУТРЕННЕМУ scroller.
// Это важно потому что в WebRewardTrack центральный divider — absolute sibling
// scroller'а, события на нём НЕ всплывают через scroller.
function useDragScrollOnChild() {
  const outerRef = useRef(null);
  const scrollRef = useRef(null);
  useEffect(() => {
    const outer = outerRef.current;
    if (!outer) return;
    let scroller = null;
    let cleanup = null;
    const findScroller = () => {
      const all = outer.querySelectorAll('*');
      for (const el of all) {
        const cs = getComputedStyle(el);
        const ox = cs.overflowX;
        if ((ox === 'auto' || ox === 'scroll') && el.scrollWidth > el.clientWidth) return el;
      }
      return null;
    };
    let attempts = 0;
    const tick = () => {
      scroller = findScroller();
      if (scroller) {
        scrollRef.current = scroller;
        scroller.style.cursor = 'grab';
        cleanup = attachDragToOuter(outer, () => scrollRef.current);
        return;
      }
      if (++attempts < 20) setTimeout(tick, 60);
    };
    tick();
    return () => { if (cleanup) cleanup(); };
  }, []);
  return { outerRef, scrollRef };
}

function attachDragToOuter(outer, getScroller) {
  let isDown = false, moved = false, startX = 0, scrollLeft0 = 0;
  const down = (e) => {
    if (e.button !== undefined && e.button !== 0) return;
    if (e.target && e.target.closest && e.target.closest('button, a, input, [role="button"]')) return;
    const sc = getScroller();
    if (!sc) return;
    isDown = true; moved = false;
    sc.style.cursor = 'grabbing';
    startX = e.pageX;
    scrollLeft0 = sc.scrollLeft;
  };
  const up = () => {
    isDown = false;
    const sc = getScroller();
    if (sc) sc.style.cursor = 'grab';
  };
  const move = (e) => {
    if (!isDown) return;
    const dx = e.pageX - startX;
    if (Math.abs(dx) > 4) moved = true;
    if (moved) {
      e.preventDefault();
      const sc = getScroller();
      if (sc) sc.scrollLeft = scrollLeft0 - dx * 1.5;
    }
  };
  const click = (e) => { if (moved) { e.preventDefault(); e.stopPropagation(); } };
  const wheel = (e) => {
    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
      const sc = getScroller();
      if (sc) { sc.scrollLeft += e.deltaY; e.preventDefault(); }
    }
  };
  outer.addEventListener('mousedown', down);
  outer.addEventListener('mouseleave', up);
  outer.addEventListener('mouseup', up);
  outer.addEventListener('mousemove', move);
  outer.addEventListener('click', click, true);
  outer.addEventListener('wheel', wheel, { passive: false });
  return () => {
    outer.removeEventListener('mousedown', down);
    outer.removeEventListener('mouseleave', up);
    outer.removeEventListener('mouseup', up);
    outer.removeEventListener('mousemove', move);
    outer.removeEventListener('click', click, true);
    outer.removeEventListener('wheel', wheel);
  };
}

function ScrollButtonsRef({ scrollRef, step = 280 }) {
  const scroll = (dir) => {
    const el = scrollRef.current;
    if (el) el.scrollBy({ left: dir * step, behavior: 'smooth' });
  };
  return (
    <>
      <button type="button" className="scroll-arrow scroll-arrow-left" onClick={() => scroll(-1)}>‹</button>
      <button type="button" className="scroll-arrow scroll-arrow-right" onClick={() => scroll(1)}>›</button>
    </>
  );
}

function Confetti() {
  const pieces = useMemo(() => Array.from({ length: 24 }).map((_, i) => {
    const angle = (i / 24) * Math.PI * 2 + Math.random() * 0.4;
    const dist = 120 + Math.random() * 80;
    const colors = ['#E63946', '#FFB627', '#22C55E', '#A855F7', '#3B82F6', '#FFD700'];
    return {
      dx: Math.cos(angle) * dist + 'px',
      dy: Math.sin(angle) * dist + 'px',
      rot: Math.random() * 540 - 270 + 'deg',
      bg: colors[i % colors.length],
      delay: (Math.random() * 0.15) + 's',
    };
  }), []);
  return (
    <div className="confetti-host">
      {pieces.map((p, i) => (
        <div key={i} className="confetti-piece" style={{
          '--dx': p.dx, '--dy': p.dy, '--rot': p.rot,
          background: p.bg, animationDelay: p.delay,
        }}/>
      ))}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// FORM PRIMITIVES — Toggle / Input / Btn
// ────────────────────────────────────────────────────────────

function Toggle({ on, onChange, size = 'md', ariaLabel }) {
  return (
    <button
      type="button"
      className={`toggle ${size === 'sm' ? 'sm' : ''} ${on ? 'on' : ''}`}
      onClick={() => onChange(!on)}
      aria-label={ariaLabel}
      aria-pressed={on}
    >
      <span className="toggle-knob"/>
    </button>
  );
}

function Input({ label, value, onChange, type = 'text', placeholder, readOnly, error, mono, helper, autoFocus }) {
  const inputRef = useRef(null);
  useEffect(() => {
    if (autoFocus && inputRef.current) inputRef.current.focus();
  }, [autoFocus]);
  return (
    <div className="field">
      {label && <label className="field-label">{label}</label>}
      <input
        ref={inputRef}
        className={`field-input ${mono ? 'mono' : ''} ${readOnly ? 'readonly' : ''} ${error ? 'error' : ''}`}
        type={type}
        value={value}
        onChange={(e) => onChange && onChange(e.target.value)}
        placeholder={placeholder}
        readOnly={readOnly}
        disabled={readOnly}
      />
      {helper && <span className={`field-helper ${error ? 'error' : ''}`}>{helper}</span>}
    </div>
  );
}

function Btn({ children, variant = 'primary', size = 'md', onClick, disabled, fullWidth, className = '', type = 'button' }) {
  const cls = ['btn', `btn-${variant}`];
  if (size !== 'md') cls.push(size);
  if (fullWidth) cls.push('btn-fullwidth');
  if (className) cls.push(className);
  return (
    <button type={type} className={cls.join(' ')} onClick={onClick} disabled={disabled}>
      {children}
    </button>
  );
}

function Checkbox({ checked, onChange, children }) {
  return (
    <div className={'cb ' + (checked ? 'on' : '')} onClick={() => onChange(!checked)} role="checkbox" aria-checked={checked}>
      <div className="cb-box">
        <svg width="12" height="10" viewBox="0 0 12 10"><path d="M1 5 L4.5 8.5 L11 1.5" stroke="#fff" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
      </div>
      <span>{children}</span>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// MODAL
// ────────────────────────────────────────────────────────────

function Modal({ open, onClose, title, subtitle, children, footer, width = 460, shake }) {
  useBodyScrollLock(open);
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);
  if (!open) return null;
  const node = (
    <div className="modal-overlay" onClick={onClose}>
      <div
        className={'modal-body' + (shake ? ' shake' : '')}
        style={{ maxWidth: width }}
        onClick={(e) => e.stopPropagation()}
      >
        <button type="button" className="modal-close" onClick={onClose} aria-label="Закрыть">✕</button>
        {title && <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 18, color: W.CX.white, letterSpacing: '0.08em', paddingRight: 36 }}>{title}</div>}
        {subtitle && <div style={{ marginTop: 8, fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec, lineHeight: 1.5 }}>{subtitle}</div>}
        <div style={{ marginTop: title ? 18 : 0 }}>{children}</div>
        {footer && <div style={{ marginTop: 22, display: 'flex', gap: 10, justifyContent: 'flex-end' }}>{footer}</div>}
      </div>
    </div>
  );
  return ReactDOM.createPortal(node, document.body);
}

// ────────────────────────────────────────────────────────────
// МОБИЛЬНАЯ ВЕРСИЯ (без изменений из v0.2 кроме иконки Профиль→Настройки)
// ────────────────────────────────────────────────────────────

function ClickWrap({ children, onBack }) {
  return (
    <div style={{ position: 'relative', width: '100%', height: '100%' }}>
      {children}
      <button type="button" onClick={onBack} aria-label="Назад" style={{
        position: 'absolute', top: 50, left: 8, width: 56, height: 50,
        background: 'transparent', border: 'none', cursor: 'pointer', zIndex: 100, padding: 0,
      }}/>
    </div>
  );
}

function InteractiveMain({ activeTab, setActiveTab, go, showToast, showConfetti, onSettings }) {
  const stripRef = useDragScroll();
  const tabs = [
    { id: 'rewards', label: 'НАГРАДЫ' },
    { id: 'tasks',   label: 'ЗАДАНИЯ' },
    { id: 'top',     label: 'ТАБЛИЦА' },
  ];
  const rewards = W.SAMPLE_REWARDS || [];
  const tasks = W.SAMPLE_TASKS || [];
  return (
    <div style={{ height: '100%', overflow: 'hidden', position: 'relative' }}>
      <W.CXBackground accent={W.CX.red}/>
      <div style={{ position: 'relative', height: '100%', overflowY: 'auto', paddingBottom: 84, scrollbarWidth: 'none' }}>
        <W.CXHeader title="СЕЗОН 1: ОПЕРАЦИЯ COPPER" sub="до конца сезона: 47 дней"/>
        <W.ProfileCard nick="TENZ_RU" level={15} xp={3500} nextXp={5000} premium={false} initials="TZ"/>
        <W.SeasonProgress toLevel={16} xpLeft={1500} daysLeft={47}/>
        <div style={{ display: 'flex', gap: 8, padding: '14px 16px 4px' }}>
          {tabs.map(t => {
            const on = t.id === activeTab;
            return (
              <div key={t.id} onClick={() => setActiveTab(t.id)} style={{
                flex: 1, padding: '10px 6px', textAlign: 'center', borderRadius: 8,
                background: on ? W.CX.red : 'transparent',
                border: `1px solid ${on ? W.CX.red : W.CX.line}`,
                fontFamily: W.FONT_DISPLAY, fontSize: 12, letterSpacing: '0.14em',
                color: on ? W.CX.white : W.CX.textSec, fontWeight: 700,
                boxShadow: on ? `0 0 14px ${W.CX.red}77` : 'none',
                cursor: 'pointer', userSelect: 'none', transition: 'all .15s',
              }}>{t.label}</div>
            );
          })}
        </div>
        {activeTab === 'rewards' && (
          <>
            <div style={{ position: 'relative' }}>
              <div ref={stripRef} style={{ display: 'flex', gap: 8, padding: '16px 16px 4px',
                overflowX: 'auto', overflowY: 'hidden', scrollbarWidth: 'none', WebkitOverflowScrolling: 'touch' }}>
                {rewards.map(r => {
                  const locked = r.lvl > 15;
                  const current = r.lvl === 15;
                  return (
                    <div key={r.lvl} onClick={() => go('reward', { reward: r.lvl })}
                         style={{ cursor: 'pointer', flexShrink: 0 }} title={`Уровень ${r.lvl}`}>
                      <W.LevelColumn level={r.lvl} freeReward={r.free} premReward={r.prem}
                        current={current} locked={locked} claimedFree={r.lvl <= 14} claimedPrem={false} hasPremium={false}/>
                    </div>
                  );
                })}
              </div>
              <ScrollButtons targetRef={stripRef} step={160}/>
            </div>
            <div style={{ padding: '8px 16px 0' }}>
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10, marginTop: 6 }}>
                <W.Display size={16} color={W.CX.white} tracking={0.12}>АКТИВНЫЕ ЗАДАНИЯ</W.Display>
                <span style={{ fontFamily: W.FONT_MONO, fontSize: 11, color: W.CX.textMute }}>
                  {tasks.filter(t => !t.done).length} активно
                </span>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {tasks.map((t, i) => (
                  <div key={i} onClick={() => { showToast('Задание принято — погнали!'); showConfetti(); }} style={{ cursor: 'pointer' }}>
                    <W.TaskCard icon={t.icon} title={t.title} desc={t.desc} xp={t.xp}
                      progress={t.progress} max={t.max} deadline={t.deadline}
                      tierColor={t.tier} steam={t.steam} done={t.done} expiring={t.expiring}/>
                  </div>
                ))}
              </div>
            </div>
            <div onClick={() => go('tasks')} style={{ cursor: 'pointer' }}>
              <W.CTAButton label="ОТКРЫТЬ ВСЕ ЗАДАНИЯ"/>
            </div>
            <div onClick={() => go('premium')} style={{
              margin: '14px 16px 8px', padding: 14, borderRadius: 12,
              background: `linear-gradient(135deg, rgba(255,215,0,0.08), rgba(184,134,11,0.04))`,
              border: `1px solid ${W.CX.premiumGold}33`,
              display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer', transition: 'all .15s',
            }}>
              <W.PremiumStar size={36}/>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 13, color: W.CX.premiumGold, letterSpacing: '0.14em' }}>PREMIUM PASS</div>
                <div style={{ fontFamily: W.FONT_BODY, fontSize: 11.5, color: W.CX.textSec, marginTop: 2, lineHeight: 1.35 }}>
                  +50% XP, эксклюзивные награды, ДР под ключ на 30 ур.
                </div>
              </div>
              <svg width="14" height="14" viewBox="0 0 14 14"><path d="M4 2 L10 7 L4 12" stroke={W.CX.premiumGold} strokeWidth="2" fill="none" strokeLinecap="round"/></svg>
            </div>
          </>
        )}
        {activeTab === 'tasks' && (
          <div style={{ padding: '16px' }}>
            <W.Display size={14} color={W.CX.textSec} tracking={0.14}>ВЫПОЛНИ И ПОЛУЧИ XP</W.Display>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 12 }}>
              {tasks.map((t, i) => (
                <div key={i} onClick={() => { showToast('Задание принято — погнали!'); showConfetti(); }} style={{ cursor: 'pointer' }}>
                  <W.TaskCard icon={t.icon} title={t.title} desc={t.desc} xp={t.xp}
                    progress={t.progress} max={t.max} deadline={t.deadline}
                    tierColor={t.tier} steam={t.steam} done={t.done} expiring={t.expiring}/>
                </div>
              ))}
            </div>
            <div onClick={() => go('tasks')} style={{ cursor: 'pointer' }}>
              <W.CTAButton label="ВСЕ ЗАДАНИЯ СЕЗОНА"/>
            </div>
          </div>
        )}
        {activeTab === 'top' && (
          <div style={{ padding: '24px 16px', textAlign: 'center' }}>
            <W.Display size={14} color={W.CX.textSec} tracking={0.14}>ТАБЛИЦА ЛИДЕРОВ</W.Display>
            <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 8, marginBottom: 16, lineHeight: 1.5 }}>
              Открой подробный экран с топ-50 клуба
            </div>
            <div onClick={() => go('leaderboard')} style={{ cursor: 'pointer' }}>
              <W.CTAButton label="ОТКРЫТЬ ТАБЛИЦУ"/>
            </div>
          </div>
        )}
      </div>
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        background: 'rgba(13,15,20,0.95)', backdropFilter: 'blur(20px)',
        borderTop: `1px solid ${W.CX.line}`, paddingTop: 8, paddingBottom: 16, paddingLeft: 8, paddingRight: 8,
        display: 'flex', justifyContent: 'space-around', zIndex: 20,
      }}>
        {[
          { id: 'home',     label: 'Главная',   icon: <path d="M3 11 L12 3 L21 11 L21 21 L14 21 L14 14 L10 14 L10 21 L3 21 Z"/>, action: () => setActiveTab('rewards') },
          { id: 'pass',     label: 'Pass',      icon: <path d="M12 2 L4 6 L4 13 Q4 19 12 22 Q20 19 20 13 L20 6 Z M9 12 L11 14 L15 10"/>, action: () => setActiveTab('rewards'), active: activeTab === 'rewards' },
          { id: 'tops',     label: 'Топы',      icon: <path d="M5 4 L5 10 Q5 14 12 14 Q19 14 19 10 L19 4 M5 6 L2 6 L2 9 Q2 11 5 11 M19 6 L22 6 L22 9 Q22 11 19 11 M12 14 L12 18 M8 21 L16 21 L15 18 L9 18 Z"/>, action: () => go('leaderboard') },
          { id: 'settings', label: 'Настройки', icon: <><circle cx="12" cy="12" r="3"/><path d="M12 1 L13.5 4 L17 3 L17 6.5 L20 8 L18.5 11 L20 14 L17 15.5 L17 19 L13.5 18 L12 21 L10.5 18 L7 19 L7 15.5 L4 14 L5.5 11 L4 8 L7 6.5 L7 3 L10.5 4 Z"/></>, action: onSettings },
        ].map(it => (
          <div key={it.id} onClick={it.action} style={{
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2,
            padding: '6px 12px', flex: 1, cursor: 'pointer',
          }}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill={it.active ? W.CX.red : 'none'}
              stroke={it.active ? W.CX.red : W.CX.textMute} strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round"
              style={{ filter: it.active ? `drop-shadow(0 0 6px ${W.CX.red}77)` : 'none', transition: 'all .15s' }}>
              {it.icon}
            </svg>
            <span style={{
              fontFamily: W.FONT_BODY, fontSize: 10.5, fontWeight: it.active ? 600 : 500,
              color: it.active ? W.CX.red : W.CX.textMute, letterSpacing: 0.2,
            }}>{it.label}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function MobileApp({ onJumpToDesktopSettings }) {
  const [screen, setScreen] = useState('main');
  const [activeTab, setActiveTab] = useState('rewards');
  const [selectedReward, setSelectedReward] = useState(20);
  const [stack, setStack] = useState([]);
  const [toast, setToast] = useState(null);
  const [confettiKey, setConfettiKey] = useState(0);
  const [confettiOn, setConfettiOn] = useState(false);

  const go = useCallback((next, data = {}) => {
    setStack(s => [...s, screen]);
    if (data.reward !== undefined) setSelectedReward(data.reward);
    setScreen(next);
  }, [screen]);
  const back = useCallback(() => {
    setStack(s => {
      if (s.length === 0) { setScreen('main'); return s; }
      const prev = s[s.length - 1];
      setScreen(prev);
      return s.slice(0, -1);
    });
  }, []);
  const showToast = useCallback((msg) => { setToast(msg); setTimeout(() => setToast(null), 2500); }, []);
  const showConfetti = useCallback(() => {
    setConfettiKey(k => k + 1); setConfettiOn(true);
    setTimeout(() => setConfettiOn(false), 1500);
  }, []);

  useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') back(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [back]);

  function renderScreen() {
    if (screen === 'main') return (
      <InteractiveMain activeTab={activeTab} setActiveTab={setActiveTab}
        go={go} showToast={showToast} showConfetti={showConfetti}
        onSettings={onJumpToDesktopSettings}/>
    );
    if (screen === 'tasks' && W.TasksScreen)
      return <ClickWrap onBack={back}><W.TasksScreen variant="full"/></ClickWrap>;
    if (screen === 'premium' && W.PremiumPurchaseScreen)
      return <ClickWrap onBack={back}><W.PremiumPurchaseScreen active={false}/></ClickWrap>;
    if (screen === 'leaderboard' && W.LeaderboardScreen)
      return <ClickWrap onBack={back}><W.LeaderboardScreen/></ClickWrap>;
    if (screen === 'reward' && W.RewardDetailScreen)
      return <ClickWrap onBack={back}><W.RewardDetailScreen level={selectedReward} unlocked={selectedReward <= 15} hasPremium={true}/></ClickWrap>;
    return <ClickWrap onBack={back}><div style={{ padding: 80, color: '#B8B8C0', textAlign: 'center' }}>Экран «{screen}» не реализован</div></ClickWrap>;
  }

  return (
    <W.PhoneFrame>
      {renderScreen()}
      {confettiOn && <Confetti key={confettiKey}/>}
      {toast && <div className="toast">✓ {toast}</div>}
    </W.PhoneFrame>
  );
}

// ────────────────────────────────────────────────────────────
// DESKTOP NAV + SIDEBAR
// ────────────────────────────────────────────────────────────

const DESKTOP_NAV = [
  { id: 'pass',     label: 'Battle Pass',     icon: 'M12 2 L4 6 L4 13 Q4 19 12 22 Q20 19 20 13 L20 6 Z' },
  { id: 'tasks',    label: 'Задания',         icon: 'M5 4 L19 4 L19 20 L5 20 Z M8 8 L16 8 M8 12 L16 12 M8 16 L14 16' },
  { id: 'top',      label: 'Лидеры',          icon: 'M5 4 L19 4 L19 9 Q19 13 12 13 Q5 13 5 9 Z M12 13 L12 17 M8 21 L16 21' },
  { id: 'shop',     label: 'Магазин бонусов', icon: 'M4 7 L20 7 L18 19 L6 19 Z M8 7 L8 4 Q8 2 12 2 Q16 2 16 4 L16 7' },
  { id: 'club',     label: 'Клуб',            icon: 'M3 21 L3 9 L12 3 L21 9 L21 21 M9 21 L9 14 L15 14 L15 21' },
  { id: 'settings', label: 'Настройки',       icon: 'M12 8 A4 4 0 1 0 12 16 A4 4 0 0 0 12 8 M12 1 L13.5 4 L17 3 L17 6.5 L20 8 L18.5 11 L20 14 L17 15.5 L17 19 L13.5 18 L12 21 L10.5 18 L7 19 L7 15.5 L4 14 L5.5 11 L4 8 L7 6.5 L7 3 L10.5 4 Z' },
];

function DesktopSidebar({ section, setSection, totalXP }) {
  const stats = [
    { l: 'Часов в клубе', v: useCountUp(42, 700, [section]) },
    { l: 'Заданий',       v: useCountUp(23, 700, [section]) },
    { l: 'Рефералов',     v: useCountUp(4,  700, [section]) },
    { l: 'Турниров',      v: useCountUp(2,  700, [section]) },
  ];
  const xpVal = useCountUp(totalXP, 800, [section, totalXP]);
  return (
    <div style={{
      width: 280, padding: 24, background: 'rgba(13,15,20,0.6)',
      borderRight: `1px solid ${W.CX.line}`, display: 'flex', flexDirection: 'column',
      flexShrink: 0, position: 'relative', zIndex: 5,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <W.CXMark size={32} color={W.CX.red} glow/>
        <div>
          <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 16, color: W.CX.white, letterSpacing: '0.06em' }}>
            CYBER<span style={{ color: W.CX.red }}>X</span>
          </div>
          <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 9, color: W.CX.textMute, letterSpacing: '0.24em' }}>BATTLE PASS</div>
        </div>
      </div>

      <div style={{
        marginTop: 24, padding: 16, borderRadius: 12,
        background: `linear-gradient(160deg, ${W.CX.card}, ${W.CX.black})`,
        border: `1px solid ${W.CX.line}`, display: 'flex', flexDirection: 'column', alignItems: 'center',
        position: 'relative', overflow: 'hidden',
      }}>
        <div style={{ position: 'absolute', top: -30, right: -30, width: 120, height: 120,
          background: `radial-gradient(circle, ${W.CX.silverHi}22, transparent 70%)` }}/>
        <W.Avatar size={72} tier={W.TIERS.knight} initials="TZ"/>
        <div style={{ marginTop: 10, fontFamily: W.FONT_DISPLAY, fontSize: 16, color: W.CX.white, letterSpacing: '0.06em' }}>TENZ_RU</div>
        <div style={{ marginTop: 2, fontFamily: W.FONT_DISPLAY, fontSize: 11, color: W.CX.silverHi, letterSpacing: '0.2em' }}>KNIGHT • УР. 15</div>
        <div style={{ marginTop: 10, width: '100%' }} className="xpbar-glow">
          <W.XPBar value={xpVal} max={5000} color={W.CX.amber} label={`До ур. 16`} height={6}/>
        </div>
      </div>

      <div style={{ marginTop: 14, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
        {stats.map(s => (
          <div key={s.l} style={{ padding: 8, borderRadius: 8, background: W.CX.card, border: `1px solid ${W.CX.line}` }}>
            <div style={{ fontFamily: W.FONT_MONO, fontSize: 16, color: W.CX.white, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{s.v}</div>
            <div style={{ fontFamily: W.FONT_BODY, fontSize: 10, color: W.CX.textMute, letterSpacing: 0.3 }}>{s.l}</div>
          </div>
        ))}
      </div>

      <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 2 }}>
        {DESKTOP_NAV.map(it => {
          const active = it.id === section;
          return (
            <div key={it.id} onClick={() => setSection(it.id)} style={{
              padding: '10px 12px', borderRadius: 8,
              display: 'flex', alignItems: 'center', gap: 12,
              background: active ? `${W.CX.red}22` : 'transparent',
              border: active ? `1px solid ${W.CX.red}55` : '1px solid transparent',
              color: active ? W.CX.white : W.CX.textSec,
              fontFamily: W.FONT_BODY, fontSize: 13, fontWeight: active ? 600 : 500,
              cursor: 'pointer', userSelect: 'none', transition: 'all .15s',
            }}
            onMouseEnter={e => { if (!active) e.currentTarget.style.background = 'rgba(255,255,255,0.04)'; }}
            onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
              <svg width="18" height="18" viewBox="0 0 24 24" stroke={active ? W.CX.red : W.CX.textSec} strokeWidth="1.8" fill="none" strokeLinejoin="round" strokeLinecap="round">
                <path d={it.icon}/>
              </svg>
              {it.label}
              {active && <div className="pulse-dot" style={{ marginLeft: 'auto', width: 6, height: 6, borderRadius: '50%', background: W.CX.red }}/>}
            </div>
          );
        })}
      </div>

      <div style={{ marginTop: 'auto', paddingTop: 18, fontFamily: W.FONT_MONO, fontSize: 10, color: W.CX.textMute, letterSpacing: 0.3 }}>
        CyberX Копейск • v0.4.2-beta
      </div>
    </div>
  );
}

function DesktopRight({ onPremium }) {
  return (
    <div style={{
      width: 290, padding: 20, background: 'rgba(13,15,20,0.4)',
      borderLeft: `1px solid ${W.CX.line}`, overflow: 'auto', flexShrink: 0,
      position: 'relative', zIndex: 5,
    }}>
      <div style={{ marginBottom: 10, display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
        <W.Display size={13} color={W.CX.white} tracking={0.16}>ТОП КЛУБА</W.Display>
        <span style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textMute }}>сезон 1</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
        {[
          { r: 1, n: 'WRAITH_42', l: 30, xp: 30000, p: true, i: 'WR' },
          { r: 2, n: 'NEON_K',    l: 29, xp: 27450, p: true, i: 'NK' },
          { r: 3, n: 'ZED_HVH',   l: 28, xp: 25800, p: false,i: 'ZD' },
          { r: 4, n: 'CHRONIC',   l: 27, xp: 24100, p: true, i: 'CH' },
          { r: 5, n: 'BOMBL4',    l: 26, xp: 22950, p: true, i: 'BL' },
        ].map((p, i) => {
          const t = W.tierFor(p.l);
          const pc = p.r === 1 ? W.CX.premiumGold : p.r === 2 ? W.CX.silver : p.r === 3 ? W.CX.bronze : W.CX.textMute;
          return (
            <div key={p.r} className="stagger-item" style={{
              display: 'flex', alignItems: 'center', gap: 8, padding: '8px 10px',
              borderRadius: 8, background: W.CX.card, border: `1px solid ${W.CX.line}`,
              animationDelay: `${i * 50}ms`,
            }}>
              <div style={{ width: 20, fontFamily: W.FONT_DISPLAY, fontSize: 13, color: pc, textAlign: 'center' }}>{p.r}</div>
              <W.Avatar size={28} tier={t} initials={p.i}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 11, color: W.CX.white, letterSpacing: '0.04em' }}>
                  {p.n} {p.p && <W.PremiumStar size={8}/>}
                </div>
                <div style={{ fontFamily: W.FONT_MONO, fontSize: 9.5, color: W.CX.textSec, marginTop: 1 }}>
                  <W.MonoNum n={p.xp}/> XP
                </div>
              </div>
            </div>
          );
        })}
        <div className="stagger-item" style={{
          marginTop: 4, padding: '8px 10px', borderRadius: 8,
          background: `linear-gradient(180deg, ${W.CX.red}22, transparent)`,
          border: `1px solid ${W.CX.red}77`,
          display: 'flex', alignItems: 'center', gap: 8, animationDelay: '300ms',
        }}>
          <div style={{ width: 20, fontFamily: W.FONT_DISPLAY, fontSize: 13, color: W.CX.red, textAlign: 'center' }}>34</div>
          <W.Avatar size={28} tier={W.TIERS.knight} initials="TZ"/>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 11, color: W.CX.white, letterSpacing: '0.04em' }}>ТЫ • TENZ_RU</div>
            <div style={{ fontFamily: W.FONT_MONO, fontSize: 9.5, color: W.CX.textSec, marginTop: 1 }}><W.MonoNum n={3500}/> XP</div>
          </div>
        </div>
      </div>

      <div style={{
        marginTop: 18, padding: 16, borderRadius: 12,
        background: `linear-gradient(160deg, ${W.CX.premiumGold}22, ${W.CX.card})`,
        border: `1.5px solid ${W.CX.premiumGold}77`,
        boxShadow: `0 0 20px ${W.CX.premiumGold}33`,
        position: 'relative', overflow: 'hidden',
      }}>
        <div style={{ position: 'absolute', top: -30, right: -30, width: 100, height: 100,
          background: `radial-gradient(circle, ${W.CX.premiumGold}55, transparent)`, filter: 'blur(20px)' }}/>
        <div style={{ position: 'relative' }}>
          <W.PremiumStar size={32}/>
          <div style={{ marginTop: 8, fontFamily: W.FONT_DISPLAY, fontSize: 18, color: W.CX.premiumGold, letterSpacing: '0.06em' }}>PREMIUM PASS</div>
          <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textSec, lineHeight: 1.4, marginTop: 6 }}>
            +50% XP, эксклюзивные награды, ДР под ключ на 30 ур.
          </div>
          <div style={{ marginTop: 10, display: 'flex', alignItems: 'baseline', gap: 5 }}>
            <span style={{ fontFamily: W.FONT_DISPLAY, fontSize: 28, color: W.CX.white }}>1 490</span>
            <span style={{ fontFamily: W.FONT_DISPLAY, fontSize: 16, color: W.CX.premiumGold }}>₽</span>
            <span style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textMute }}>/ сезон</span>
          </div>
          <div onClick={onPremium} className="shimmer" style={{
            marginTop: 12, padding: '12px', borderRadius: 8, cursor: 'pointer',
            background: `linear-gradient(135deg, ${W.CX.gold}, ${W.CX.premiumGold} 60%, #B8860B)`,
            boxShadow: `0 4px 16px ${W.CX.premiumGold}55`,
            fontFamily: W.FONT_DISPLAY, fontSize: 13, letterSpacing: '0.14em',
            color: '#3a2700', fontWeight: 700, textAlign: 'center',
          }}>АКТИВИРОВАТЬ</div>
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// DESKTOP CENTER — PASS / TASKS / TOP / SHOP / CLUB
// ────────────────────────────────────────────────────────────

function DesktopCenterPass() {
  const { outerRef, scrollRef } = useDragScrollOnChild();
  const tasks = W.SAMPLE_TASKS || [];
  return (
    <div className="section-enter">
      <div className="stagger-item" style={{
        padding: 18, borderRadius: 14,
        background: `linear-gradient(135deg, ${W.CX.red}22 0%, ${W.CX.card} 50%, ${W.CX.bronze}22 100%)`,
        border: `1px solid ${W.CX.red}44`,
        display: 'flex', alignItems: 'center', gap: 20,
        position: 'relative', overflow: 'hidden', animationDelay: '0ms',
      }}>
        <div style={{ position: 'absolute', right: -20, top: -40, width: 220, height: 220,
          background: `radial-gradient(circle, ${W.CX.red}55, transparent 70%)`, filter: 'blur(40px)' }}/>
        <div style={{ width: 64, height: 64, borderRadius: 12, flexShrink: 0,
          background: `linear-gradient(135deg, ${W.CX.bronze}, ${W.CX.bronzeHi})`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: `0 0 24px ${W.CX.bronze}77` }}>
          <W.Display size={28} color="#3a1f00">S1</W.Display>
        </div>
        <div style={{ flex: 1, position: 'relative' }}>
          <W.Display size={11} color={W.CX.bronzeHi} tracking={0.32}>СЕЗОН 1 • 90 ДНЕЙ • 30 УРОВНЕЙ</W.Display>
          <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 28, color: W.CX.white, letterSpacing: '0.06em', marginTop: 4 }}>ОПЕРАЦИЯ COPPER</div>
          <div style={{ fontFamily: W.FONT_BODY, fontSize: 12.5, color: W.CX.textSec, marginTop: 4 }}>
            Стартовый сезон CyberX Battle Pass. Зарабатывай XP за часы, задания, турниры и Steam-челленджи.
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textMute, letterSpacing: 0.4, textTransform: 'uppercase' }}>Завершится</div>
          <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 22, color: W.CX.white, marginTop: 2 }}>47 ДНЕЙ</div>
          <div style={{ fontFamily: W.FONT_MONO, fontSize: 11, color: W.CX.textMute }}>12.08.2026 23:59 МСК</div>
        </div>
      </div>

      <div className="stagger-item" style={{ marginTop: 22, display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', animationDelay: '60ms' }}>
        <W.Display size={16} color={W.CX.white} tracking={0.16}>ДОРОЖКА НАГРАД</W.Display>
        <div style={{ display: 'flex', gap: 14, fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textSec }}>
          <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: W.CX.silver }}/> Free
          </span>
          <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: W.CX.premiumGold, boxShadow: `0 0 6px ${W.CX.premiumGold}` }}/> Premium
          </span>
        </div>
      </div>

      <div ref={outerRef} className="stagger-item" style={{
        marginTop: 10, position: 'relative', borderRadius: 14, overflow: 'hidden', animationDelay: '100ms',
      }}>
        <W.WebRewardTrack/>
        <ScrollButtonsRef scrollRef={scrollRef} step={300}/>
      </div>

      <div className="stagger-item" style={{ marginTop: 22, animationDelay: '160ms' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
          <W.Display size={16} color={W.CX.white} tracking={0.16}>АКТИВНЫЕ ЗАДАНИЯ</W.Display>
          <span style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.red, fontWeight: 600 }}>Все задания →</span>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          {tasks.map((t, i) => (
            <div key={i} className="stagger-item card-lift" style={{ animationDelay: `${200 + i * 50}ms` }}>
              <W.TaskCard {...t}/>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function DesktopCenterTasks() {
  const tasks = W.SAMPLE_TASKS || [];
  const grouped = [
    { title: 'ЕЖЕДНЕВНЫЕ', items: tasks.slice(0, 2) },
    { title: 'СЕЗОННЫЕ',   items: tasks.slice(2) },
  ];
  return (
    <div className="section-enter">
      <div className="stagger-item" style={{ animationDelay: '0ms' }}>
        <W.Display size={20} color={W.CX.white} tracking={0.16}>ВСЕ ЗАДАНИЯ СЕЗОНА</W.Display>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 4 }}>
          Выполняй задания и получай XP. Чем больше XP — тем выше уровень и круче награды.
        </div>
      </div>
      {grouped.map((g, gi) => (
        <div key={g.title} className="stagger-item" style={{ marginTop: 22, animationDelay: `${60 + gi * 80}ms` }}>
          <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 12, letterSpacing: '0.24em', color: W.CX.textSec, marginBottom: 10 }}>{g.title}</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            {g.items.map((t, i) => (
              <div key={i} className="stagger-item card-lift" style={{ animationDelay: `${140 + gi * 80 + i * 50}ms` }}>
                <W.TaskCard {...t}/>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function DesktopCenterTop() {
  const players = [
    { r: 1, n: 'WRAITH_42', l: 30, xp: 30000, p: true,  i: 'WR' },
    { r: 2, n: 'NEON_K',    l: 29, xp: 27450, p: true,  i: 'NK' },
    { r: 3, n: 'ZED_HVH',   l: 28, xp: 25800, p: false, i: 'ZD' },
    { r: 4, n: 'CHRONIC',   l: 27, xp: 24100, p: true,  i: 'CH' },
    { r: 5, n: 'BOMBL4',    l: 26, xp: 22950, p: true,  i: 'BL' },
    { r: 6, n: 'KILLJOY',   l: 24, xp: 19880, p: false, i: 'KJ' },
    { r: 7, n: 'PHANTOM',   l: 23, xp: 18420, p: true,  i: 'PH' },
    { r: 8, n: 'BREEZE',    l: 22, xp: 17560, p: false, i: 'BR' },
  ];
  return (
    <div className="section-enter">
      <div className="stagger-item" style={{ animationDelay: '0ms' }}>
        <W.Display size={20} color={W.CX.white} tracking={0.16}>ЛИДЕРЫ СЕЗОНА</W.Display>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 4 }}>
          Топ-30 клуба по XP в сезоне «Операция COPPER»
        </div>
      </div>
      <div style={{ marginTop: 20, display: 'flex', flexDirection: 'column', gap: 4 }}>
        {players.map((p, i) => {
          const t = W.tierFor(p.l);
          const pc = p.r === 1 ? W.CX.premiumGold : p.r === 2 ? W.CX.silver : p.r === 3 ? W.CX.bronze : W.CX.textMute;
          return (
            <div key={p.r} className="stagger-item card-lift" style={{
              display: 'flex', alignItems: 'center', gap: 14, padding: '12px 18px',
              borderRadius: 10, background: W.CX.card, border: `1px solid ${W.CX.line}`,
              animationDelay: `${60 + i * 40}ms`,
            }}>
              <div style={{ width: 32, fontFamily: W.FONT_DISPLAY, fontSize: 20, color: pc, textAlign: 'center' }}>{p.r}</div>
              <W.Avatar size={40} tier={t} initials={p.i}/>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 14, color: W.CX.white, letterSpacing: '0.06em' }}>
                  {p.n} {p.p && <W.PremiumStar size={11}/>}
                </div>
                <div style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textSec, marginTop: 2 }}>{t.name} • УР. {p.l}</div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 18, color: W.CX.white }}><W.MonoNum n={p.xp}/></div>
                <div style={{ fontFamily: W.FONT_BODY, fontSize: 10, color: W.CX.textMute }}>XP</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function DesktopCenterShop() {
  const items = [
    { icon: '⏱️', name: '+1 час игры',         price: '300 XP',   desc: 'Один раз в день' },
    { icon: '🎁', name: 'Стикерпак CyberX',    price: '500 XP',   desc: 'Лимит 1 на сезон' },
    { icon: '👕', name: 'Футболка CyberX',     price: '8 000 XP', desc: 'Размер на выбор' },
    { icon: '🥤', name: 'Энергетик в баре',    price: '150 XP',   desc: 'Любой 0.5л' },
    { icon: '🎮', name: 'Турнирный слот',      price: '1 000 XP', desc: 'Запись вне очереди' },
    { icon: '🎯', name: '+50% XP buff (24ч)',  price: '2 000 XP', desc: 'Premium-only' },
  ];
  return (
    <div className="section-enter">
      <div className="stagger-item" style={{ animationDelay: '0ms' }}>
        <W.Display size={20} color={W.CX.white} tracking={0.16}>МАГАЗИН БОНУСОВ</W.Display>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 4 }}>Трать XP на бенефиты внутри клуба и мерч CyberX</div>
      </div>
      <div style={{ marginTop: 20, display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
        {items.map((it, i) => (
          <div key={i} className="stagger-item card-lift" style={{
            padding: 18, borderRadius: 12, background: W.CX.card, border: `1px solid ${W.CX.line}`,
            display: 'flex', flexDirection: 'column', gap: 8, cursor: 'pointer',
            animationDelay: `${60 + i * 50}ms`,
          }}>
            <div style={{ fontSize: 32 }}>{it.icon}</div>
            <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 16, color: W.CX.white, letterSpacing: '0.04em' }}>{it.name}</div>
            <div style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textSec }}>{it.desc}</div>
            <div style={{ marginTop: 4, fontFamily: W.FONT_DISPLAY, fontSize: 18, color: W.CX.amber, letterSpacing: '0.04em' }}>{it.price}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function DesktopCenterClub() {
  return (
    <div className="section-enter">
      <div className="stagger-item" style={{ animationDelay: '0ms' }}>
        <W.Display size={20} color={W.CX.white} tracking={0.16}>CYBERX КОПЕЙСК</W.Display>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 4 }}>Адрес, часы работы, состав клуба</div>
      </div>
      <div className="stagger-item" style={{ marginTop: 24, padding: 24, borderRadius: 14, background: W.CX.card, border: `1px solid ${W.CX.line}`, animationDelay: '60ms' }}>
        <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 14, letterSpacing: '0.24em', color: W.CX.textSec }}>АДРЕС</div>
        <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 22, color: W.CX.white, marginTop: 6 }}>Копейск, пр. Ленина, 42</div>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec, marginTop: 4 }}>ТРЦ «Тополь», 2-й этаж • работаем 24/7</div>
        <div style={{ marginTop: 24, display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
          {[
            { l: 'ПК-зон', v: '38' }, { l: 'PS5-зон', v: '4' }, { l: 'VR', v: '2' },
            { l: 'Игроков клуба', v: '1 240' }, { l: 'В сезоне', v: '420' }, { l: 'Премиум', v: '67' },
          ].map((s, i) => (
            <div key={s.l} className="stagger-item" style={{ padding: 12, borderRadius: 8, background: W.CX.black, border: `1px solid ${W.CX.line}`, animationDelay: `${120 + i * 40}ms` }}>
              <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 22, color: W.CX.white }}>{s.v}</div>
              <div style={{ fontFamily: W.FONT_BODY, fontSize: 10, color: W.CX.textMute, letterSpacing: 0.3, marginTop: 2 }}>{s.l}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// SETTINGS — компонент + модалки
// ────────────────────────────────────────────────────────────

function SettingsCard({ title, children, delay = 0 }) {
  return (
    <div className="stagger-item" style={{
      marginTop: 16, padding: 22, borderRadius: 14, background: W.CX.card,
      border: `1px solid ${W.CX.line}`, animationDelay: `${delay}ms`,
    }}>
      {title && <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 12, letterSpacing: '0.24em', color: W.CX.textSec, marginBottom: 14 }}>{title}</div>}
      {children}
    </div>
  );
}

function GreenChip({ children }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '3px 8px', borderRadius: 4, fontFamily: W.FONT_DISPLAY,
      fontSize: 10, letterSpacing: '0.16em', color: '#16A34A',
      background: 'rgba(34,197,94,0.12)', border: '1px solid rgba(34,197,94,0.3)',
    }}>{children}</span>
  );
}
function NeutralChip({ children }) {
  return (
    <span style={{
      display: 'inline-flex', padding: '3px 8px', borderRadius: 4,
      fontFamily: W.FONT_BODY, fontSize: 10.5, color: W.CX.textMute,
      background: 'rgba(255,255,255,0.04)', border: `1px solid ${W.CX.line}`,
    }}>{children}</span>
  );
}

// ── Steam-style icon (used in modal & attachment) ──
function SteamIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: size / 2,
      background: '#1B2838', display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0, boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.08)',
    }}>
      <svg width={size * 0.55} height={size * 0.55} viewBox="0 0 24 24" fill="#fff">
        <circle cx="12" cy="12" r="9" fill="none" stroke="#fff" strokeWidth="1.5"/>
        <circle cx="9" cy="13" r="2" stroke="#fff" strokeWidth="1.2" fill="none"/>
        <circle cx="16" cy="9" r="2.5" stroke="#fff" strokeWidth="1.2" fill="none"/>
        <path d="M9 13 L16 9" stroke="#fff" strokeWidth="1.2"/>
      </svg>
    </div>
  );
}
function FaceitIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 8, background: '#FF5500',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0, color: '#fff', fontFamily: W.FONT_DISPLAY,
      fontSize: size * 0.5, fontWeight: 800, letterSpacing: '-0.04em',
    }}>F</div>
  );
}
function DiscordIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: 8, background: '#5865F2',
      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
    }}>
      <svg width={size * 0.55} height={size * 0.55} viewBox="0 0 24 24" fill="#fff">
        <path d="M19 5 Q15 3 12 3 Q9 3 5 5 L4 7 Q3 11 4 15 Q5 17 8 18 L9 16 Q7 15 6.5 14 Q9 15 12 15 Q15 15 17.5 14 Q17 15 15 16 L16 18 Q19 17 20 15 Q21 11 20 7 Z"/>
        <circle cx="10" cy="11" r="1.3"/>
        <circle cx="14" cy="11" r="1.3"/>
      </svg>
    </div>
  );
}
function TgIcon({ size = 40 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: size / 2, background: '#0088CC',
      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
    }}>
      <svg width={size * 0.6} height={size * 0.6} viewBox="0 0 24 24" fill="#fff">
        <path d="M21 4 L2 12 L9 14 L11 20 L14 16 L19 20 Z M9 14 L19 6"/>
      </svg>
    </div>
  );
}

// ───── Attachment row для игровых аккаунтов ─────
function GameAccountRow({ icon, name, sub, status, statusKind, ctaLabel, onCta, danger }) {
  return (
    <div className="settings-row" style={{ gap: 16 }}>
      {icon}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
          <span style={{ fontFamily: W.FONT_DISPLAY, fontSize: 15, color: W.CX.white, letterSpacing: '0.06em' }}>{name}</span>
          {sub && <span style={{ fontFamily: W.FONT_MONO, fontSize: 11, color: W.CX.textMute }}>{sub}</span>}
          {statusKind === 'attached' && <GreenChip>ПРИВЯЗАН</GreenChip>}
        </div>
        <div style={{ marginTop: 4, fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textSec, lineHeight: 1.4 }}>{status}</div>
      </div>
      <Btn variant={danger ? 'ghost' : (statusKind === 'attached' ? 'ghost' : 'primary')} size="sm"
        onClick={onCta}
        className={danger ? 'btn-danger' : ''}>
        {ctaLabel}
      </Btn>
    </div>
  );
}

// ───── MODALS ─────

function SteamAuthModal({ open, onClose, onSuccess }) {
  const [scopes, setScopes] = useState({ games: true, stats: true, public: false });
  return (
    <Modal open={open} onClose={onClose}
      title="Привязать Steam"
      subtitle="Авторизуйся через Steam OpenID, чтобы получать XP за матчи в CS2, Dota 2 и другие игры из библиотеки."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" onClick={onSuccess}>Войти через Steam</Btn>
      </>}>
      <button type="button" className="auth-btn steam" onClick={onSuccess}>
        <SteamIcon size={28}/>
        <span>Sign in through STEAM</span>
      </button>
      <div style={{ marginTop: 10, fontSize: 11, color: W.CX.textMute, fontFamily: W.FONT_BODY, lineHeight: 1.4 }}>
        В прототипе авторизация эмулируется. В продакшене ведёт на <span style={{ color: W.CX.textSec }}>steamcommunity.com/openid</span>
      </div>
      <div style={{ marginTop: 18, paddingTop: 14, borderTop: `1px solid ${W.CX.line}` }}>
        <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 10, letterSpacing: '0.2em', color: W.CX.textMute, marginBottom: 8 }}>РАЗРЕШЕНИЯ</div>
        <Checkbox checked={scopes.games}  onChange={v => setScopes(s => ({ ...s, games: v }))}>Разрешить чтение списка игр</Checkbox>
        <Checkbox checked={scopes.stats}  onChange={v => setScopes(s => ({ ...s, stats: v }))}>Разрешить чтение статистики матчей</Checkbox>
        <Checkbox checked={scopes.public} onChange={v => setScopes(s => ({ ...s, public: v }))}>Опубличить мой Steam-профиль в Battle Pass-лидерборде</Checkbox>
      </div>
    </Modal>
  );
}

function FaceitAuthModal({ open, onClose, onSuccess }) {
  return (
    <Modal open={open} onClose={onClose}
      title="Авторизация Faceit"
      subtitle="Подключи Faceit-аккаунт, чтобы получать +50 XP за матч в режимах Level 5+."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" onClick={onSuccess}>Привязать Faceit</Btn>
      </>}>
      <button type="button" className="auth-btn faceit" onClick={onSuccess}>
        <FaceitIcon size={28}/>
        <span>Connect with FACEIT</span>
      </button>
      <div style={{ marginTop: 10, fontSize: 11, color: W.CX.textMute, fontFamily: W.FONT_BODY, lineHeight: 1.4 }}>
        В прототипе авторизация эмулируется. В продакшене — OAuth flow на faceit.com.
      </div>
    </Modal>
  );
}

function DiscordAuthModal({ open, onClose, onSuccess }) {
  return (
    <Modal open={open} onClose={onClose}
      title="Привязать Discord"
      subtitle="Получай в DM уведомления о турнирах и сезонах. Опционально — синхронизация ника."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" onClick={onSuccess}>Подключить</Btn>
      </>}>
      <button type="button" className="auth-btn discord" onClick={onSuccess}>
        <DiscordIcon size={28}/>
        <span>Authorize with Discord</span>
      </button>
    </Modal>
  );
}

function ConfirmUnbindModal({ open, onClose, onConfirm, accountName }) {
  return (
    <Modal open={open} onClose={onClose}
      title={`Отвязать ${accountName}?`}
      subtitle="После отвязки XP за прошлые матчи сохранится, но новые матчи перестанут засчитываться."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="danger" onClick={onConfirm}>Отвязать</Btn>
      </>}>
      <div style={{ padding: 14, borderRadius: 8, background: 'rgba(239,68,68,0.08)',
        border: '1px solid rgba(239,68,68,0.2)', color: '#FCA5A5', fontSize: 12, fontFamily: W.FONT_BODY }}>
        Можно вернуть в любой момент — все настройки сохранятся.
      </div>
    </Modal>
  );
}

function EmailModal({ open, onClose, currentEmail, onSaved }) {
  const [newEmail, setNewEmail] = useState('');
  const [pwd, setPwd] = useState('');
  const [shake, setShake] = useState(false);
  const [errors, setErrors] = useState({});
  const submit = () => {
    const e = { newEmail: !newEmail.trim(), pwd: !pwd };
    setErrors(e);
    if (e.newEmail || e.pwd) {
      setShake(true); setTimeout(() => setShake(false), 450); return;
    }
    onSaved(newEmail);
  };
  useEffect(() => { if (open) { setNewEmail(''); setPwd(''); setErrors({}); } }, [open]);
  return (
    <Modal open={open} onClose={onClose}
      title="Изменить email"
      subtitle="Введи новый email — мы отправим письмо для подтверждения."
      shake={shake}
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" onClick={submit}>Сохранить</Btn>
      </>}>
      <Input label="Текущий email" value={currentEmail} readOnly mono/>
      <Input label="Новый email" value={newEmail} onChange={setNewEmail}
        placeholder="example@mail.com" error={errors.newEmail}
        helper={errors.newEmail ? 'Введи новый email' : null} autoFocus/>
      <Input label="Пароль для подтверждения" value={pwd} onChange={setPwd}
        type="password" error={errors.pwd}
        helper={errors.pwd ? 'Введи пароль' : null}/>
    </Modal>
  );
}

function PasswordModal({ open, onClose, onSaved }) {
  const [cur, setCur] = useState('');
  const [neu, setNeu] = useState('');
  const [rep, setRep] = useState('');
  const [shake, setShake] = useState(false);
  const [errors, setErrors] = useState({});

  const strength = (() => {
    if (neu.length === 0) return 0;
    if (neu.length < 6)   return 1;
    if (neu.length < 10)  return 2;
    return 3;
  })();

  const submit = () => {
    const e = { cur: !cur, neu: !neu, rep: rep !== neu };
    setErrors(e);
    if (e.cur || e.neu || e.rep) {
      setShake(true); setTimeout(() => setShake(false), 450); return;
    }
    onSaved();
  };
  useEffect(() => { if (open) { setCur(''); setNeu(''); setRep(''); setErrors({}); } }, [open]);

  return (
    <Modal open={open} onClose={onClose}
      title="Сменить пароль"
      subtitle="Минимум 6 символов. Рекомендуем 10+ с цифрами и спецсимволами."
      shake={shake}
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" onClick={submit}>Сменить пароль</Btn>
      </>}>
      <Input label="Текущий пароль" value={cur} onChange={setCur} type="password" error={errors.cur} helper={errors.cur ? 'Введи текущий пароль' : null} autoFocus/>
      <div>
        <Input label="Новый пароль" value={neu} onChange={setNeu} type="password" error={errors.neu} helper={errors.neu ? 'Введи новый пароль' : null}/>
        <div className="strength" style={{ marginTop: -8, marginBottom: 12 }}>
          <div className={'strength-seg ' + (strength >= 1 ? (strength === 1 ? 'weak' : strength === 2 ? 'medium' : 'strong') : '')}/>
          <div className={'strength-seg ' + (strength >= 2 ? (strength === 2 ? 'medium' : 'strong') : '')}/>
          <div className={'strength-seg ' + (strength >= 3 ? 'strong' : '')}/>
        </div>
      </div>
      <Input label="Повторить новый пароль" value={rep} onChange={setRep} type="password"
        error={errors.rep} helper={errors.rep ? 'Пароли не совпадают' : null}/>
    </Modal>
  );
}

function AvatarModal({ open, onClose, onSaved }) {
  const [selected, setSelected] = useState(null);
  const tiers = W.TIERS ? Object.values(W.TIERS) : [];
  // 12 cells — 8 tier badges + 4 цветных
  const cells = useMemo(() => {
    const out = [];
    tiers.slice(0, 8).forEach((t, i) => out.push({ kind: 'tier', tier: t, label: t.name }));
    ['#E63946', '#A855F7', '#22C55E', '#FFB627'].forEach((c, i) => out.push({ kind: 'color', color: c, label: 'COLOR ' + (i + 1) }));
    return out;
  }, []);
  useEffect(() => { if (open) setSelected(null); }, [open]);
  return (
    <Modal open={open} onClose={onClose}
      title="Выбрать аватар"
      subtitle="Перетащи своё изображение или выбери готовый аватар клуба."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Отмена</Btn>
        <Btn variant="primary" disabled={selected === null} onClick={onSaved}>Применить</Btn>
      </>}>
      <div className="dropzone" onClick={() => alert('Загрузка эмулируется')}>
        <svg width="38" height="28" viewBox="0 0 38 28" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M9 18 Q3 18 3 12 Q3 8 8 7 Q8 2 14 2 Q19 2 21 6 Q26 6 27 11 Q33 11 33 17 Q33 22 26 22 L12 22 Q9 22 9 19 Z"/>
          <path d="M19 12 L19 22 M15 16 L19 12 L23 16"/>
        </svg>
        <div>Перетащи изображение или нажми</div>
        <div style={{ fontSize: 11, color: W.CX.textMute }}>PNG/JPG до 2МБ • 256×256+</div>
      </div>
      <div className="avatar-grid">
        {cells.map((c, i) => {
          const isSel = i === selected;
          return (
            <div key={i} className={'avatar-cell' + (isSel ? ' selected' : '')} onClick={() => setSelected(i)}>
              {c.kind === 'tier' ? <W.TierBadge tier={Object.keys(W.TIERS).find(k => W.TIERS[k] === c.tier) || 'recruit'} size={48} label={false}/>
                : <div style={{ width: 38, height: 38, borderRadius: '50%', background: c.color, boxShadow: `0 0 14px ${c.color}88` }}/>}
            </div>
          );
        })}
      </div>
    </Modal>
  );
}

function PremiumModal({ open, onClose, onSuccess }) {
  return (
    <Modal open={open} onClose={onClose}
      title="Premium Battle Pass"
      subtitle="+50% XP к каждому заданию, эксклюзивные награды на 30 уровнях, главный приз — ДР под ключ."
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Позже</Btn>
        <Btn variant="secondary" onClick={onSuccess}>Активировать — 1 490 ₽</Btn>
      </>}>
      <div style={{ padding: 18, borderRadius: 10, background: `linear-gradient(160deg, ${W.CX.premiumGold}22, ${W.CX.card})`,
        border: `1.5px solid ${W.CX.premiumGold}77`, boxShadow: `0 0 20px ${W.CX.premiumGold}33`, textAlign: 'center' }}>
        <W.PremiumStar size={56}/>
        <div style={{ marginTop: 10, fontFamily: W.FONT_DISPLAY, fontSize: 24, color: W.CX.premiumGold, letterSpacing: '0.06em' }}>1 490 ₽</div>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textMute }}>за полный сезон • 90 дней</div>
      </div>
      <div style={{ marginTop: 16, display: 'flex', flexDirection: 'column', gap: 8, fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec }}>
        {['⚡ +50% XP к каждому заданию',
          '⭐ Эксклюзивные награды на всех 30 уровнях',
          '👑 Premium-рамка аватара и значок',
          '🏆 Приоритет в очередях на турниры',
          '🎂 30 уровень: ДР под ключ в клубе на компанию до 8 чел.'].map(t => (
          <div key={t}>{t}</div>
        ))}
      </div>
    </Modal>
  );
}

// ───── DesktopCenterSettings ─────

function DesktopCenterSettings({ premium, totalXP, onAddXP, onPremiumActivate, onNickChange, showToast }) {
  // Game accounts attachment state
  const [accounts, setAccounts] = useState({
    steam:    { attached: true,  meta: '76561198812345678', since: '14.03.2024' },
    faceit:   { attached: false, meta: null,                since: null },
    discord:  { attached: false, meta: null,                since: null },
    telegram: { attached: true,  meta: '@tenz_ru',          since: '04.04.2024' },
  });

  // Modals state
  const [modal, setModal] = useState(null);   // {kind, ...payload}
  const [confirmUnbind, setConfirmUnbind] = useState(null);

  // Notifications state
  const [notif, setNotif] = useState({
    tasks: true, levelUp: true, expiring: true, seasonAnnounce: true,
    tournaments: false, referral: true, marketing: false,
  });

  // 2FA toggle
  const [tfa, setTfa] = useState(true);

  const openModal = (kind, payload = {}) => setModal({ kind, ...payload });
  const closeModal = () => setModal(null);

  // Handlers
  const attachAccount = (id, meta) => {
    setAccounts(a => ({ ...a, [id]: { attached: true, meta, since: '15.05.2026' } }));
  };
  const detachAccount = (id) => {
    setAccounts(a => ({ ...a, [id]: { attached: false, meta: null, since: null } }));
  };

  return (
    <div className="section-enter" style={{ position: 'relative' }}>
      <div className="stagger-item" style={{ animationDelay: '0ms' }}>
        <W.Display size={20} color={W.CX.white} tracking={0.16}>НАСТРОЙКИ</W.Display>
        <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textMute, marginTop: 4 }}>
          Профиль, привязки, безопасность и оповещения
        </div>
      </div>

      {/* ── PROFILE ── */}
      <SettingsCard delay={40}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
          <div onClick={() => openModal('avatar')} style={{ position: 'relative', cursor: 'pointer', flexShrink: 0 }}
               onMouseEnter={e => { const ov = e.currentTarget.querySelector('.av-overlay'); if (ov) ov.style.opacity = '1'; }}
               onMouseLeave={e => { const ov = e.currentTarget.querySelector('.av-overlay'); if (ov) ov.style.opacity = '0'; }}>
            <W.Avatar size={96} tier={W.TIERS.knight} initials="TZ"/>
            <div className="av-overlay" style={{
              position: 'absolute', inset: 0, borderRadius: '50%',
              background: 'rgba(0,0,0,0.6)', display: 'flex', alignItems: 'center', justifyContent: 'center',
              opacity: 0, transition: 'opacity .2s', pointerEvents: 'none',
              fontSize: 11, color: '#fff', fontFamily: W.FONT_BODY, textAlign: 'center', padding: 8, lineHeight: 1.3,
            }}>📷<br/>Изменить</div>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
              <span style={{ fontFamily: W.FONT_DISPLAY, fontSize: 22, color: W.CX.white, letterSpacing: '0.06em' }}>TENZ_RU</span>
              {premium && <W.PremiumStar size={14}/>}
            </div>
            <div style={{ marginTop: 2, fontFamily: W.FONT_DISPLAY, fontSize: 11, color: W.CX.silverHi, letterSpacing: '0.2em' }}>KNIGHT • УРОВЕНЬ 15</div>
            <div style={{ marginTop: 8, maxWidth: 280 }}>
              <W.XPBar value={totalXP} max={5000} color={W.CX.amber} height={4}/>
              <div style={{ marginTop: 4, fontFamily: W.FONT_MONO, fontSize: 11, color: W.CX.textMute }}>
                {totalXP} / 5 000 XP до УР. 16
              </div>
            </div>
            <div style={{ marginTop: 6, fontFamily: W.FONT_BODY, fontSize: 11, color: W.CX.textMute }}>С нами с 12.04.2024</div>
          </div>
          <Btn variant="ghost" onClick={onNickChange}>Изменить ник</Btn>
        </div>
      </SettingsCard>

      {/* ── GAME ACCOUNTS ── */}
      <SettingsCard title="ИГРОВЫЕ АККАУНТЫ" delay={80}>
        <GameAccountRow icon={<SteamIcon size={44}/>}
          name="Steam" sub={accounts.steam.attached ? accounts.steam.meta : null}
          statusKind={accounts.steam.attached ? 'attached' : 'detached'}
          status={accounts.steam.attached ? `Привязан ${accounts.steam.since}. +50 XP за матч CS2/Dota` : 'Не привязан. Получай +50 XP за матчи'}
          ctaLabel={accounts.steam.attached ? 'Отвязать' : 'Привязать'}
          danger={accounts.steam.attached}
          onCta={() => accounts.steam.attached ? setConfirmUnbind('steam') : openModal('steam')}/>

        <GameAccountRow icon={<FaceitIcon size={44}/>}
          name="Faceit" sub={accounts.faceit.attached ? accounts.faceit.meta : null}
          statusKind={accounts.faceit.attached ? 'attached' : 'detached'}
          status={accounts.faceit.attached ? `Привязан ${accounts.faceit.since}. +50 XP за матчи Level 5+` : 'Не привязан. Получай +50 XP за матчи Level 5+'}
          ctaLabel={accounts.faceit.attached ? 'Отвязать' : 'Привязать'}
          danger={accounts.faceit.attached}
          onCta={() => accounts.faceit.attached ? setConfirmUnbind('faceit') : openModal('faceit')}/>

        <GameAccountRow icon={<DiscordIcon size={44}/>}
          name="Discord" sub={accounts.discord.attached ? accounts.discord.meta : null}
          statusKind={accounts.discord.attached ? 'attached' : 'detached'}
          status={accounts.discord.attached ? `Привязан ${accounts.discord.since}` : 'Получай уведомления о турнирах и сезонах в DM'}
          ctaLabel={accounts.discord.attached ? 'Отвязать' : 'Привязать'}
          danger={accounts.discord.attached}
          onCta={() => accounts.discord.attached ? setConfirmUnbind('discord') : openModal('discord')}/>

        <GameAccountRow icon={<TgIcon size={44}/>}
          name="Telegram" sub={accounts.telegram.attached ? accounts.telegram.meta : null}
          statusKind={accounts.telegram.attached ? 'attached' : 'detached'}
          status={accounts.telegram.attached ? `Привязан ${accounts.telegram.since}` : 'Не привязан'}
          ctaLabel={accounts.telegram.attached ? 'Отвязать' : 'Привязать'}
          danger={accounts.telegram.attached}
          onCta={() => accounts.telegram.attached ? setConfirmUnbind('telegram') : showToast('Перейди в @cyberx_smm_bot и нажми /start')}/>
      </SettingsCard>

      {/* ── ACCOUNT & SECURITY ── */}
      <SettingsCard title="АККАУНТ И БЕЗОПАСНОСТЬ" delay={120}>
        <div className="settings-row">
          <div style={{ flex: '0 0 130px', fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec }}>Email</div>
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontFamily: W.FONT_MONO, fontSize: 13, color: W.CX.white }}>tenz.ru@gmail.com</span>
            <GreenChip>ПОДТВЕРЖДЁН</GreenChip>
          </div>
          <Btn variant="ghost" size="sm" onClick={() => openModal('email')}>Изменить</Btn>
        </div>
        <div className="settings-row">
          <div style={{ flex: '0 0 130px', fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec }}>Пароль</div>
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontFamily: W.FONT_MONO, fontSize: 13, color: W.CX.white, letterSpacing: '0.15em' }}>•••••••••••</span>
            <NeutralChip>сменён 14 дней назад</NeutralChip>
          </div>
          <Btn variant="ghost" size="sm" onClick={() => openModal('password')}>Сменить пароль</Btn>
        </div>
        <div className="settings-row">
          <div style={{ flex: '0 0 130px', fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec }}>2FA</div>
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.white }}>Telegram-бот</span>
            {tfa ? <GreenChip>ВКЛЮЧЕНА</GreenChip> : <NeutralChip>выкл</NeutralChip>}
          </div>
          <Toggle on={tfa} onChange={setTfa} ariaLabel="2FA"/>
        </div>
        <div className="settings-row">
          <div style={{ flex: '0 0 130px', fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.textSec }}>Активные устройства</div>
          <div style={{ flex: 1, fontFamily: W.FONT_MONO, fontSize: 13, color: W.CX.white }}>3 устройства</div>
          <Btn variant="ghost" size="sm" onClick={() => showToast('Открыто управление сессиями')}>Управление сессиями</Btn>
        </div>
      </SettingsCard>

      {/* ── NOTIFICATIONS ── */}
      <SettingsCard title="ОПОВЕЩЕНИЯ" delay={160}>
        {[
          { k: 'tasks',          l: 'Новые задания сезона' },
          { k: 'levelUp',        l: 'Уровень разблокирован' },
          { k: 'expiring',       l: 'Скоро истекают задания (за 24ч)' },
          { k: 'seasonAnnounce', l: 'Анонсы новых сезонов' },
          { k: 'tournaments',    l: 'Турниры клуба' },
          { k: 'referral',       l: 'Реферал пришёл в клуб' },
          { k: 'marketing',      l: 'Маркетинг и акции' },
        ].map(n => (
          <div key={n.k} className="settings-row">
            <div style={{ flex: 1, fontFamily: W.FONT_BODY, fontSize: 13, color: W.CX.white }}>{n.l}</div>
            <Toggle on={notif[n.k]} onChange={v => setNotif(p => ({ ...p, [n.k]: v }))} ariaLabel={n.l}/>
          </div>
        ))}
      </SettingsCard>

      {/* ── PREMIUM ── */}
      <SettingsCard title="ПОДПИСКА" delay={200}>
        {!premium ? (
          <div style={{
            padding: 18, borderRadius: 12,
            background: `linear-gradient(160deg, ${W.CX.premiumGold}22, ${W.CX.card})`,
            border: `1.5px solid ${W.CX.premiumGold}77`, boxShadow: `0 0 24px ${W.CX.premiumGold}22`,
            display: 'flex', alignItems: 'center', gap: 20, position: 'relative', overflow: 'hidden',
          }}>
            <W.PremiumStar size={48}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 18, color: W.CX.premiumGold, letterSpacing: '0.08em' }}>PREMIUM PASS НЕ АКТИВЕН</div>
              <div style={{ fontFamily: W.FONT_BODY, fontSize: 12, color: W.CX.textSec, marginTop: 4, lineHeight: 1.4 }}>
                +50% XP, эксклюзивные награды и ДР под ключ на 30 уровне.
              </div>
            </div>
            <Btn variant="secondary" className="shimmer" onClick={() => openModal('premium')}>АКТИВИРОВАТЬ — 1 490 ₽</Btn>
          </div>
        ) : (
          <div style={{ padding: 18, borderRadius: 12, background: `${W.CX.premiumGold}11`, border: `1px solid ${W.CX.premiumGold}55`, display: 'flex', alignItems: 'center', gap: 14 }}>
            <W.PremiumStar size={36}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 16, color: W.CX.premiumGold, letterSpacing: '0.08em' }}>PREMIUM PASS АКТИВЕН</div>
              <div style={{ fontFamily: W.FONT_BODY, fontSize: 11.5, color: W.CX.textSec, marginTop: 2 }}>Действует до 12.08.2026 • +50% XP включён</div>
            </div>
            <GreenChip>АКТИВЕН</GreenChip>
          </div>
        )}
      </SettingsCard>

      {/* ── DANGER ── */}
      <SettingsCard delay={240}>
        <div style={{ fontFamily: W.FONT_DISPLAY, fontSize: 12, letterSpacing: '0.24em', color: '#EF4444', marginBottom: 14 }}>ОПАСНАЯ ЗОНА</div>
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
          <Btn variant="ghost" onClick={() => showToast('Сессия завершена — заходи снова')}>Выйти из аккаунта</Btn>
          <Btn variant="danger" onClick={() => showToast('Удаление через 30 дней — напишите в поддержку клуба')}>Удалить аккаунт</Btn>
        </div>
      </SettingsCard>

      {/* ── MODALS ── */}
      <SteamAuthModal open={modal?.kind === 'steam'} onClose={closeModal}
        onSuccess={() => { attachAccount('steam', '76561198812345678'); onAddXP(200); showToast('Steam привязан 🎮 +200 XP'); closeModal(); }}/>
      <FaceitAuthModal open={modal?.kind === 'faceit'} onClose={closeModal}
        onSuccess={() => { attachAccount('faceit', 'TENZ_RU'); onAddXP(150); showToast('Faceit привязан 🔶 +150 XP'); closeModal(); }}/>
      <DiscordAuthModal open={modal?.kind === 'discord'} onClose={closeModal}
        onSuccess={() => { attachAccount('discord', 'tenz_ru#0001'); showToast('Discord привязан 💬'); closeModal(); }}/>
      <ConfirmUnbindModal open={!!confirmUnbind}
        onClose={() => setConfirmUnbind(null)}
        onConfirm={() => { detachAccount(confirmUnbind); showToast(`${confirmUnbind} отвязан`); setConfirmUnbind(null); }}
        accountName={confirmUnbind ? confirmUnbind[0].toUpperCase() + confirmUnbind.slice(1) : ''}/>
      <EmailModal open={modal?.kind === 'email'} onClose={closeModal}
        currentEmail="tenz.ru@gmail.com"
        onSaved={(newEmail) => { showToast(`Письмо отправлено на ${newEmail}`); closeModal(); }}/>
      <PasswordModal open={modal?.kind === 'password'} onClose={closeModal}
        onSaved={() => { showToast('Пароль изменён 🔒'); closeModal(); }}/>
      <AvatarModal open={modal?.kind === 'avatar'} onClose={closeModal}
        onSaved={() => { showToast('Аватар обновлён ✨'); closeModal(); }}/>
      <PremiumModal open={modal?.kind === 'premium'} onClose={closeModal}
        onSuccess={() => { onPremiumActivate(); showToast('Premium активирован ⭐'); closeModal(); }}/>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// DESKTOP APP
// ────────────────────────────────────────────────────────────

function DesktopApp({ initialSection = 'pass', showToast }) {
  const [section, setSection] = useState(initialSection);
  const [totalXP, setTotalXP] = useState(3500);
  const [premium, setPremium] = useState(false);
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [isMobile, setIsMobile] = useState(() =>
    typeof window !== 'undefined' && window.innerWidth < 1024);

  useEffect(() => {
    const onResize = () => setIsMobile(window.innerWidth < 1024);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  useEffect(() => { setSection(initialSection); }, [initialSection]);

  const handleSelectSection = (s) => {
    setSection(s);
    setMobileMenuOpen(false);
  };

  const center = (() => {
    if (section === 'pass')     return <DesktopCenterPass key="pass"/>;
    if (section === 'tasks')    return <DesktopCenterTasks key="tasks"/>;
    if (section === 'top')      return <DesktopCenterTop key="top"/>;
    if (section === 'shop')     return <DesktopCenterShop key="shop"/>;
    if (section === 'club')     return <DesktopCenterClub key="club"/>;
    if (section === 'settings') return <DesktopCenterSettings key="settings"
      premium={premium} totalXP={totalXP}
      onAddXP={(d) => setTotalXP(x => x + d)}
      onPremiumActivate={() => setPremium(true)}
      onNickChange={() => showToast('Смена ника доступна 1 раз в 30 дней')}
      showToast={showToast}/>;
    return null;
  })();

  return (
    <div className="fullscreen-app">
      <div className="cx-grid-bg"/>
      <div className="orbs-host fullscreen-orbs">
        <div className="orb orb-red"/>
        <div className="orb orb-purple"/>
      </div>

      {isMobile && (
        <button type="button" className="mobile-menu-btn"
                onClick={() => setMobileMenuOpen(true)} aria-label="Меню">
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round">
            <path d="M3 6h18M3 12h18M3 18h18"/>
          </svg>
        </button>
      )}

      {isMobile && mobileMenuOpen && (
        <div className="drawer-overlay" onClick={() => setMobileMenuOpen(false)}/>
      )}

      <aside className={'app-sidebar' + (isMobile ? ' mobile' : '') + (mobileMenuOpen ? ' open' : '')}>
        <DesktopSidebar section={section} setSection={handleSelectSection} totalXP={totalXP}/>
        {isMobile && (
          <button type="button" className="drawer-close"
                  onClick={() => setMobileMenuOpen(false)} aria-label="Закрыть">✕</button>
        )}
      </aside>

      <main className="app-center">
        <div className="app-center-inner">
          {center}
        </div>
      </main>

      {!isMobile && (
        <aside className="app-right">
          <DesktopRight onPremium={() => setSection('settings')}/>
        </aside>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// ROOT
// ────────────────────────────────────────────────────────────

function RootApp() {
  const [ready, setReady] = useState(false);
  const [desktopInitialSection, setDesktopInitialSection] = useState('pass');
  const [toast, setToast] = useState(null);

  const showToast = useCallback((msg) => {
    setToast(msg);
    setTimeout(() => setToast(null), 2800);
  }, []);

  useEffect(() => {
    let cancelled = false;
    const tryReady = () => {
      const need = ['MainScreen', 'TasksScreen', 'PremiumPurchaseScreen', 'LeaderboardScreen',
                    'RewardDetailScreen', 'UnlockScreen', 'PhoneFrame', 'CXBackground', 'CXHeader',
                    'ProfileCard', 'SeasonProgress', 'CTAButton', 'LevelColumn', 'TaskCard',
                    'CX', 'FONT_DISPLAY', 'FONT_BODY', 'FONT_MONO', 'Display', 'PremiumStar',
                    'SAMPLE_REWARDS', 'SAMPLE_TASKS',
                    'WebFrame', 'WebDashboard', 'WebRewardTrack',
                    'Avatar', 'XPBar', 'CXMark', 'TierBadge', 'MonoNum', 'TIERS', 'tierFor'];
      const missing = need.filter(k => !W[k]);
      if (missing.length === 0) { if (!cancelled) setReady(true); }
      else { setTimeout(tryReady, 100); }
    };
    tryReady();
    return () => { cancelled = true; };
  }, []);

  if (!ready) {
    return (
      <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#B8B8C0' }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontSize: 44, color: '#E63946', fontWeight: 900, letterSpacing: '-0.02em' }}>CYBERX</div>
          <div style={{ marginTop: 8, fontFamily: 'Inter,sans-serif' }}>Загрузка…</div>
          <div style={{ marginTop: 14, fontSize: 11, color: '#6C757D' }}>Babel компилирует JSX</div>
        </div>
      </div>
    );
  }

  return (
    <>
      <div className="topbar">
        <div className="topbar-left">
          <span className="logo">CYBERX</span>
          <span className="badge">Battle Pass · Season 1</span>
        </div>
        <div className="topbar-right">
          <a href="/design/" className="design-link">Дизайн-холст →</a>
        </div>
      </div>

      <DesktopApp initialSection={desktopInitialSection} showToast={showToast}/>

      {toast && (
        <div style={{
          position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)',
          background: 'linear-gradient(135deg,#22C55E,#16A34A)', color: '#fff',
          padding: '14px 22px', borderRadius: 12, fontSize: 14, fontWeight: 600,
          fontFamily: 'Inter,sans-serif', letterSpacing: '0.02em', whiteSpace: 'nowrap',
          boxShadow: '0 10px 32px rgba(0,0,0,0.5)', zIndex: 3000, pointerEvents: 'none',
        }}>✓ {toast}</div>
      )}
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<RootApp/>);
