// FURY · Direction C — Cinematic Post-Apoc
// Editorial serif headlines + warm cream highlights on deep warm-black,
// oxblood accent, atmospheric photo placeholders, generous breathing
// room. Magazine-style. 1440×900.

(function () {
  const { useShop, furyFmt, furyTone, FuryGlyph } = window;

  const C = {
    bg: '#0d0a08',
    panel: '#181410',
    panel2: '#221c16',
    line: '#3a2e24',
    lineSoft: '#2a221b',
    text: '#cfc2ad',
    hi: '#e8dccb',
    paper: '#e8dccb',
    dim: '#7a6e5f',
    blood: '#a82828',
    bloodHi: '#c93838',
    bloodDeep: '#5a1414',
    ember: '#d97a2a',
  };
  const F = {
    serif: '"Spectral", "Cormorant Garamond", Georgia, serif',
    sans: '"Inter", "Manrope", system-ui, sans-serif',
    mono: '"IBM Plex Mono", "Courier New", monospace',
  };

  function Display({ s = 38, italic, c, w = 500, children, style }) {
    return (
      <span style={{
        fontFamily: F.serif, fontSize: s, fontWeight: w,
        fontStyle: italic ? 'italic' : 'normal',
        color: c || C.hi, letterSpacing: '-0.01em', lineHeight: 1.1, ...style,
      }}>{children}</span>
    );
  }
  function Sans({ s = 12, w = 400, c, upper, tracked, children, style }) {
    return (
      <span style={{
        fontFamily: F.sans, fontSize: s, fontWeight: w,
        color: c || C.text, letterSpacing: tracked ? '0.16em' : 'normal',
        textTransform: upper ? 'uppercase' : 'none', ...style,
      }}>{children}</span>
    );
  }
  function Mono({ s = 10, c, children, style }) {
    return (
      <span style={{
        fontFamily: F.mono, fontSize: s, color: c || C.dim, letterSpacing: '0.05em', ...style,
      }}>{children}</span>
    );
  }

  // Модал пополнения баланса. Вызывает /api/payments/create через FURY_API.pay
  // и редиректит игрока на чекаут FreeKassa или ЮKassa. Никаких локальных списаний —
  // деньги начисляются только когда придёт webhook от провайдера.
  function TopUpModal({ lang, onClose, loggedIn }) {
    const [amount, setAmount]   = React.useState(500);
    const [provider, setProv]   = React.useState('freekassa');
    const [busy, setBusy]       = React.useState(false);
    const [err, setErr]         = React.useState(null);
    const presets = [100, 250, 500, 1000, 2500, 5000];
    const tt = lang === 'ru'
      ? { title: 'Пополнение баланса', amount: 'Сумма', provider: 'Платёжная система',
          rub: '₽', pay: 'Перейти к оплате', cancel: 'Отмена',
          login: 'Сначала войдите через Steam',
          info: 'Оплата идёт через провайдера, баланс зачислится автоматически после успешной оплаты.' }
      : { title: 'Top up balance', amount: 'Amount', provider: 'Payment method',
          rub: '₽', pay: 'Proceed to checkout', cancel: 'Cancel',
          login: 'Please log in with Steam first',
          info: 'Payment goes through the provider; the balance is credited automatically once payment succeeds.' };

    async function submit() {
      if (!loggedIn) { setErr(tt.login); return; }
      const a = Math.max(1, Math.floor(Number(amount) || 0));
      if (!a) { setErr('bad_amount'); return; }
      setBusy(true); setErr(null);
      try {
        await window.FURY_API.pay(a, provider); // на успехе делает location.href = url
      } catch (e) {
        setBusy(false);
        setErr(e?.data?.error || e.message || 'pay_failed');
      }
    }

    return (
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(13,10,8,0.78)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <div onClick={(e) => e.stopPropagation()} style={{
          background: C.bg, border: `1px solid ${C.line}`, width: 460, padding: 28,
          boxShadow: '0 30px 80px rgba(0,0,0,0.6)',
        }}>
          <Display s={22} w={500}>{tt.title}</Display>
          <div style={{ marginTop: 20 }}>
            <Sans s={9} c={C.dim} upper tracked>{tt.amount}</Sans>
            <div style={{ marginTop: 6, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {presets.map((p) => (
                <button key={p} onClick={() => setAmount(p)} style={{
                  background: amount === p ? C.ember : 'transparent',
                  color: amount === p ? C.bg : C.hi,
                  border: `1px solid ${amount === p ? C.ember : C.line}`,
                  padding: '6px 12px', cursor: 'pointer',
                  fontFamily: F.sans, fontSize: 11, letterSpacing: '0.16em',
                }}>{p}</button>
              ))}
            </div>
            <div style={{ marginTop: 10 }}>
              <input
                type="number" min="1" max="100000" value={amount}
                onChange={(e) => setAmount(e.target.value)}
                style={{
                  width: '100%', background: 'transparent', border: `1px solid ${C.line}`,
                  color: C.hi, padding: '10px 12px', fontFamily: F.serif, fontSize: 18,
                }} />
            </div>
          </div>

          <div style={{ marginTop: 18 }}>
            <Sans s={9} c={C.dim} upper tracked>{tt.provider}</Sans>
            <div style={{ marginTop: 8, display: 'flex', gap: 8 }}>
              {[
                ['freekassa', 'FreeKassa'],
                ['yookassa',  'ЮKassa'],
              ].map(([k, label]) => (
                <button key={k} onClick={() => setProv(k)} style={{
                  flex: 1, background: provider === k ? C.paper : 'transparent',
                  color: provider === k ? C.bg : C.hi,
                  border: `1px solid ${provider === k ? C.paper : C.line}`,
                  padding: '10px 14px', cursor: 'pointer',
                  fontFamily: F.sans, fontSize: 11, letterSpacing: '0.18em',
                  textTransform: 'uppercase', fontWeight: 600,
                }}>{label}</button>
              ))}
            </div>
          </div>

          <div style={{ marginTop: 16 }}>
            <Sans s={10} c={C.dim}>{tt.info}</Sans>
          </div>

          {err && (
            <div style={{ marginTop: 14, padding: '8px 12px', background: 'rgba(150,30,30,0.18)', border: `1px solid ${C.blood}` }}>
              <Sans s={11} c={C.paper}>{err}</Sans>
            </div>
          )}

          <div style={{ marginTop: 22, display: 'flex', gap: 10 }}>
            <Btn kind="ghost" onClick={onClose} disabled={busy}>{tt.cancel}</Btn>
            <div style={{ flex: 1 }} />
            <Btn kind="blood" onClick={submit} disabled={busy}>{busy ? '…' : tt.pay}</Btn>
          </div>
        </div>
      </div>
    );
  }

  // ── Настройки сайта (футер + политики + лого/фавикон). Кешим в window.
  // Любая смена настроек прокатывается через событие 'fury:site-settings'.
  function useSiteSettings() {
    const [s, setS] = React.useState(window.__FURY_SITE_SETTINGS || null);
    React.useEffect(() => {
      let alive = true;
      function load() {
        fetch('/api/site-settings', { credentials: 'include' })
          .then((r) => r.json())
          .then((d) => {
            if (!alive) return;
            window.__FURY_SITE_SETTINGS = d.settings;
            applyFavicon(d.settings.favicon_url);
            setS(d.settings);
          })
          .catch(() => {});
      }
      if (!s) load();
      function onChange() { load(); }
      window.addEventListener('fury:site-settings', onChange);
      return () => { alive = false; window.removeEventListener('fury:site-settings', onChange); };
    }, []);
    return s;
  }

  // Динамически вставляет/обновляет <link rel="icon"> в <head>.
  function applyFavicon(url) {
    let link = document.querySelector('link[rel~="icon"]');
    if (!url) {
      if (link) link.remove();
      return;
    }
    if (!link) {
      link = document.createElement('link');
      link.rel = 'icon';
      document.head.appendChild(link);
    }
    link.href = url + (url.includes('?') ? '&' : '?') + 'v=' + Date.now();  // bust cache
  }

  // ── Подвал сайта с Discord/политиками/модом + просмотром политик в модале.
  function SiteFooter({ lang }) {
    const settings = useSiteSettings();
    const [policy, setPolicy] = React.useState(null);  // { title, text }
    const ru = lang === 'ru';
    if (!settings) return null;
    const labels = ru ? {
      terms:    'Пользовательское соглашение',
      privacy:  'Политика конфиденциальности',
      security: 'Политика инф. безопасности',
      discord:  'Discord',
      mod:      'Мод в Steam',
    } : {
      terms:    'Terms of Use',
      privacy:  'Privacy Policy',
      security: 'Information Security Policy',
      discord:  'Discord',
      mod:      'Steam Workshop',
    };
    const link = (label, href) => (
      <a href={href} target="_blank" rel="noopener noreferrer" style={{
        color: C.dim, textDecoration: 'none', fontFamily: F.sans, fontSize: 11,
        letterSpacing: '0.18em', textTransform: 'uppercase',
      }}>{label}</a>
    );
    const policyBtn = (label, key, title) => (
      <button onClick={() => setPolicy({ title, text: settings[key] || '' })} style={{
        background: 'transparent', border: 'none', cursor: 'pointer', color: C.dim,
        fontFamily: F.sans, fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', padding: 0,
      }}>{label}</button>
    );
    return (
      <>
        <footer style={{
          padding: '32px 48px', borderTop: `1px solid ${C.lineSoft}`,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 20, flexWrap: 'wrap',
        }}>
          <Sans s={10} c={C.dim} upper tracked>FURY · DayZ · {new Date().getFullYear()}</Sans>
          <div style={{ display: 'flex', gap: 20, flexWrap: 'wrap', alignItems: 'center' }}>
            {policyBtn(labels.terms,    'policy_terms',    labels.terms)}
            {policyBtn(labels.privacy,  'policy_privacy',  labels.privacy)}
            {policyBtn(labels.security, 'policy_security', labels.security)}
            {settings.discord_url && link(labels.discord, settings.discord_url)}
            {settings.mod_url     && link(labels.mod,     settings.mod_url)}
          </div>
        </footer>
        {policy && <PolicyModal lang={lang} title={policy.title} text={policy.text} onClose={() => setPolicy(null)} />}
      </>
    );
  }

  function PolicyModal({ lang, title, text, onClose }) {
    return (
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 1100, background: 'rgba(13,10,8,0.82)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <div onClick={(e) => e.stopPropagation()} style={{
          background: C.bg, border: `1px solid ${C.line}`,
          width: 'min(720px, 92vw)', maxHeight: '82vh', display: 'flex', flexDirection: 'column',
        }}>
          <div style={{ padding: '20px 26px', borderBottom: `1px solid ${C.line}`, display: 'flex', alignItems: 'center' }}>
            <Display s={22} italic w={500}>{title}</Display>
            <div style={{ flex: 1 }} />
            <button onClick={onClose} style={{
              background: 'transparent', border: 'none', cursor: 'pointer', color: C.dim,
              fontSize: 20, padding: '0 6px',
            }}>×</button>
          </div>
          <div style={{ padding: '20px 26px', overflow: 'auto', whiteSpace: 'pre-wrap' }}>
            <Sans s={13} c={C.text} style={{ lineHeight: 1.65 }}>{text || (lang === 'ru' ? '(пусто)' : '(empty)')}</Sans>
          </div>
        </div>
      </div>
    );
  }

  // ── Маленький REST-помощник для админ-API. credentials:'include' — куки сессии. ─
  async function api(path, opts = {}) {
    const base = (window.FURY_API && window.FURY_API.base) || '';
    const r = await fetch(base + path, {
      credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      ...opts,
    });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) throw Object.assign(new Error(data.error || `${path} → ${r.status}`), { status: r.status, data });
    return data;
  }

  // ── Бонусный код: ввод в профиле, шлёт POST /api/me/bonus-codes/redeem
  function BonusCodeRedeem({ lang }) {
    const [code, setCode] = React.useState('');
    const [busy, setBusy] = React.useState(false);
    const [msg, setMsg]   = React.useState(null);
    const ru = lang === 'ru';

    async function submit() {
      if (!code.trim()) return;
      setBusy(true); setMsg(null);
      try {
        const r = await api('/api/me/bonus-codes/redeem', {
          method: 'POST',
          body: JSON.stringify({ code: code.trim().toUpperCase() }),
        });
        setMsg({ kind: 'ok', text: ru
          ? `Начислено ${r.amount} ₽ · баланс ${r.balance} ₽`
          : `Credited ${r.amount} ₽ · balance ${r.balance} ₽` });
        setCode('');
        if (window.FURY_API && window.FURY_API.refreshMe) window.FURY_API.refreshMe();
      } catch (e) {
        const errMap = ru ? {
          not_found: 'Код не найден',
          revoked: 'Код отозван владельцем',
          expired: 'Срок действия истёк',
          exhausted: 'Лимит использований исчерпан',
          already_redeemed: 'Этот код уже активирован',
        } : {
          not_found: 'Code not found',
          revoked: 'Code revoked by owner',
          expired: 'Code expired',
          exhausted: 'Usage limit exhausted',
          already_redeemed: 'You have already used this code',
        };
        setMsg({ kind: 'err', text: errMap[e.data?.error] || e.message });
      } finally { setBusy(false); }
    }

    return (
      <div style={{ marginTop: 32, padding: 22, background: C.panel2, border: `1px solid ${C.line}` }}>
        <Mono c={C.ember}>· {ru ? 'БОНУСНЫЙ КОД' : 'BONUS CODE'}</Mono>
        <div style={{ marginTop: 8 }}>
          <Sans s={11} c={C.dim}>{ru
            ? 'Введите код, выданный администратором FURY. Каждый код действует один раз на аккаунт и не более 24 часов.'
            : 'Enter a code issued by a FURY admin. Each code is one-time per account, valid up to 24 hours.'}</Sans>
        </div>
        <div style={{ marginTop: 14, display: 'flex', gap: 10 }}>
          <input
            value={code}
            onChange={(e) => setCode(e.target.value.toUpperCase())}
            onKeyDown={(e) => { if (e.key === 'Enter') submit(); }}
            placeholder="XXXX-XXXX-XXXX"
            style={{
              flex: 1, background: 'transparent', border: `1px solid ${C.line}`,
              color: C.hi, padding: '10px 14px',
              fontFamily: F.mono, fontSize: 14, letterSpacing: '0.18em', textTransform: 'uppercase',
            }} />
          <Btn kind="blood" onClick={submit} disabled={busy || !code.trim()}>
            {busy ? '…' : (ru ? 'Активировать' : 'Redeem')}
          </Btn>
        </div>
        {msg && (
          <div style={{
            marginTop: 12, padding: '8px 12px',
            background: msg.kind === 'ok' ? 'rgba(60,140,60,0.15)' : 'rgba(150,30,30,0.18)',
            border: `1px solid ${msg.kind === 'ok' ? '#3c8c3c' : C.blood}`,
          }}>
            <Sans s={11} c={C.paper}>{msg.text}</Sans>
          </div>
        )}
      </div>
    );
  }

  // ── Админ-экран: три вкладки. «Админы» и «Бонус-коды» видны только owner. ─
  function AdminScreen({ shop }) {
    const { profile, lang } = shop;
    const role = profile && profile.role;
    const ru = lang === 'ru';

    const [tab, setTab] = React.useState('products');
    const tabs = [['products', ru ? 'Товары' : 'Products']];
    if (role === 'owner') {
      tabs.push(['admins',  ru ? 'Администраторы' : 'Admins']);
      tabs.push(['codes',   ru ? 'Бонус-коды'    : 'Bonus codes']);
      tabs.push(['content', ru ? 'Контент'        : 'Content']);
    }

    if (role !== 'admin' && role !== 'owner') {
      return (
        <div style={{ padding: 80, textAlign: 'center' }}>
          <Display s={28} italic c={C.dim}>{ru ? 'Доступ только для администраторов' : 'Admins only'}</Display>
        </div>
      );
    }

    return (
      <div style={{ overflow: 'auto', height: '100%' }}>
        <section style={{
          padding: '32px 48px 0', borderBottom: `1px solid ${C.line}`,
          background: 'linear-gradient(180deg, rgba(13,10,8,0.7) 0%, transparent 100%)',
        }}>
          <Mono c={C.ember}>· {ru ? 'АДМИНИСТРИРОВАНИЕ' : 'ADMINISTRATION'}</Mono>
          <div style={{ marginTop: 8, marginBottom: 18 }}>
            <Display s={36} italic w={500}>{ru ? 'Панель управления' : 'Control panel'}</Display>
          </div>
          <div style={{ display: 'flex', gap: 24 }}>
            {tabs.map(([k, label]) => (
              <button key={k} onClick={() => setTab(k)} style={{
                background: 'transparent', border: 'none', cursor: 'pointer',
                padding: '10px 0', position: 'relative',
                fontFamily: F.sans, fontSize: 11, letterSpacing: '0.2em',
                textTransform: 'uppercase', fontWeight: 500,
                color: tab === k ? C.hi : C.dim,
              }}>
                {label}
                {tab === k && <span style={{
                  position: 'absolute', left: 0, right: 0, bottom: -1,
                  height: 2, background: C.blood,
                }} />}
              </button>
            ))}
          </div>
        </section>

        <section style={{ padding: '32px 48px' }}>
          {tab === 'products' && <AdminProducts ru={ru} />}
          {tab === 'admins'   && role === 'owner' && <AdminAdmins ru={ru} ownerId={profile.steam_id} />}
          {tab === 'codes'    && role === 'owner' && <AdminBonusCodes ru={ru} />}
          {tab === 'content'  && role === 'owner' && <AdminContent ru={ru} />}
        </section>
      </div>
    );
  }

  // — Управление товарами
  function AdminProducts({ ru }) {
    const [items, setItems] = React.useState([]);
    const [editing, setEditing] = React.useState(null);  // объект продукта или 'new'
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);

    async function reload() {
      try { const r = await api('/api/admin/products'); setItems(r.products || []); }
      catch (e) { setErr(e.message); }
    }
    React.useEffect(() => { reload(); }, []);

    async function save(p) {
      setBusy(true); setErr(null);
      try {
        if (editing === 'new') {
          await api('/api/admin/products', { method: 'POST', body: JSON.stringify(p) });
        } else {
          await api('/api/admin/products/' + encodeURIComponent(p.id), { method: 'PATCH', body: JSON.stringify(p) });
        }
        setEditing(null);
        await reload();
        if (window.FURY_API && window.FURY_API.refreshProducts) window.FURY_API.refreshProducts();
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    async function remove(id) {
      if (!confirm(ru ? `Удалить «${id}»?` : `Delete "${id}"?`)) return;
      setBusy(true); setErr(null);
      try {
        await api('/api/admin/products/' + encodeURIComponent(id), { method: 'DELETE' });
        await reload();
        if (window.FURY_API && window.FURY_API.refreshProducts) window.FURY_API.refreshProducts();
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    if (editing) return <ProductEditor
      initial={editing === 'new' ? { id: '', cat: 'kits', name_ru: '', name_en: '', price: 100, gear: [], active: true } : editing}
      isNew={editing === 'new'}
      ru={ru}
      busy={busy}
      err={err}
      onCancel={() => setEditing(null)}
      onSave={save} />;

    return (
      <div>
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 18 }}>
          <Sans s={11} c={C.dim} upper tracked>{ru ? `Всего товаров: ${items.length}` : `Total: ${items.length}`}</Sans>
          <div style={{ flex: 1 }} />
          <Btn kind="blood" onClick={() => setEditing('new')}>{ru ? '+ Новый товар' : '+ New product'}</Btn>
        </div>
        {err && <div style={{ marginBottom: 12, padding: 10, background: 'rgba(150,30,30,0.18)' }}><Sans s={11} c={C.paper}>{err}</Sans></div>}
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead>
            <tr style={{ textAlign: 'left', borderBottom: `1px solid ${C.line}` }}>
              {['ID','Кат.','Название','Цена','—','Статус',''].map((h, i) => (
                <th key={i} style={{ padding: '10px 8px' }}><Sans s={9} c={C.dim} upper tracked>{h}</Sans></th>
              ))}
            </tr>
          </thead>
          <tbody>
            {items.map((p) => (
              <tr key={p.id} style={{ borderBottom: `1px solid ${C.lineSoft}` }}>
                <td style={{ padding: '10px 8px' }}><Mono c={C.hi}>{p.id}</Mono></td>
                <td style={{ padding: '10px 8px' }}><Sans s={11} c={C.text}>{p.cat}</Sans></td>
                <td style={{ padding: '10px 8px' }}><Sans s={12} c={C.hi}>{p.name_ru}</Sans></td>
                <td style={{ padding: '10px 8px' }}><Display s={14} c={C.ember}>{p.price} ₽</Display></td>
                <td style={{ padding: '10px 8px' }}><Sans s={10} c={C.dim}>{p.was ? p.was + ' ₽' : ''}</Sans></td>
                <td style={{ padding: '10px 8px' }}><Sans s={10} c={p.active ? '#3c8c3c' : C.dim}>{p.active ? (ru ? 'актив' : 'active') : (ru ? 'скрыт' : 'hidden')}</Sans></td>
                <td style={{ padding: '10px 8px', textAlign: 'right' }}>
                  <button onClick={() => setEditing(p)} style={miniBtn(C.line, C.hi)}>{ru ? 'править' : 'edit'}</button>
                  <button onClick={() => remove(p.id)} disabled={busy} style={miniBtn(C.blood, '#fff', 6)}>×</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }

  function miniBtn(bd, fg, ml = 0) {
    return {
      background: 'transparent', border: `1px solid ${bd}`, color: fg, cursor: 'pointer',
      padding: '4px 10px', marginLeft: ml,
      fontFamily: F.sans, fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase',
    };
  }

  function ProductEditor({ initial, isNew, ru, busy, err, onCancel, onSave }) {
    const [p, setP] = React.useState({ ...initial });
    const set = (k) => (e) => setP({ ...p, [k]: e.target.value });
    const setGear = (e) => setP({ ...p, gear: e.target.value.split(',').map((s) => s.trim()).filter(Boolean) });
    return (
      <div style={{ maxWidth: 600 }}>
        <Display s={22} italic w={500}>{isNew ? (ru ? 'Новый товар' : 'New product') : (ru ? 'Редактирование' : 'Editing') + ' · ' + p.id}</Display>
        <div style={{ marginTop: 18, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <Field label="ID" disabled={!isNew} value={p.id} onChange={set('id')} placeholder="kit-bandit" />
          <Field label={ru ? 'Категория' : 'Category'} value={p.cat} onChange={set('cat')} placeholder="kits | vehicles | vip | ..." />
          <Field label={ru ? 'Название (ru)' : 'Name (ru)'} value={p.name_ru} onChange={set('name_ru')} />
          <Field label={ru ? 'Название (en)' : 'Name (en)'} value={p.name_en} onChange={set('name_en')} />
          <Field label={ru ? 'Цена' : 'Price'} type="number" value={p.price} onChange={set('price')} />
          <Field label={ru ? 'Было (опц.)' : 'Was (opt.)'} type="number" value={p.was ?? ''} onChange={set('was')} />
          <Field label={ru ? 'Бейдж' : 'Badge'} value={p.badge ?? ''} onChange={set('badge')} placeholder="hot | new | vip | limited" />
          <Field label={ru ? 'Тон' : 'Tone'} value={p.tone ?? ''} onChange={set('tone')} placeholder="olive | crimson | rust | bone | gold | iron | wood | frost" />
        </div>
        <div style={{ marginTop: 14 }}>
          <Field label={ru ? 'Состав (через запятую)' : 'Gear (comma-separated)'} value={(p.gear || []).join(', ')} onChange={setGear} placeholder="SKS, MP5, каска, рюкзак" />
        </div>

        {/* Картинка товара. Загрузка через FileReader → base64 → отправляется в image_data. */}
        <div style={{ marginTop: 18 }}>
          <Sans s={9} c={C.dim} upper tracked>{ru ? 'Картинка слота (PNG/JPG/WebP/GIF, до 4 МБ)' : 'Slot image (PNG/JPG/WebP/GIF, up to 4 MB)'}</Sans>
          <div style={{ marginTop: 8, display: 'flex', gap: 12, alignItems: 'flex-start' }}>
            <div style={{ width: 140, height: 90, background: C.panel2, border: `1px solid ${C.line}`, overflow: 'hidden', flexShrink: 0 }}>
              {(p.image_data || p.image_url) ? (
                <img src={p.image_data || p.image_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              ) : (
                <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Sans s={10} c={C.dim}>{ru ? 'нет картинки' : 'no image'}</Sans>
                </div>
              )}
            </div>
            <div style={{ flex: 1 }}>
              <input type="file" accept="image/png,image/jpeg,image/webp,image/gif"
                onChange={(e) => {
                  const file = e.target.files && e.target.files[0];
                  if (!file) return;
                  if (file.size > 4 * 1024 * 1024) { alert(ru ? 'Файл больше 4 МБ' : 'File larger than 4 MB'); return; }
                  const reader = new FileReader();
                  reader.onload = () => setP({ ...p, image_data: reader.result });
                  reader.readAsDataURL(file);
                }} />
              {(p.image_data || p.image_url) && (
                <button onClick={() => setP({ ...p, image_data: undefined, image_url: null })}
                  style={{
                    marginTop: 8, background: 'transparent', border: `1px solid ${C.blood}`, color: '#fff',
                    cursor: 'pointer', padding: '4px 10px', fontFamily: F.sans, fontSize: 10,
                    letterSpacing: '0.14em', textTransform: 'uppercase',
                  }}>{ru ? '× убрать картинку' : '× remove image'}</button>
              )}
            </div>
          </div>
        </div>

        <div style={{ marginTop: 14, display: 'flex', alignItems: 'center', gap: 10 }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}>
            <input type="checkbox" checked={!!p.active} onChange={(e) => setP({ ...p, active: e.target.checked })} />
            <Sans s={11} c={C.hi}>{ru ? 'Виден в магазине' : 'Visible in shop'}</Sans>
          </label>
        </div>
        {err && <div style={{ marginTop: 12, padding: 10, background: 'rgba(150,30,30,0.18)' }}><Sans s={11} c={C.paper}>{err}</Sans></div>}
        <div style={{ marginTop: 22, display: 'flex', gap: 10 }}>
          <Btn kind="ghost" onClick={onCancel} disabled={busy}>{ru ? 'Отмена' : 'Cancel'}</Btn>
          <div style={{ flex: 1 }} />
          <Btn kind="blood" onClick={() => onSave(p)} disabled={busy}>{busy ? '…' : (isNew ? (ru ? 'Создать' : 'Create') : (ru ? 'Сохранить' : 'Save'))}</Btn>
        </div>
      </div>
    );
  }

  function Field({ label, value, onChange, placeholder, type = 'text', disabled }) {
    return (
      <div>
        <Sans s={9} c={C.dim} upper tracked>{label}</Sans>
        <input type={type} value={value ?? ''} onChange={onChange} placeholder={placeholder} disabled={disabled}
          style={{
            marginTop: 4, width: '100%', background: 'transparent',
            border: `1px solid ${disabled ? C.lineSoft : C.line}`, color: disabled ? C.dim : C.hi,
            padding: '8px 12px', fontFamily: F.sans, fontSize: 13,
          }} />
      </div>
    );
  }

  // — Управление администраторами
  function AdminAdmins({ ru, ownerId }) {
    const [admins, setAdmins] = React.useState([]);
    const [owner, setOwner] = React.useState(null);
    const [sid, setSid] = React.useState('');
    const [note, setNote] = React.useState('');
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);

    async function reload() {
      try { const r = await api('/api/owner/admins'); setAdmins(r.admins || []); setOwner(r.owner); }
      catch (e) { setErr(e.message); }
    }
    React.useEffect(() => { reload(); }, []);

    async function add() {
      setBusy(true); setErr(null);
      try {
        await api('/api/owner/admins', { method: 'POST', body: JSON.stringify({ steam_id: sid.trim(), note: note.trim() }) });
        setSid(''); setNote('');
        await reload();
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    async function remove(s) {
      if (!confirm(ru ? `Удалить админа ${s}?` : `Remove admin ${s}?`)) return;
      setBusy(true); setErr(null);
      try { await api('/api/owner/admins/' + s, { method: 'DELETE' }); await reload(); }
      catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    return (
      <div style={{ maxWidth: 760 }}>
        <div style={{ padding: 18, background: C.panel2, border: `1px solid ${C.line}`, marginBottom: 22 }}>
          <Mono c={C.ember}>· {ru ? 'ВЛАДЕЛЕЦ' : 'OWNER'}</Mono>
          <div style={{ marginTop: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <Mono c={C.hi}>{owner || '—'}</Mono>
            <Sans s={10} c={C.dim}>{ru ? 'из переменной OWNER_STEAM_ID в .env' : 'from OWNER_STEAM_ID env'}</Sans>
          </div>
        </div>

        <Mono c={C.ember}>· {ru ? 'ДОБАВИТЬ АДМИНА' : 'ADD ADMIN'}</Mono>
        <div style={{ marginTop: 10, display: 'flex', gap: 10 }}>
          <input value={sid} onChange={(e) => setSid(e.target.value)} placeholder="SteamID64 (76561198…)"
            style={{ flex: 2, background: 'transparent', border: `1px solid ${C.line}`, color: C.hi, padding: '10px 14px', fontFamily: F.mono, fontSize: 13 }} />
          <input value={note} onChange={(e) => setNote(e.target.value)} placeholder={ru ? 'заметка (опц.)' : 'note (opt.)'}
            style={{ flex: 1, background: 'transparent', border: `1px solid ${C.line}`, color: C.hi, padding: '10px 14px', fontFamily: F.sans, fontSize: 13 }} />
          <Btn kind="blood" onClick={add} disabled={busy || !sid.trim()}>{ru ? '+ Добавить' : '+ Add'}</Btn>
        </div>
        {err && <div style={{ marginTop: 10, padding: 8, background: 'rgba(150,30,30,0.18)' }}><Sans s={11} c={C.paper}>{err}</Sans></div>}

        <div style={{ marginTop: 28 }}>
          <Mono c={C.ember}>· {ru ? `АДМИНИСТРАТОРЫ (${admins.length})` : `ADMINS (${admins.length})`}</Mono>
          <table style={{ width: '100%', borderCollapse: 'collapse', marginTop: 10 }}>
            <thead>
              <tr style={{ textAlign: 'left', borderBottom: `1px solid ${C.line}` }}>
                {['Steam ID', ru ? 'Добавил' : 'Added by', ru ? 'Когда' : 'When', ru ? 'Заметка' : 'Note', ''].map((h, i) => (
                  <th key={i} style={{ padding: '10px 8px' }}><Sans s={9} c={C.dim} upper tracked>{h}</Sans></th>
                ))}
              </tr>
            </thead>
            <tbody>
              {admins.map((a) => (
                <tr key={a.steam_id} style={{ borderBottom: `1px solid ${C.lineSoft}` }}>
                  <td style={{ padding: '10px 8px' }}><Mono c={C.hi}>{a.steam_id}</Mono></td>
                  <td style={{ padding: '10px 8px' }}><Mono c={C.dim}>{a.added_by.slice(-4)}</Mono></td>
                  <td style={{ padding: '10px 8px' }}><Sans s={11} c={C.text}>{new Date(a.added_at).toLocaleDateString()}</Sans></td>
                  <td style={{ padding: '10px 8px' }}><Sans s={11} c={C.text}>{a.note || ''}</Sans></td>
                  <td style={{ padding: '10px 8px', textAlign: 'right' }}>
                    <button onClick={() => remove(a.steam_id)} disabled={busy} style={miniBtn(C.blood, '#fff')}>{ru ? 'удалить' : 'remove'}</button>
                  </td>
                </tr>
              ))}
              {admins.length === 0 && (
                <tr><td colSpan={5} style={{ padding: '20px 8px' }}><Sans s={11} c={C.dim}>{ru ? 'Админы пока не добавлены.' : 'No admins yet.'}</Sans></td></tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    );
  }

  // — Управление бонус-кодами
  function AdminBonusCodes({ ru }) {
    const [codes, setCodes] = React.useState([]);
    const [amount, setAmount] = React.useState(500);
    const [ttl, setTtl] = React.useState(24);
    const [maxUses, setMaxUses] = React.useState(1);
    const [lastCode, setLastCode] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);

    async function reload() {
      try { const r = await api('/api/owner/bonus-codes'); setCodes(r.codes || []); }
      catch (e) { setErr(e.message); }
    }
    React.useEffect(() => { reload(); }, []);

    async function gen() {
      setBusy(true); setErr(null);
      try {
        const r = await api('/api/owner/bonus-codes', {
          method: 'POST',
          body: JSON.stringify({ amount: Number(amount), ttl_hours: Number(ttl), max_uses: Number(maxUses) }),
        });
        setLastCode(r);
        await reload();
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    async function revoke(code) {
      if (!confirm(ru ? `Отозвать код ${code}?` : `Revoke code ${code}?`)) return;
      setBusy(true);
      try { await api('/api/owner/bonus-codes/' + code, { method: 'DELETE' }); await reload(); }
      catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    function statusOf(c) {
      if (c.revoked)   return ru ? 'отозван' : 'revoked';
      if (c.expired)   return ru ? 'истёк'   : 'expired';
      if (c.exhausted) return ru ? 'исчерпан' : 'exhausted';
      return ru ? 'активен' : 'active';
    }

    return (
      <div style={{ maxWidth: 900 }}>
        <Mono c={C.ember}>· {ru ? 'СГЕНЕРИРОВАТЬ КОД' : 'GENERATE CODE'}</Mono>
        <div style={{ marginTop: 12, display: 'flex', gap: 14, alignItems: 'flex-end' }}>
          <div style={{ minWidth: 120 }}>
            <Sans s={9} c={C.dim} upper tracked>{ru ? 'Сумма, ₽' : 'Amount, ₽'}</Sans>
            <input type="number" value={amount} onChange={(e) => setAmount(e.target.value)} min="1" max="100000"
              style={{ marginTop: 4, width: '100%', background: 'transparent', border: `1px solid ${C.line}`, color: C.hi, padding: '8px 12px', fontSize: 14 }} />
          </div>
          <div style={{ minWidth: 120 }}>
            <Sans s={9} c={C.dim} upper tracked>{ru ? 'Срок, часов' : 'TTL, hours'}</Sans>
            <input type="number" value={ttl} onChange={(e) => setTtl(e.target.value)} min="1" max="720"
              style={{ marginTop: 4, width: '100%', background: 'transparent', border: `1px solid ${C.line}`, color: C.hi, padding: '8px 12px', fontSize: 14 }} />
          </div>
          <div style={{ minWidth: 120 }}>
            <Sans s={9} c={C.dim} upper tracked>{ru ? 'Активаций' : 'Max uses'}</Sans>
            <input type="number" value={maxUses} onChange={(e) => setMaxUses(e.target.value)} min="1" max="10000"
              style={{ marginTop: 4, width: '100%', background: 'transparent', border: `1px solid ${C.line}`, color: C.hi, padding: '8px 12px', fontSize: 14 }} />
          </div>
          <Btn kind="blood" onClick={gen} disabled={busy}>{busy ? '…' : (ru ? '+ Создать' : '+ Generate')}</Btn>
        </div>

        {lastCode && (
          <div style={{ marginTop: 18, padding: 18, background: 'rgba(60,140,60,0.10)', border: '1px solid #3c8c3c' }}>
            <Sans s={10} c={C.dim} upper tracked>{ru ? 'НОВЫЙ КОД (СКОПИРУЙТЕ — БОЛЬШЕ ОТКРЫТО НЕ ОТОБРАЗИТСЯ)' : 'NEW CODE (COPY NOW)'}</Sans>
            <div style={{ marginTop: 8 }}><Display s={28} c={C.paper} style={{ fontFamily: F.mono, letterSpacing: '0.18em' }}>{lastCode.code}</Display></div>
            <Sans s={11} c={C.text}>{lastCode.amount} ₽ · {lastCode.max_uses} {ru ? 'активаций' : 'uses'} · {ru ? 'до' : 'until'} {new Date(lastCode.expires_at).toLocaleString()}</Sans>
          </div>
        )}
        {err && <div style={{ marginTop: 10, padding: 8, background: 'rgba(150,30,30,0.18)' }}><Sans s={11} c={C.paper}>{err}</Sans></div>}

        <div style={{ marginTop: 28 }}>
          <Mono c={C.ember}>· {ru ? `ВЫПУЩЕННЫЕ КОДЫ (${codes.length})` : `ISSUED CODES (${codes.length})`}</Mono>
          <table style={{ width: '100%', borderCollapse: 'collapse', marginTop: 10 }}>
            <thead>
              <tr style={{ textAlign: 'left', borderBottom: `1px solid ${C.line}` }}>
                {[ru ? 'Код' : 'Code', '₽', ru ? 'Активаций' : 'Uses', ru ? 'Истекает' : 'Expires', ru ? 'Статус' : 'Status', ''].map((h, i) => (
                  <th key={i} style={{ padding: '10px 8px' }}><Sans s={9} c={C.dim} upper tracked>{h}</Sans></th>
                ))}
              </tr>
            </thead>
            <tbody>
              {codes.map((c) => (
                <tr key={c.code} style={{ borderBottom: `1px solid ${C.lineSoft}` }}>
                  <td style={{ padding: '10px 8px' }}><Mono c={C.hi}>{c.code}</Mono></td>
                  <td style={{ padding: '10px 8px' }}><Display s={14} c={C.ember}>{c.amount}</Display></td>
                  <td style={{ padding: '10px 8px' }}><Sans s={11} c={C.text}>{c.uses}/{c.max_uses}</Sans></td>
                  <td style={{ padding: '10px 8px' }}><Sans s={10} c={C.dim}>{new Date(c.expires_at).toLocaleString()}</Sans></td>
                  <td style={{ padding: '10px 8px' }}><Sans s={10} c={(c.revoked || c.expired || c.exhausted) ? C.dim : '#3c8c3c'}>{statusOf(c)}</Sans></td>
                  <td style={{ padding: '10px 8px', textAlign: 'right' }}>
                    {!c.revoked && !c.expired && !c.exhausted && (
                      <button onClick={() => revoke(c.code)} disabled={busy} style={miniBtn(C.blood, '#fff')}>{ru ? 'отозвать' : 'revoke'}</button>
                    )}
                  </td>
                </tr>
              ))}
              {codes.length === 0 && (
                <tr><td colSpan={6} style={{ padding: '20px 8px' }}><Sans s={11} c={C.dim}>{ru ? 'Кодов пока нет.' : 'No codes yet.'}</Sans></td></tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    );
  }

  // — Маленький инпут: загрузка логотипа/фавикона. Тип = 'logo' | 'favicon'.
  function SiteImagePicker({ ru, type, label, hint, currentUrl, onChange }) {
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);

    async function upload(file) {
      if (!file) return;
      if (file.size > 1024 * 1024) { setErr(ru ? 'Файл больше 1 МБ' : 'File larger than 1 MB'); return; }
      const reader = new FileReader();
      reader.onload = async () => {
        setBusy(true); setErr(null);
        try {
          const r = await api('/api/admin/site-images/' + type, {
            method: 'POST',
            body: JSON.stringify({ image_data: reader.result }),
          });
          onChange(r.url);
          window.dispatchEvent(new CustomEvent('fury:site-settings'));
        } catch (e) { setErr(e.data?.error || e.message); }
        finally { setBusy(false); }
      };
      reader.readAsDataURL(file);
    }

    async function remove() {
      setBusy(true); setErr(null);
      try {
        await api('/api/admin/site-images/' + type, { method: 'DELETE' });
        onChange('');
        window.dispatchEvent(new CustomEvent('fury:site-settings'));
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    return (
      <div style={{ marginTop: 14, padding: 14, background: C.panel2, border: `1px solid ${C.line}` }}>
        <Sans s={9} c={C.dim} upper tracked>{label}</Sans>
        <div style={{ marginTop: 4 }}><Sans s={10} c={C.dim}>{hint}</Sans></div>
        <div style={{ marginTop: 10, display: 'flex', alignItems: 'flex-start', gap: 14 }}>
          <div style={{
            width: type === 'favicon' ? 64 : 140,
            height: type === 'favicon' ? 64 : 60,
            background: C.bg, border: `1px solid ${C.line}`, overflow: 'hidden', flexShrink: 0,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {currentUrl ? (
              <img src={currentUrl} alt="" style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
            ) : <Sans s={10} c={C.dim}>{ru ? 'нет' : 'empty'}</Sans>}
          </div>
          <div style={{ flex: 1 }}>
            <input type="file"
              accept={type === 'favicon' ? 'image/png,image/svg+xml,image/x-icon,image/webp,image/jpeg' : 'image/png,image/jpeg,image/svg+xml,image/webp'}
              disabled={busy}
              onChange={(e) => upload(e.target.files && e.target.files[0])} />
            {currentUrl && (
              <button onClick={remove} disabled={busy} style={{
                display: 'block', marginTop: 8,
                background: 'transparent', border: `1px solid ${C.blood}`, color: '#fff', cursor: 'pointer',
                padding: '4px 10px', fontFamily: F.sans, fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase',
              }}>{ru ? '× удалить' : '× remove'}</button>
            )}
            {err && <div style={{ marginTop: 8 }}><Sans s={10} c={C.blood}>{err}</Sans></div>}
          </div>
        </div>
      </div>
    );
  }

  // — Редактирование содержимого сайта (футер-ссылки + 3 политики). Owner-only.
  function AdminContent({ ru }) {
    const [s, setS] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const [msg, setMsg] = React.useState(null);
    const [err, setErr] = React.useState(null);

    async function reload() {
      try {
        const r = await api('/api/site-settings');
        setS(r.settings || {});
      } catch (e) { setErr(e.message); }
    }
    React.useEffect(() => { reload(); }, []);

    if (!s) return <Sans s={11} c={C.dim}>{ru ? 'Загрузка…' : 'Loading…'}</Sans>;

    const set = (k) => (e) => setS({ ...s, [k]: e.target.value });

    async function save() {
      setBusy(true); setMsg(null); setErr(null);
      try {
        await api('/api/admin/site-settings', { method: 'PATCH', body: JSON.stringify(s) });
        // Обновим кеш в window для футера.
        window.__FURY_SITE_SETTINGS = { ...s };
        setMsg(ru ? 'Сохранено' : 'Saved');
      } catch (e) { setErr(e.data?.error || e.message); }
      finally { setBusy(false); }
    }

    const labelStyle = { display: 'block', marginTop: 18 };
    const taStyle = {
      marginTop: 6, width: '100%', minHeight: 180, background: 'transparent',
      border: `1px solid ${C.line}`, color: C.hi, padding: 12,
      fontFamily: F.sans, fontSize: 13, lineHeight: 1.5, resize: 'vertical',
    };
    const inputStyle = {
      marginTop: 6, width: '100%', background: 'transparent',
      border: `1px solid ${C.line}`, color: C.hi, padding: '10px 14px',
      fontFamily: F.mono, fontSize: 13,
    };

    return (
      <div style={{ maxWidth: 880 }}>
        <Sans s={11} c={C.dim}>{ru
          ? 'Эти поля видны всем посетителям сайта в подвале и в модальных окнах с политиками. Сохранение перезапишет текущие значения сразу для всех.'
          : 'These fields are public — they show in the site footer and policy modals. Save updates them for all visitors immediately.'}</Sans>

        {/* Логотип в шапке + фавикон вкладки. Сохраняются мгновенно при выборе файла. */}
        <div style={{ marginTop: 22 }}>
          <Mono c={C.ember}>· {ru ? 'ЛОГОТИП И ИКОНКА ВКЛАДКИ' : 'LOGO & FAVICON'}</Mono>
          <SiteImagePicker ru={ru} type="logo" label={ru ? 'Логотип в шапке' : 'Header logo'}
            hint={ru
              ? 'PNG/JPG/WebP/SVG, до 1 МБ. Заменяет крест-иконку слева от слова FURY. Высота 50px, ширина — автоматически.'
              : 'PNG/JPG/WebP/SVG, up to 1 MB. Replaces the cross icon next to the FURY wordmark.'}
            currentUrl={s.logo_url}
            onChange={(url) => setS({ ...s, logo_url: url })} />
          <SiteImagePicker ru={ru} type="favicon" label={ru ? 'Иконка вкладки браузера (favicon)' : 'Browser tab icon (favicon)'}
            hint={ru
              ? 'PNG/SVG/ICO/WebP, до 1 МБ. Желательно квадратное изображение 32×32 или 64×64.'
              : 'PNG/SVG/ICO/WebP, up to 1 MB. Square 32×32 or 64×64 is ideal.'}
            currentUrl={s.favicon_url}
            onChange={(url) => setS({ ...s, favicon_url: url })} />
        </div>

        <div style={{ marginTop: 28 }}>
          <Mono c={C.ember}>· {ru ? 'ССЫЛКИ В ПОДВАЛЕ' : 'FOOTER LINKS'}</Mono>
        </div>

        <label style={labelStyle}>
          <Sans s={9} c={C.dim} upper tracked>Discord URL</Sans>
          <input value={s.discord_url || ''} onChange={set('discord_url')} placeholder="https://discord.gg/..." style={inputStyle} />
        </label>

        <label style={labelStyle}>
          <Sans s={9} c={C.dim} upper tracked>{ru ? 'Ссылка на мод в Steam' : 'Steam Workshop mod URL'}</Sans>
          <input value={s.mod_url || ''} onChange={set('mod_url')} placeholder="https://steamcommunity.com/sharedfiles/filedetails/?id=..." style={inputStyle} />
        </label>

        <label style={labelStyle}>
          <Sans s={9} c={C.dim} upper tracked>{ru ? 'Пользовательское соглашение' : 'Terms of Use'}</Sans>
          <textarea value={s.policy_terms || ''} onChange={set('policy_terms')} style={taStyle} />
        </label>

        <label style={labelStyle}>
          <Sans s={9} c={C.dim} upper tracked>{ru ? 'Политика конфиденциальности' : 'Privacy Policy'}</Sans>
          <textarea value={s.policy_privacy || ''} onChange={set('policy_privacy')} style={taStyle} />
        </label>

        <label style={labelStyle}>
          <Sans s={9} c={C.dim} upper tracked>{ru ? 'Политика информационной безопасности' : 'Information Security Policy'}</Sans>
          <textarea value={s.policy_security || ''} onChange={set('policy_security')} style={taStyle} />
        </label>

        {err && <div style={{ marginTop: 14, padding: 10, background: 'rgba(150,30,30,0.18)' }}><Sans s={11} c={C.paper}>{err}</Sans></div>}
        {msg && <div style={{ marginTop: 14, padding: 10, background: 'rgba(60,140,60,0.18)' }}><Sans s={11} c={C.paper}>{msg}</Sans></div>}

        <div style={{ marginTop: 22, display: 'flex' }}>
          <div style={{ flex: 1 }} />
          <Btn kind="blood" onClick={save} disabled={busy}>{busy ? '…' : (ru ? 'Сохранить' : 'Save')}</Btn>
        </div>
      </div>
    );
  }

  function Btn({ kind = 'blood', children, onClick, full, disabled, style }) {
    const map = {
      blood: { bg: C.blood, fg: '#fff', bd: 'transparent' },
      cream: { bg: C.paper, fg: C.bg, bd: 'transparent' },
      ghost: { bg: 'transparent', fg: C.hi, bd: C.line },
      link:  { bg: 'transparent', fg: C.ember, bd: 'transparent' },
    };
    const v = map[kind];
    return (
      <button onClick={onClick} disabled={disabled} style={{
        background: v.bg, color: v.fg, border: `1px solid ${v.bd}`,
        padding: '12px 22px', fontFamily: F.sans, fontSize: 11,
        letterSpacing: '0.18em', textTransform: 'uppercase', fontWeight: 600,
        cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
        width: full ? '100%' : 'auto', transition: 'all .15s', ...style,
      }}>{children}</button>
    );
  }

  // Atmospheric card image — full-bleed gradient w/ silhouette glyph + faint
  // grain. Wider than other variants.
  function CardArt({ p, h = 240, withVignette = true }) {
    return (
      <div style={{ position: 'relative', height: h, overflow: 'hidden', background: furyTone(p.tone) }}>
        {/* user-uploaded image, если есть — затирает gradient/glyph */}
        {p.image_url && (
          <img src={p.image_url} alt="" style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%',
            objectFit: 'cover', display: 'block',
          }} />
        )}
        {/* fog */}
        <div style={{
          position: 'absolute', inset: 0,
          background: 'radial-gradient(ellipse at 50% 100%, rgba(13,10,8,0.7) 0%, transparent 60%)',
        }} />
        {/* grain */}
        <div style={{
          position: 'absolute', inset: 0, opacity: 0.18, mixBlendMode: 'overlay',
          backgroundImage:
            "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.7'/></svg>\")",
        }} />
        {/* silhouette — показываем только если нет загруженной картинки */}
        {!p.image_url && (
          <div style={{
            position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'rgba(232,220,203,0.78)',
          }}>
            <FuryGlyph cat={p.cat} size={Math.round(h * 0.45)} />
          </div>
        )}
        {withVignette && (
          <div style={{
            position: 'absolute', inset: 0, pointerEvents: 'none',
            background:
              'radial-gradient(ellipse at center, transparent 50%, rgba(13,10,8,0.6) 100%)',
          }} />
        )}
        {/* watermark label */}
        <div style={{
          position: 'absolute', bottom: 14, left: 16, color: 'rgba(232,220,203,0.55)',
          fontFamily: F.mono, fontSize: 9, letterSpacing: '0.2em',
        }}>
          № {String(window.FURY_PRODUCTS.indexOf(p) + 1).padStart(3, '0')}
        </div>
      </div>
    );
  }

  function Badge({ kind, t }) {
    if (!kind) return null;
    const m = {
      hot:     { ribbon: C.blood, fg: '#fff', text: t.hot_badge },
      new:     { ribbon: C.ember, fg: '#1a1208', text: t.new_badge },
      vip:     { ribbon: C.paper, fg: C.bg, text: t.vip_badge },
      limited: { ribbon: C.bloodDeep, fg: '#fff', text: t.limited },
    };
    const v = m[kind] || m.hot;
    return (
      <div style={{
        position: 'absolute', top: 16, left: 0, zIndex: 2,
        background: v.ribbon, color: v.fg, padding: '6px 14px 6px 16px',
        fontFamily: F.sans, fontSize: 10, fontWeight: 600,
        letterSpacing: '0.2em', textTransform: 'uppercase',
      }}>{v.text}</div>
    );
  }

  // ── Product card ─────────────────────────────────────────────────────────
  function ProductCard({ p, inCart, onAdd, onOpen, t }) {
    return (
      <article onClick={() => onOpen(p.id)} style={{
        background: C.panel, position: 'relative', overflow: 'hidden',
        boxShadow: `inset 0 0 0 1px ${C.lineSoft}`,
        transition: 'transform .2s, box-shadow .2s', cursor: 'pointer',
      }}>
        <Badge kind={p.badge} t={t} />
        <CardArt p={p} h={220} />
        <div style={{ padding: '22px 24px 24px', position: 'relative' }}>
          {/* price chip — bottom-right of image, overlapping */}
          <div style={{
            position: 'absolute', right: 22, top: -22,
            background: C.bg, padding: '10px 14px 10px 18px',
            border: `1px solid ${C.line}`, textAlign: 'right',
          }}>
            {p.was && <Sans s={11} c={C.dim} style={{ textDecoration: 'line-through', display: 'block' }}>{furyFmt(p.was)} {t.rub}</Sans>}
            <Display s={24} c={C.hi} w={500}>{furyFmt(p.price)}</Display>
            <Sans s={11} c={C.dim} style={{ marginLeft: 4 }}>{t.rub}</Sans>
          </div>
          <Mono c={C.ember}>· {t.cats[p.cat]}</Mono>
          <div style={{ marginTop: 6 }}>
            <Display s={22} italic style={{ lineHeight: 1.15 }}>{window.FURY_pname(p)}</Display>
          </div>
          <div style={{
            marginTop: 12, color: C.text, fontFamily: F.sans, fontSize: 12,
            lineHeight: 1.5,
          }}>
            {p.gear.join(' · ')}
          </div>
          <div style={{ marginTop: 18, display: 'flex', alignItems: 'center', gap: 10 }}>
            <Btn kind={inCart ? 'cream' : 'blood'} onClick={(e) => { e.stopPropagation(); onAdd(p.id); }} style={{ padding: '10px 18px', fontSize: 10 }}>
              {inCart ? `✓ ${t.in_cart} · ${inCart}` : `+ ${t.add_to_cart}`}
            </Btn>
            <Btn kind="link" style={{ padding: '10px 4px', fontSize: 10 }}>{t.buy_now} →</Btn>
          </div>
        </div>
      </article>
    );
  }

  // ── Header ───────────────────────────────────────────────────────────────
  function Header({ shop }) {
    const { t, view, setView, cartCount, setCartOpen, profile, lang } = shop;
    const [topupOpen, setTopupOpen] = React.useState(false);
    const siteSettings = useSiteSettings();
    const logoUrl = siteSettings && siteSettings.logo_url;
    return (
      <header style={{
        height: 88, background: C.bg, borderBottom: `1px solid ${C.lineSoft}`,
        display: 'flex', alignItems: 'center', padding: '0 36px', gap: 32,
      }}>
        {topupOpen && (
          <TopUpModal lang={lang} onClose={() => setTopupOpen(false)} loggedIn={profile.loggedIn !== false} />
        )}
        {/* Logo: serif wordmark with hairline cross above */}
        <button onClick={() => setView('shop')} title={lang === 'ru' ? 'В магазин' : 'To shop'} style={{
          display: 'flex', alignItems: 'center', gap: 14,
          background: 'transparent', border: 'none', padding: 0, cursor: 'pointer', color: 'inherit',
        }}>
          {logoUrl ? (
            <img src={logoUrl} alt="FURY" style={{ height: 50, width: 'auto', maxWidth: 120, objectFit: 'contain', display: 'block' }} />
          ) : (
            <div style={{ position: 'relative', width: 40, height: 50 }}>
              <span style={{ position: 'absolute', top: 6,  left: '50%', width: 1,  height: 38, background: C.blood, transform: 'translateX(-50%)' }} />
              <span style={{ position: 'absolute', top: 18, left: '50%', width: 22, height: 1,  background: C.blood, transform: 'translateX(-50%)' }} />
              <span style={{ position: 'absolute', bottom: 0, left: '50%', width: 8, height: 8, background: C.blood, transform: 'translateX(-50%) rotate(45deg)' }} />
            </div>
          )}
          <div style={{ textAlign: 'left' }}>
            <Display s={28} w={600} style={{ letterSpacing: '0.04em' }}>{t.brand}</Display>
            <div style={{ marginTop: 2 }}><Sans s={9} c={C.dim} upper tracked>— {t.tagline}</Sans></div>
          </div>
        </button>

        <div style={{ flex: 1 }} />

        <nav style={{ display: 'flex', gap: 28 }}>
          {(() => {
            const items = [['shop', t.nav_shop], ['servers', t.nav_servers], ['profile', t.nav_profile]];
            const role = profile && profile.role;
            if (role === 'admin' || role === 'owner') {
              items.push(['admin', lang === 'ru' ? 'Админка' : 'Admin']);
            }
            return items;
          })().map(([k, label]) => {
            const active = view === k;
            return (
              <button key={k} onClick={() => setView(k)} style={{
                background: 'transparent', border: 'none', cursor: 'pointer',
                padding: '6px 0', position: 'relative',
                fontFamily: F.sans, fontSize: 11, letterSpacing: '0.2em',
                textTransform: 'uppercase', fontWeight: 500,
                color: active ? C.hi : C.dim,
              }}>
                {label}
                {active && (
                  <span style={{
                    position: 'absolute', left: 0, right: 0, bottom: -4,
                    height: 1, background: C.blood,
                  }} />
                )}
              </button>
            );
          })}
        </nav>

        <div style={{ flex: 1 }} />

        {/* Search */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10,
          borderBottom: `1px solid ${C.line}`, padding: '6px 4px', width: 200,
        }}>
          <span style={{ color: C.dim, fontFamily: F.serif, fontStyle: 'italic' }}>⌕</span>
          <input value={shop.search} onChange={(e) => shop.setSearch(e.target.value)}
            placeholder={t.search}
            style={{
              flex: 1, background: 'transparent', border: 'none', outline: 'none',
              color: C.hi, fontFamily: F.serif, fontStyle: 'italic', fontSize: 14,
            }} />
        </div>

        {/* Balance — кликабельный, открывает модал пополнения через FreeKassa/ЮKassa */}
        <button
          onClick={() => setTopupOpen(true)}
          title={lang === 'ru' ? 'Пополнить баланс' : 'Top up balance'}
          style={{
            textAlign: 'right', background: 'transparent', border: 'none', cursor: 'pointer',
            padding: '4px 6px', color: 'inherit', display: 'flex', flexDirection: 'column',
            alignItems: 'flex-end', gap: 0,
          }}>
          <Sans s={9} c={C.dim} upper tracked>{t.balance}</Sans>
          <div>
            <Display s={20} w={500} c={C.ember}>
              {furyFmt(profile.balance)} <span style={{ fontSize: 12, color: C.dim }}>{t.rub}</span>
            </Display>
            <span style={{
              marginLeft: 8, color: C.ember, border: `1px solid ${C.ember}`, padding: '0 6px',
              fontFamily: F.sans, fontSize: 12, fontWeight: 700, lineHeight: '18px',
              display: 'inline-block', verticalAlign: 'middle',
            }}>+</span>
          </div>
        </button>

        {/* Cart */}
        <button onClick={() => setCartOpen(true)} style={{
          background: 'transparent', border: `1px solid ${C.line}`, cursor: 'pointer',
          padding: '10px 16px', color: C.hi, display: 'flex', alignItems: 'center', gap: 10,
          fontFamily: F.sans, fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
        }}>
          <span>{t.nav_cart}</span>
          <span style={{
            background: C.blood, color: '#fff', padding: '1px 7px',
            borderRadius: 10, fontSize: 10, fontWeight: 700,
          }}>{cartCount}</span>
        </button>
      </header>
    );
  }

  // ── Hero / deal banner ───────────────────────────────────────────────────
  // Хук-таймер: возвращает {d, h, m} до полуночи. Тикает раз в секунду.
  function useCountdownToMidnight() {
    const [now, setNow] = React.useState(Date.now());
    React.useEffect(() => {
      const id = setInterval(() => setNow(Date.now()), 1000);
      return () => clearInterval(id);
    }, []);
    const midnight = new Date();
    midnight.setHours(24, 0, 0, 0);
    const diff = Math.max(0, midnight.getTime() - now);
    const totalSec = Math.floor(diff / 1000);
    const d = Math.floor(totalSec / 86400);
    const h = Math.floor((totalSec % 86400) / 3600);
    const m = Math.floor((totalSec % 3600) / 60);
    const pad2 = (n) => String(n).padStart(2, '0');
    return { d: pad2(d), h: pad2(h), m: pad2(m) };
  }

  function Hero({ shop }) {
    const { t, add, servers, serverId, lang } = shop;
    const srv = servers.find((s) => s.id === serverId) || servers[0];
    const map = lang === 'ru' ? srv.map_ru : srv.map_en;
    const cd = useCountdownToMidnight();
    // Сделка дня приезжает из бэкенда (fury-api.js → /api/daily-deal).
    // Если бэкенд недоступен — показываем дефолт из data.js.
    const deal = window.FURY_DAILY_DEAL || null;
    const dealName = deal && deal.product
      ? (lang === 'ru' ? deal.product.name_ru : deal.product.name_en).toUpperCase()
      : t.deal_title;
    const dealDescParts = deal && deal.product && Array.isArray(deal.product.gear)
      ? deal.product.gear.slice(0, 4).join(' · ')
      : t.deal_desc;
    const dealPct = deal ? deal.discount_pct : 25;
    const dealAddId = deal ? deal.product_id : 'kit-survivor';
    return (
      <section style={{
        position: 'relative', height: 280, overflow: 'hidden',
        background: 'linear-gradient(135deg, #1a1410 0%, #2a1818 60%, #0d0a08 100%)',
      }}>
        {/* atmospheric layer — distant pine silhouette */}
        <svg viewBox="0 0 1440 280" preserveAspectRatio="none" style={{
          position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: 0.55,
        }}>
          <defs>
            <linearGradient id="fog" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="#3a2018" stopOpacity="0" />
              <stop offset="100%" stopColor="#0d0a08" stopOpacity="1" />
            </linearGradient>
          </defs>
          <rect width="1440" height="280" fill="url(#fog)" />
          {Array.from({ length: 22 }).map((_, i) => {
            const x = i * 70 + (i % 3) * 12;
            const w = 32 + (i % 5) * 6;
            const h = 70 + (i % 4) * 25;
            return (
              <polygon key={i}
                points={`${x},${280} ${x + w / 2},${280 - h} ${x + w},${280}`}
                fill="#0a0806" />
            );
          })}
          {Array.from({ length: 16 }).map((_, i) => {
            const x = i * 95 + 40;
            const w = 26 + (i % 3) * 4;
            const h = 50 + (i % 4) * 20;
            return (
              <polygon key={'b' + i}
                points={`${x},${280} ${x + w / 2},${280 - h} ${x + w},${280}`}
                fill="#1a1410" opacity="0.7" />
            );
          })}
        </svg>
        {/* grain */}
        <div style={{
          position: 'absolute', inset: 0, opacity: 0.12, mixBlendMode: 'overlay',
          backgroundImage:
            "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>\")",
        }} />
        {/* content */}
        <div style={{
          position: 'relative', height: '100%', padding: '40px 48px',
          display: 'flex', alignItems: 'center', gap: 40,
        }}>
          <div style={{ flex: 1, maxWidth: 720 }}>
            <Mono c={C.ember}>· {t.daily_deal.toUpperCase()}</Mono>
            <div style={{ marginTop: 10 }}>
              <Display s={58} italic c={C.hi} w={400}>{dealName}</Display>
            </div>
            <div style={{ marginTop: 14, maxWidth: 520 }}>
              <Sans s={14} c={C.text} style={{ lineHeight: 1.5 }}>{dealDescParts}</Sans>
            </div>
            <div style={{ marginTop: 22, display: 'flex', alignItems: 'center', gap: 18 }}>
              <Btn kind="blood" onClick={() => add(dealAddId)}>{t.deal_cta}</Btn>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 4 }}>
                <Display s={36} c={C.blood} w={600}>−{dealPct}%</Display>
                <Sans s={11} c={C.dim} upper tracked>· {t.save}</Sans>
              </div>
              <div style={{ width: 1, height: 30, background: C.line }} />
              <div style={{ display: 'flex', gap: 14 }}>
                {[[cd.d, t.days_short], [cd.h, t.hours_short], [cd.m, t.mins_short]].map(([v, l], i) => (
                  <div key={i} style={{ textAlign: 'center' }}>
                    <Display s={24} c={C.hi} w={500}>{v}</Display>
                    <div><Mono c={C.dim}>{l}</Mono></div>
                  </div>
                ))}
              </div>
            </div>
          </div>
          {/* right-side server card */}
          <div style={{
            width: 280, background: 'rgba(13,10,8,0.65)', padding: 22,
            border: `1px solid ${C.line}`, backdropFilter: 'blur(6px)',
          }}>
            <Mono c={C.ember}>· {t.server_status}</Mono>
            <div style={{ marginTop: 8 }}><Display s={20} w={500}>{srv.name}</Display></div>
            <div style={{ marginTop: 4 }}><Sans s={11} c={C.dim}>{map} · {srv.mods}</Sans></div>
            <div style={{ marginTop: 16, display: 'flex', gap: 20 }}>
              <div>
                <Mono c={C.dim}>{t.online.toUpperCase()}</Mono>
                <div><Display s={20} c={C.hi}>{srv.online}<span style={{ color: C.dim, fontSize: 14 }}>/{srv.max}</span></Display></div>
              </div>
              <div>
                <Mono c={C.dim}>{t.ping.toUpperCase()}</Mono>
                <div><Display s={20} c={C.hi}>{srv.ping}<span style={{ color: C.dim, fontSize: 11 }}>ms</span></Display></div>
              </div>
            </div>
            <div style={{
              marginTop: 14, height: 2, background: C.lineSoft, position: 'relative',
            }}>
              <div style={{
                position: 'absolute', inset: 0, width: `${(srv.online / srv.max) * 100}%`,
                background: C.ember,
              }} />
            </div>
          </div>
        </div>
      </section>
    );
  }

  // ── Filter rail (horizontal pills above grid) ────────────────────────────
  function FilterRail({ shop }) {
    const { t, cat, setCat, sort, setSort } = shop;
    const cats = [
      ['all', t.cats.all], ['kits', t.cats.kits], ['build', t.cats.build],
      ['vehicles', t.cats.vehicles], ['vip', t.cats.vip], ['cosmetics', t.cats.cosmetics],
      ['currency', t.cats.currency], ['slots', t.cats.slots],
    ];
    return (
      <div style={{
        padding: '24px 48px 12px', display: 'flex', alignItems: 'center', gap: 6,
        borderBottom: `1px solid ${C.lineSoft}`, flexWrap: 'wrap',
      }}>
        {cats.map(([k, label]) => {
          const active = cat === k;
          return (
            <button key={k} onClick={() => setCat(k)} style={{
              background: active ? C.hi : 'transparent',
              color: active ? C.bg : C.text,
              border: `1px solid ${active ? C.hi : C.line}`,
              padding: '8px 16px', cursor: 'pointer',
              fontFamily: F.sans, fontSize: 11, letterSpacing: '0.14em',
              textTransform: 'uppercase', fontWeight: 500,
              borderRadius: 999,
            }}>{label}</button>
          );
        })}
        <div style={{ flex: 1 }} />
        <Sans s={10} c={C.dim} upper tracked style={{ marginRight: 6 }}>{t.sort_by} —</Sans>
        <select value={sort} onChange={(e) => setSort(e.target.value)} style={{
          background: 'transparent', color: C.hi, border: `1px solid ${C.line}`,
          padding: '8px 12px', fontFamily: F.sans, fontSize: 11, letterSpacing: '0.1em',
          textTransform: 'uppercase', borderRadius: 999, cursor: 'pointer',
        }}>
          <option value="popular" style={{ background: C.bg }}>{t.sort_popular}</option>
          <option value="price_asc" style={{ background: C.bg }}>{t.sort_price_asc}</option>
          <option value="price_desc" style={{ background: C.bg }}>{t.sort_price_desc}</option>
          <option value="new" style={{ background: C.bg }}>{t.sort_new}</option>
        </select>
      </div>
    );
  }

  // ── Cart drawer ──────────────────────────────────────────────────────────
  function CartDrawer({ shop }) {
    const { t, cartOpen, setCartOpen, cartItems, subtotal, discount, total, setQty, remove, profile, lang } = shop;
    const [pending, setPending] = React.useState(false);
    const [err, setErr] = React.useState(null);
    const [done, setDone] = React.useState(null);

    async function onCheckout() {
      setErr(null); setDone(null);
      if (!profile || profile.loggedIn === false) {
        if (window.FURY_API) window.FURY_API.login();
        return;
      }
      if (!window.FURY_API) {
        setErr(lang === 'ru' ? 'Сервер недоступен' : 'Server unavailable');
        return;
      }
      try {
        setPending(true);
        const res = await window.FURY_API.checkout(cartItems, { useBonus: true });
        cartItems.forEach(({ p }) => remove(p.id));
        setDone(res);
      } catch (e) {
        if (e.status === 402) {
          setErr(lang === 'ru' ? 'Недостаточно средств — пополните баланс' : 'Insufficient funds — top up your balance');
        } else if (e.status === 401) {
          window.FURY_API.login();
        } else {
          setErr(String(e.message || e));
        }
      } finally {
        setPending(false);
      }
    }

    if (!cartOpen) return null;
    return (
      <>
        <div onClick={() => setCartOpen(false)} style={{
          position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.7)', zIndex: 50,
          backdropFilter: 'blur(2px)',
        }} />
        <div style={{
          position: 'absolute', top: 0, right: 0, bottom: 0, width: 440,
          background: C.panel, zIndex: 51, display: 'flex', flexDirection: 'column',
          borderLeft: `1px solid ${C.line}`,
        }}>
          <div style={{ padding: '28px 32px', borderBottom: `1px solid ${C.lineSoft}` }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
              <Mono c={C.ember}>· {t.cart_title.toUpperCase()}</Mono>
              <button onClick={() => setCartOpen(false)} style={{
                background: 'transparent', border: 'none', color: C.dim, cursor: 'pointer',
                fontFamily: F.serif, fontSize: 22, lineHeight: 1,
              }}>✕</button>
            </div>
            <div style={{ marginTop: 8 }}>
              <Display s={32} italic>{cartItems.length} {t.cart_title.toLowerCase()}</Display>
            </div>
          </div>
          {cartItems.length === 0 ? (
            <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 18 }}>
              <Display s={20} italic c={C.dim}>{t.cart_empty}</Display>
              <Btn kind="ghost" onClick={() => setCartOpen(false)}>{t.continue_shopping}</Btn>
            </div>
          ) : (
            <>
              <div style={{ flex: 1, overflow: 'auto', padding: '20px 32px' }}>
                {cartItems.map(({ p, qty }, i) => (
                  <div key={p.id} style={{
                    display: 'flex', gap: 14, padding: '16px 0',
                    borderBottom: i < cartItems.length - 1 ? `1px solid ${C.lineSoft}` : 'none',
                  }}>
                    <div style={{
                      width: 72, height: 72, background: furyTone(p.tone),
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      color: 'rgba(232,220,203,0.75)', flexShrink: 0,
                    }}>
                      <FuryGlyph cat={p.cat} size={42} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <Mono c={C.ember}>· {t.cats[p.cat]}</Mono>
                      <div><Display s={16} italic w={500}>{window.FURY_pname(p)}</Display></div>
                      <div style={{ marginTop: 8, display: 'flex', alignItems: 'center', gap: 12 }}>
                        <div style={{ display: 'flex', alignItems: 'center', border: `1px solid ${C.line}` }}>
                          <button onClick={() => setQty(p.id, qty - 1)} style={{ background: 'transparent', border: 'none', color: C.hi, cursor: 'pointer', width: 24, height: 22, fontFamily: F.serif, fontSize: 14 }}>−</button>
                          <span style={{ width: 22, textAlign: 'center', fontFamily: F.serif, fontSize: 13, color: C.hi }}>{qty}</span>
                          <button onClick={() => setQty(p.id, qty + 1)} style={{ background: 'transparent', border: 'none', color: C.hi, cursor: 'pointer', width: 24, height: 22, fontFamily: F.serif, fontSize: 14 }}>+</button>
                        </div>
                        <button onClick={() => remove(p.id)} style={{ background: 'transparent', border: 'none', color: C.dim, cursor: 'pointer', fontFamily: F.sans, fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase' }}>{t.remove}</button>
                      </div>
                    </div>
                    <div style={{ textAlign: 'right' }}>
                      <Display s={18} c={C.hi} w={500}>{furyFmt(p.price * qty)}</Display>
                      <div><Sans s={10} c={C.dim}>{t.rub}</Sans></div>
                    </div>
                  </div>
                ))}
              </div>
              <div style={{ padding: '20px 32px 28px', borderTop: `1px solid ${C.lineSoft}` }}>
                <CartRow label={t.cart_subtotal} val={`${furyFmt(subtotal)} ${t.rub}`} />
                <CartRow label={`${t.cart_discount} · ${window.FURY_PROFILE.bonus}`} val={`−${furyFmt(discount)} ${t.rub}`} dim />
                <div style={{ height: 1, background: C.lineSoft, margin: '12px 0' }} />
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                  <Display s={16} italic>{t.cart_total}</Display>
                  <Display s={32} c={C.ember} w={500}>{furyFmt(total)} <span style={{ fontSize: 14, color: C.dim }}>{t.rub}</span></Display>
                </div>
                <div style={{ height: 14 }} />
                {err && (
                  <div style={{ marginBottom: 10, padding: '8px 12px', background: 'rgba(168,40,40,0.15)', border: `1px solid ${C.blood}` }}>
                    <Sans s={11} c={C.bloodHi}>{err}</Sans>
                  </div>
                )}
                {done && (
                  <div style={{ marginBottom: 10, padding: '8px 12px', background: 'rgba(40,80,40,0.15)', border: `1px solid ${C.ember}` }}>
                    <Sans s={11} c={C.ember}>
                      {lang === 'ru' ? 'Покупка оформлена · списано' : 'Purchase completed · charged'} {furyFmt(done.total_paid)} {t.rub}
                    </Sans>
                  </div>
                )}
                <Btn kind="blood" full disabled={pending} onClick={onCheckout}>
                  {pending ? (lang === 'ru' ? 'Обработка…' : 'Processing…') : (t.checkout + ' →')}
                </Btn>
              </div>
            </>
          )}
        </div>
      </>
    );
  }
  function CartRow({ label, val, dim }) {
    return (
      <div style={{ display: 'flex', justifyContent: 'space-between', padding: '3px 0' }}>
        <Sans s={11} c={dim ? C.dim : C.text} upper tracked>{label}</Sans>
        <Sans s={11} c={dim ? C.ember : C.hi}>{val}</Sans>
      </div>
    );
  }

  // ── Login screen (Steam OpenID) ──────────────────────────────────────────
  function LoginScreen({ lang }) {
    const ru = lang === 'ru';
    return (
      <div style={{
        height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: 'linear-gradient(135deg, #1a1410 0%, #0d0a08 60%, #2a1818 100%)',
      }}>
        <div style={{
          maxWidth: 440, padding: '40px 44px', textAlign: 'center',
          background: 'rgba(13,10,8,0.55)', border: `1px solid ${C.line}`, backdropFilter: 'blur(6px)',
        }}>
          <Mono c={C.ember}>· {ru ? 'АВТОРИЗАЦИЯ' : 'AUTHORISATION'}</Mono>
          <div style={{ marginTop: 12 }}>
            <Display s={36} italic w={500}>{ru ? 'Войдите через Steam' : 'Sign in with Steam'}</Display>
          </div>
          <div style={{ marginTop: 14 }}>
            <Sans s={13} c={C.text} style={{ lineHeight: 1.6 }}>
              {ru
                ? 'Профиль игрока, баланс и история покупок привязаны к вашему Steam ID. Авторизация безопасна — пароль не передаётся серверу FURY.'
                : 'Your profile, balance and order history are tied to your Steam ID. Authentication is safe — your password never reaches the FURY server.'}
            </Sans>
          </div>
          <div style={{ marginTop: 28 }}>
            <Btn kind="blood" full onClick={() => window.FURY_API && window.FURY_API.login()}>
              {ru ? 'Войти через Steam →' : 'Continue with Steam →'}
            </Btn>
          </div>
          <div style={{ marginTop: 18 }}>
            <Sans s={10} c={C.dim} upper tracked>
              {ru ? 'Steam OpenID · сессия 30 дней' : 'Steam OpenID · 30-day session'}
            </Sans>
          </div>
        </div>
      </div>
    );
  }

  // ── Profile ──────────────────────────────────────────────────────────────
  function ProfileScreen({ shop }) {
    const { t, profile, lang } = shop;
    if (profile && profile.loggedIn === false) return <LoginScreen lang={lang} />;
    const joined = lang === 'ru' ? profile.joined_ru : profile.joined_en;
    const vipUntil = lang === 'ru' ? profile.vip_until_ru : profile.vip_until_en;
    return (
      <div style={{ overflow: 'auto', height: '100%' }}>
        {/* portrait header */}
        <section style={{
          position: 'relative', padding: '40px 48px', overflow: 'hidden',
          background: 'linear-gradient(135deg, #1a1410 0%, #2a1818 100%)',
          borderBottom: `1px solid ${C.line}`,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 36 }}>
            <div style={{
              width: 140, height: 180, background: furyTone('crimson'),
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              flexShrink: 0, position: 'relative', overflow: 'hidden',
            }}>
              {profile.avatar ? (
                <img
                  src={profile.avatar}
                  alt={profile.name || 'avatar'}
                  referrerPolicy="no-referrer"
                  onError={(e) => { e.currentTarget.style.display = 'none'; }}
                  style={{
                    position: 'absolute', inset: 0, width: '100%', height: '100%',
                    objectFit: 'cover', display: 'block',
                  }}
                />
              ) : (
                // Фоллбек, если у юзера в Steam нет публичной картинки —
                // показываем первую букву ника на тёмном фоне.
                <Display s={84} italic c={C.paper} w={400}>
                  {(profile.name || 'F').slice(0, 1).toUpperCase()}
                </Display>
              )}
              <div style={{
                position: 'absolute', inset: 0, pointerEvents: 'none',
                background: 'radial-gradient(ellipse at 50% 100%, rgba(0,0,0,0.6), transparent 60%)',
              }} />
            </div>
            <div style={{ flex: 1 }}>
              <Mono c={C.ember}>· {t.welcome.toUpperCase()}</Mono>
              <div style={{ marginTop: 8 }}>
                <Display s={54} italic w={400}>{profile.name}</Display>
              </div>
              <div style={{ marginTop: 18, display: 'flex', gap: 36 }}>
                <KV label={t.profile_steam} val={profile.steam} />
                <KV label={t.profile_joined} val={joined} />
                <KV label={t.profile_hours} val={furyFmt(profile.hours)} />
              </div>
            </div>
            <div style={{
              background: 'rgba(13,10,8,0.55)', padding: 22, minWidth: 220,
              border: `1px solid ${C.line}`,
            }}>
              <Mono c={C.ember}>· {t.profile_vip}</Mono>
              <div style={{ marginTop: 6 }}><Display s={26} italic c={C.paper} w={500}>{t.vip_badge}</Display></div>
              <Sans s={10} c={C.dim} upper tracked>{t.profile_vip_active}</Sans>
              <div><Sans s={13} c={C.hi}>{vipUntil}</Sans></div>
              <div style={{ marginTop: 18, paddingTop: 14, borderTop: `1px solid ${C.lineSoft}` }}>
                <button
                  onClick={async () => {
                    if (!window.FURY_API) return;
                    await window.FURY_API.logout();
                    // После logout сессионная кука удалится и /api/me вернёт loggedIn:false →
                    // ProfileScreen сам отрисует LoginScreen.
                  }}
                  style={{
                    background: 'transparent', border: `1px solid ${C.line}`, cursor: 'pointer',
                    padding: '8px 14px', width: '100%', color: C.hi,
                    fontFamily: F.sans, fontSize: 10, letterSpacing: '0.18em',
                    textTransform: 'uppercase', fontWeight: 600,
                  }}
                  title={lang === 'ru' ? 'Выйти из Steam-аккаунта' : 'Sign out from Steam'}>
                  {lang === 'ru' ? '↪ Выйти из Steam' : '↪ Sign out'}
                </button>
              </div>
            </div>
          </div>
        </section>

        <section style={{ padding: '36px 48px' }}>
          {/* stats row */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 24 }}>
            <Stat label={t.balance} val={furyFmt(profile.balance)} suffix={t.rub} />
            <Stat label={t.bonus} val={`+${profile.bonus}`} accent={C.ember} />
            <Stat label="K/D" val="2.18" />
            <Stat label="RANK" val="#42" accent={C.blood} />
          </div>

          {/* bonus code redeem */}
          <BonusCodeRedeem lang={lang} />


          {/* inventory + history */}
          <div style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 32, marginTop: 36 }}>
            <div>
              <SectionHead label={t.profile_inventory} />
              <div style={{ marginTop: 16, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
                {profile.inventory.map((it, i) => {
                  const p = window.FURY_PRODUCTS.find((x) => x.id === it.id);
                  if (!p) return null;
                  return (
                    <div key={i} style={{ background: C.panel2, position: 'relative' }}>
                      <div style={{ height: 90, background: furyTone(p.tone), display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'rgba(232,220,203,0.7)' }}>
                        <FuryGlyph cat={p.cat} size={50} />
                      </div>
                      <div style={{ padding: 10 }}>
                        <Sans s={11} c={C.hi}>{window.FURY_pname(p)}</Sans>
                      </div>
                      <div style={{ position: 'absolute', top: 6, right: 6, background: C.blood, color: '#fff', fontFamily: F.sans, fontSize: 10, padding: '1px 6px', fontWeight: 700 }}>×{it.qty}</div>
                    </div>
                  );
                })}
              </div>
            </div>
            <div>
              <SectionHead label={t.profile_history} />
              <div style={{ marginTop: 12 }}>
                {profile.history.map((h, i) => {
                  const items = lang === 'ru' ? h.items : h.items_en;
                  return (
                    <div key={i} style={{
                      display: 'flex', alignItems: 'center', gap: 16, padding: '14px 0',
                      borderBottom: i < profile.history.length - 1 ? `1px solid ${C.lineSoft}` : 'none',
                    }}>
                      <Display s={14} italic c={C.dim} style={{ width: 70 }}>{lang === 'ru' ? h.date_ru : h.date_en}</Display>
                      <Sans s={12} c={C.text} style={{ flex: 1 }}>{items.join(' · ')}</Sans>
                      <Display s={16} c={C.hi}>{furyFmt(h.total)} <span style={{ color: C.dim, fontSize: 11, fontFamily: F.sans }}>{t.rub}</span></Display>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        </section>
      </div>
    );
  }
  function KV({ label, val }) {
    return (
      <div>
        <Sans s={10} c={C.dim} upper tracked>{label}</Sans>
        <div style={{ marginTop: 2 }}><Sans s={13} c={C.hi}>{val}</Sans></div>
      </div>
    );
  }
  function Stat({ label, val, suffix, accent }) {
    return (
      <div style={{ borderLeft: `1px solid ${C.line}`, paddingLeft: 18 }}>
        <Sans s={10} c={C.dim} upper tracked>{label}</Sans>
        <div style={{ marginTop: 6 }}>
          <Display s={36} c={accent || C.hi} w={500}>{val}</Display>
          {suffix && <Sans s={12} c={C.dim} style={{ marginLeft: 4 }}>{suffix}</Sans>}
        </div>
      </div>
    );
  }
  function SectionHead({ label }) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <Display s={20} italic w={500}>{label}</Display>
        <div style={{ flex: 1, height: 1, background: C.line }} />
      </div>
    );
  }

  // ── Servers ──────────────────────────────────────────────────────────────
  function ServersScreen({ shop }) {
    const { t, servers, lang, setView, setServerId, serverId } = shop;
    return (
      <div style={{ overflow: 'auto', height: '100%' }}>
        <section style={{
          padding: '48px 48px 32px',
          background: 'linear-gradient(180deg, #1a1410 0%, transparent 100%)',
        }}>
          <Mono c={C.ember}>· {t.nav_servers.toUpperCase()}</Mono>
          <div style={{ marginTop: 8 }}><Display s={48} italic w={400}>{t.server_pick}</Display></div>
        </section>
        <div style={{ padding: '0 48px 48px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24 }}>
          {servers.map((s) => {
            const sel = s.id === serverId;
            const map = lang === 'ru' ? s.map_ru : s.map_en;
            return (
              <article key={s.id} style={{
                position: 'relative', background: C.panel, overflow: 'hidden',
                boxShadow: sel ? `inset 0 0 0 1.5px ${C.ember}, 0 0 0 1px ${C.ember}` : `inset 0 0 0 1px ${C.lineSoft}`,
                cursor: 'pointer',
              }} onClick={() => setServerId(s.id)}>
                {/* image strip */}
                <div style={{
                  height: 120, background: furyTone(s.id === 'fury-3' ? 'frost' : s.id === 'fury-4' ? 'frost' : 'olive'),
                  position: 'relative', overflow: 'hidden',
                }}>
                  <div style={{
                    position: 'absolute', inset: 0,
                    background: 'linear-gradient(180deg, transparent 0%, rgba(13,10,8,0.7) 100%)',
                  }} />
                  {s.full && (
                    <div style={{
                      position: 'absolute', top: 12, right: 12, background: C.blood,
                      color: '#fff', padding: '4px 12px', fontFamily: F.sans, fontSize: 10,
                      letterSpacing: '0.2em', textTransform: 'uppercase', fontWeight: 600,
                    }}>{t.server_full}</div>
                  )}
                  {sel && (
                    <div style={{
                      position: 'absolute', top: 12, left: 12, background: C.ember,
                      color: '#1a1208', padding: '4px 12px', fontFamily: F.sans, fontSize: 10,
                      letterSpacing: '0.2em', textTransform: 'uppercase', fontWeight: 600,
                    }}>● {t.online}</div>
                  )}
                  <div style={{
                    position: 'absolute', bottom: 14, left: 18, right: 18,
                  }}>
                    <Display s={26} italic c={C.paper} w={500}>{s.name}</Display>
                  </div>
                </div>
                <div style={{ padding: '20px 22px 22px' }}>
                  <Sans s={11} c={C.dim} upper tracked>{map} · {s.mods}</Sans>
                  <div style={{ marginTop: 14, display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 14 }}>
                    <div><Sans s={9} c={C.dim} upper tracked>{t.online}</Sans><div><Display s={20} c={C.hi}>{s.online}<span style={{ color: C.dim, fontSize: 12 }}>/{s.max}</span></Display></div></div>
                    <div><Sans s={9} c={C.dim} upper tracked>{t.ping}</Sans><div><Display s={20} c={C.hi}>{s.ping}<span style={{ color: C.dim, fontSize: 10 }}>ms</span></Display></div></div>
                    <div><Sans s={9} c={C.dim} upper tracked>{t.map}</Sans><div><Display s={16} italic c={C.hi}>{map}</Display></div></div>
                  </div>
                  <div style={{ marginTop: 14, display: 'flex', alignItems: 'center', gap: 8 }}>
                    {s.tags.map((tag) => (
                      <span key={tag} style={{
                        border: `1px solid ${C.line}`, color: C.text, padding: '4px 10px',
                        fontFamily: F.sans, fontSize: 9, letterSpacing: '0.16em',
                        textTransform: 'uppercase', borderRadius: 999,
                      }}>{tag}</span>
                    ))}
                    <div style={{ flex: 1 }} />
                    <Btn kind={sel ? 'blood' : 'ghost'} disabled={s.full}
                      onClick={(e) => { e.stopPropagation(); setServerId(s.id); setView('shop'); }}
                      style={{ padding: '10px 18px', fontSize: 10 }}>
                      {s.full ? t.server_full : t.server_join} →
                    </Btn>
                  </div>
                </div>
              </article>
            );
          })}
        </div>
      </div>
    );
  }

  // ── Shop main ────────────────────────────────────────────────────────────
  function ShopScreen({ shop }) {
    const { t, products, add, cart, select, lang } = shop;
    return (
      <div style={{ flex: 1, overflow: 'auto' }}>
        <Hero shop={shop} />
        <FilterRail shop={shop} />
        <div style={{ padding: '32px 48px 48px' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 18, marginBottom: 22 }}>
            <Display s={28} italic w={400}>{t.cats[shop.cat]}</Display>
            <div style={{ flex: 1, height: 1, background: C.line }} />
            <Sans s={11} c={C.dim} upper tracked>{products.length} {shop.lang === 'ru' ? 'товаров' : 'items'}</Sans>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 28 }}>
            {products.map((p) => <ProductCard key={p.id} p={p} t={t} inCart={cart[p.id]} onAdd={add} onOpen={select} />)}
          </div>
        </div>
        <SiteFooter lang={lang} />
      </div>
    );
  }

  // ── Detail modal ─────────────────────────────────────────────────────────
  function DetailModal({ shop }) {
    const { t, selected, closeSelected, add, setCartOpen, buyQty, setBuyQty, cart, lang } = shop;
    if (!selected) return null;
    const p = selected;
    const total = p.price * Math.max(1, buyQty);
    return (
      <>
        <div onClick={closeSelected} style={{
          position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.78)', zIndex: 60, backdropFilter: 'blur(4px)',
        }} />
        <div style={{
          position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-50%)',
          width: 620, background: C.panel, zIndex: 61, color: C.text,
          border: `1px solid ${C.line}`, boxShadow: '0 40px 100px rgba(0,0,0,0.6)',
          display: 'flex', flexDirection: 'column', maxHeight: 800,
        }}>
          {/* edition strip */}
          <div style={{
            padding: '12px 28px', borderBottom: `1px solid ${C.lineSoft}`,
            display: 'flex', alignItems: 'center',
          }}>
            <Mono c={C.dim}>FURY · № {String(window.FURY_PRODUCTS.indexOf(p) + 1).padStart(3, '0')} · {t.cats[p.cat].toUpperCase()}</Mono>
            <div style={{ flex: 1 }} />
            <button onClick={closeSelected} style={{
              background: 'transparent', border: 'none', color: C.dim, cursor: 'pointer',
              fontFamily: F.serif, fontSize: 24, lineHeight: 1, padding: 0,
            }}>✕</button>
          </div>
          {/* hero image */}
          <div style={{ position: 'relative' }}>
            <CardArt p={p} h={260} />
            <Badge kind={p.badge} t={t} />
          </div>
          {/* title overlapping */}
          <div style={{ padding: '24px 28px 0' }}>
            <div style={{
              marginTop: -54, marginBottom: 16,
              background: C.bg, padding: '14px 18px', display: 'inline-block',
              border: `1px solid ${C.line}`,
            }}>
              <Display s={32} italic w={500} c={C.hi}>{window.FURY_pname(p)}</Display>
            </div>
            <div style={{ color: C.text, fontFamily: F.sans, fontSize: 13, lineHeight: 1.6 }}>
              {window.FURY_desc(p)}
            </div>
            <div style={{ marginTop: 18 }}>
              <Mono c={C.ember}>· {lang === 'ru' ? 'СОДЕРЖИМОЕ' : 'CONTENTS'}</Mono>
              <div style={{ marginTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px 16px' }}>
                {p.gear.map((g, i) => (
                  <div key={i} style={{ display: 'flex', gap: 8, alignItems: 'baseline', padding: '4px 0', borderBottom: `1px dotted ${C.lineSoft}` }}>
                    <Sans s={12} c={C.text} style={{ flex: 1 }}>{g}</Sans>
                    <Mono c={C.ember}>✓</Mono>
                  </div>
                ))}
              </div>
            </div>
          </div>
          {/* footer */}
          <div style={{
            padding: '20px 28px 24px', marginTop: 'auto',
            borderTop: `1px solid ${C.lineSoft}`, background: C.bg,
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
              <div>
                <Sans s={10} c={C.dim} upper tracked>{t.quantity}</Sans>
                <div style={{ display: 'flex', alignItems: 'center', marginTop: 4, border: `1px solid ${C.line}` }}>
                  <button onClick={() => setBuyQty(Math.max(1, buyQty - 1))} style={{ background: 'transparent', border: 'none', color: C.hi, cursor: 'pointer', width: 30, height: 32, fontFamily: F.serif, fontSize: 16 }}>−</button>
                  <input value={buyQty} onChange={(e) => setBuyQty(Math.max(1, Number(e.target.value) || 1))}
                    style={{ width: 42, height: 32, background: 'transparent', border: 'none', outline: 'none', color: C.hi, textAlign: 'center', fontFamily: F.serif, fontSize: 16 }} />
                  <button onClick={() => setBuyQty(buyQty + 1)} style={{ background: 'transparent', border: 'none', color: C.hi, cursor: 'pointer', width: 30, height: 32, fontFamily: F.serif, fontSize: 16 }}>+</button>
                </div>
              </div>
              <div style={{ flex: 1 }} />
              <div style={{ textAlign: 'right' }}>
                <Sans s={10} c={C.dim} upper tracked>{t.cart_total}</Sans>
                <div><Display s={32} c={C.ember} w={500}>{furyFmt(total)} <span style={{ fontSize: 14, color: C.dim }}>{t.rub}</span></Display></div>
              </div>
            </div>
            <div style={{ display: 'flex', gap: 10, marginTop: 14 }}>
              <Btn kind="ghost" onClick={closeSelected} style={{ flex: 1 }}>{lang === 'ru' ? 'Закрыть' : 'Close'}</Btn>
              <Btn kind="blood" onClick={() => { for (let i = 0; i < buyQty; i++) add(p.id); closeSelected(); setCartOpen(true); }} style={{ flex: 1.4 }}>
                {t.buy_now} →
              </Btn>
            </div>
          </div>
        </div>
      </>
    );
  }

  // ── Root ─────────────────────────────────────────────────────────────────
  function CinematicApp({ fullscreen = false }) {
    const shop = useShop('shop');
    const rootStyle = fullscreen
      ? { width: '100%', height: '100vh', position: 'relative', overflow: 'hidden' }
      : { width: 1440, height: 900, position: 'relative', overflow: 'hidden' };
    return (
      <div data-screen-label="C · Cinematic" style={{
        ...rootStyle, background: C.bg, color: C.text,
        fontFamily: F.sans, display: 'flex', flexDirection: 'column',
      }}>
        <Header shop={shop} />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          {shop.view === 'shop' && <ShopScreen shop={shop} />}
          {shop.view === 'profile' && <ProfileScreen shop={shop} />}
          {shop.view === 'servers' && <ServersScreen shop={shop} />}
          {shop.view === 'admin' && <AdminScreen shop={shop} />}
        </div>
        <CartDrawer shop={shop} />
        <DetailModal shop={shop} />
      </div>
    );
  }

  window.CinematicApp = CinematicApp;
})();
