// THE EPIZODE — shared layout & theme system.
// Header, footer, theme toggle, ticket — used by every page.

const EPZ_THEME = {
  dark: {
    bg: '#14110E',
    bgAlt: '#0A0907',
    bgFeatured: '#1C1815',
    text: '#EFE7D6',
    textSoft: 'rgba(239,231,214,0.78)',
    textMute: 'rgba(239,231,214,0.55)',
    textDim: 'rgba(239,231,214,0.4)',
    border: 'rgba(239,231,214,0.18)',
    borderSoft: 'rgba(239,231,214,0.10)',
    accent: '#6E1A21',
    accentInk: '#D2C7B0',
    accentText: '#EFE7D6',
    accentBg: 'rgba(110,26,33,0.4)',
    saveText: '#CBA968',
    clubBg: '#241C17',
    ticketBg: '#6E1A21',
    ticketFg: '#EFE7D6',
    ticketCutout: '#14110E',
    btnPrimary: '#EFE7D6',
    btnPrimaryFg: '#14110E',
    btnSecondaryBorder: 'rgba(239,231,214,0.5)',
    filmStrip: '#000',
    filmGap: '#2a1a18',
    scanline: 'rgba(239,231,214,0.18)',
    cornerCrop: 'rgba(239,231,214,0.85)',
    grainBlend: 'overlay',
    grainOpacity: 0.16,
    placeholderTone: 'dark',
  },
  light: {
    bg: '#F6F1E4',
    bgAlt: '#EBE3CE',
    bgFeatured: '#FBF7EC',
    text: '#14110E',
    textSoft: 'rgba(20,17,14,0.72)',
    textMute: 'rgba(20,17,14,0.5)',
    textDim: 'rgba(20,17,14,0.35)',
    border: 'rgba(20,17,14,0.18)',
    borderSoft: 'rgba(20,17,14,0.10)',
    accent: '#6E1A21',
    accentInk: '#6E1A21',
    accentText: '#EFE7D6',
    accentBg: 'rgba(110,26,33,0.08)',
    saveText: '#6E1A21',
    clubBg: '#1C1815',
    ticketBg: '#6E1A21',
    ticketFg: '#EFE7D6',
    ticketCutout: '#F6F1E4',
    btnPrimary: '#6E1A21',
    btnPrimaryFg: '#EFE7D6',
    btnSecondaryBorder: 'rgba(20,17,14,0.4)',
    filmStrip: '#1C1815',
    filmGap: '#2a1a18',
    scanline: 'rgba(20,17,14,0.10)',
    cornerCrop: 'rgba(20,17,14,0.55)',
    grainBlend: 'multiply',
    grainOpacity: 0.10,
    placeholderTone: 'light',
  },
};

// ─── Hook: read theme from localStorage, expose tokens ───────────────────────
function useEpzTheme() {
  const [theme, setTheme] = React.useState(() => {
    if (typeof window === 'undefined') return 'light';
    return localStorage.getItem('epz-theme') || 'light';
  });
  React.useEffect(() => {
    try { localStorage.setItem('epz-theme', theme); } catch (e) {}
  }, [theme]);

  // Listen for cross-tab + same-page changes to stay in sync if user toggles
  // on another tab / another component.
  React.useEffect(() => {
    const onStorage = (e) => {
      if (e.key === 'epz-theme' && e.newValue && e.newValue !== theme) {
        setTheme(e.newValue);
      }
    };
    window.addEventListener('storage', onStorage);
    return () => window.removeEventListener('storage', onStorage);
  }, [theme]);

  return [theme, setTheme, EPZ_THEME[theme]];
}

// ─── i18n: global language + translate helper ────────────────────────────────
// Source language is Russian; the dictionary (EPZ_I18N, defined in i18n.jsx) maps
// a Russian source string → its English translation. epzT(ru) returns the EN
// string when language is EN, otherwise the Russian source unchanged. Missing
// keys degrade gracefully to the Russian source.
let EPZ_LANG = (typeof window !== 'undefined' && localStorage.getItem('epz-lang')) || 'RU';
function epzT(ru) {
  if (EPZ_LANG !== 'EN') return ru;
  const dict = (typeof EPZ_I18N !== 'undefined') ? EPZ_I18N : null;
  if (dict && Object.prototype.hasOwnProperty.call(dict, ru)) return dict[ru];
  return ru;
}
function epzSetLang(lang) {
  EPZ_LANG = lang;
  try { localStorage.setItem('epz-lang', lang); } catch (e) {}
  try { window.dispatchEvent(new CustomEvent('epz-lang', { detail: { lang } })); } catch (e) {}
}
function epzIsEN() { return EPZ_LANG === 'EN'; }
function useEpzLang() {
  const [lang, setLangState] = React.useState(EPZ_LANG);
  React.useEffect(() => {
    const onLang = () => setLangState(EPZ_LANG);
    const onStorage = (e) => { if (e.key === 'epz-lang' && e.newValue) { EPZ_LANG = e.newValue; setLangState(e.newValue); } };
    window.addEventListener('epz-lang', onLang);
    window.addEventListener('storage', onStorage);
    return () => { window.removeEventListener('epz-lang', onLang); window.removeEventListener('storage', onStorage); };
  }, []);
  const setLang = (l) => { epzSetLang(l); };
  return [lang, setLang, epzT];
}

// ─── Store: cart + wishlist in localStorage (no account needed) ──────────────
// Lightweight global store. Persists to localStorage and notifies via a custom
// event so the header badges update from anywhere on the page.
const EPZ_CART_KEY = 'epz-cart';
const EPZ_WISH_KEY = 'epz-wish';

function epzReadStore(key) {
  try { return JSON.parse(localStorage.getItem(key) || '[]'); } catch (e) { return []; }
}
function epzWriteStore(key, val) {
  try { localStorage.setItem(key, JSON.stringify(val)); } catch (e) {}
  try { window.dispatchEvent(new CustomEvent('epz-store', { detail: { key } })); } catch (e) {}
}

// Cart line key = article id + variant (so silk-top ≠ silk-set).
function epzCartLineKey(id, variant) { return id + (variant ? '::' + variant : ''); }

function epzAddToCart(id, { variant = null, size = null, qty = 1 } = {}) {
  const cart = epzReadStore(EPZ_CART_KEY);
  const k = epzCartLineKey(id, variant);
  const existing = cart.find((c) => epzCartLineKey(c.id, c.variant) === k && c.size === size);
  if (existing) existing.qty += qty;
  else cart.push({ id, variant, size, qty });
  epzWriteStore(EPZ_CART_KEY, cart);
  try { localStorage.setItem('epz-cart-touched', '1'); } catch (e) {}
  try { window.dispatchEvent(new CustomEvent('epz-cart-open', { detail: { id, variant, size } })); } catch (e) {}
  return cart;
}
function epzToggleWish(id) {
  let wish = epzReadStore(EPZ_WISH_KEY);
  if (wish.includes(id)) wish = wish.filter((w) => w !== id);
  else wish.push(id);
  epzWriteStore(EPZ_WISH_KEY, wish);
  return wish;
}

// ── База: добавление в избранное всегда с выбором размера ──
const EPZ_WISH_SIZE_KEY = 'epz-wish-sizes';
function epzWishSizeGet(id) { try { return (JSON.parse(localStorage.getItem(EPZ_WISH_SIZE_KEY) || '{}'))[id] || null; } catch (e) { return null; } }
function epzWishSizeSet(id, size) { try { const m = JSON.parse(localStorage.getItem(EPZ_WISH_SIZE_KEY) || '{}'); if (size) m[id] = size; else delete m[id]; localStorage.setItem(EPZ_WISH_SIZE_KEY, JSON.stringify(m)); } catch (e) {} }
// Составные вещи: у комплектов размер выбирается ОТДЕЛЬНО для каждой части (верх/низ, платье/тренч)
function epzWishParts(a) {
  const G = { 'Топ': 'размер топа', 'Брюки': 'размер брюк', 'Платье': 'размер платья', 'Тренч': 'размер тренча' };
  const lab = (t) => G[t] || ('размер · ' + t.toLowerCase());
  if (a.bundleParts) {
    return a.bundleParts.map((p) => {
      const pa = (typeof EPZ_ARTICLES !== 'undefined') ? EPZ_ARTICLES.find((x) => x.id === p.id) : null;
      const t = p.variant === 'top' ? 'Топ' : p.variant === 'bottom' ? 'Брюки' : (pa && pa.type) || 'Вещь';
      return { label: lab(t), short: t, sizes: p.size ? [p.size] : (pa && pa.sizes) || ['ONE SIZE'] };
    });
  }
  if (a.variants) return [
    { label: lab('Топ'), short: 'Топ', sizes: a.sizes || ['ONE SIZE'] },
    { label: lab('Брюки'), short: 'Брюки', sizes: a.sizes || ['ONE SIZE'] },
  ];
  return null;
}

// Единая точка добавления/удаления: если размеров несколько — сначала модалка выбора размера
function epzWishAdd(a) {
  if (!a) return;
  const id = a.wishId || a.id;
  if (epzReadStore(EPZ_WISH_KEY).includes(id)) { epzToggleWish(id); epzWishSizeSet(id, null); return; }
  const parts = epzWishParts(a);
  if (parts) {
    if (parts.every((p) => p.sizes.length === 1)) {
      epzWishSizeSet(id, parts.map((p) => `${p.short.toLowerCase()} ${p.sizes[0]}`).join(' · '));
      epzToggleWish(id);
      try { epzToast(epzT('добавлено в избранное')); } catch (e) {}
      return;
    }
    try { window.dispatchEvent(new CustomEvent('epz-wish-size', { detail: { id, title: a.short || a.title, parts } })); } catch (e) {}
    return;
  }
  const sizes = a.sizes || ['ONE SIZE'];
  if (sizes.length > 1) {
    try { window.dispatchEvent(new CustomEvent('epz-wish-size', { detail: { id, title: a.short || a.title, sizes } })); } catch (e) {}
    return;
  }
  epzWishSizeSet(id, sizes[0]);
  epzToggleWish(id);
  try { epzToast(epzT('добавлено в избранное')); } catch (e) {}
}

// Модалка выбора размера при добавлении в избранное — рендерится в шапке на всех страницах
function EpzWishSizeModal({ T }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const [req, setReq] = React.useState(null);
  const [sel, setSel] = React.useState({});
  React.useEffect(() => {
    const fn = (e) => {
      setReq(e.detail);
      // части с единственным размером выбраны сразу
      const pre = {};
      (e.detail.parts || []).forEach((p, i) => { if (p.sizes.length === 1) pre[i] = p.sizes[0]; });
      setSel(pre);
    };
    window.addEventListener('epz-wish-size', fn);
    return () => window.removeEventListener('epz-wish-size', fn);
  }, []);
  if (!req) return null;
  const finish = (sizeLabel) => {
    epzWishSizeSet(req.id, sizeLabel);
    const already = epzReadStore(EPZ_WISH_KEY).includes(req.id);
    if (!already) epzToggleWish(req.id);
    try { epzToast(epzT('добавлено в избранное') + ' · ' + sizeLabel); } catch (e) {}
    setReq(null); setSel({});
  };
  const pick = (s) => finish(s);
  const pickPart = (i, s) => {
    const next = { ...sel, [i]: s };
    setSel(next);
    if (req.parts.every((p, k) => next[k])) {
      finish(req.parts.map((p, k) => `${epzT(p.short).toLowerCase()} ${next[k]}`).join(' · '));
    }
  };
  const btnStyle = (active) => ({
    minWidth: 56, padding: '13px 10px', cursor: 'pointer',
    background: active ? T.accent : 'transparent', color: active ? T.accentText : T.text,
    border: `1px solid ${active ? T.accent : T.border}`,
    fontFamily: F.mono, fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase',
    transition: 'background 0.15s, color 0.15s, border-color 0.15s'
  });
  return (
    <div onClick={() => setReq(null)} style={{ position: 'fixed', inset: 0, zIndex: 300, background: 'rgba(10,9,8,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ position: 'relative', background: T.bg, color: T.text, border: `1px solid ${T.accent}`, padding: '26px 28px 26px', width: 'min(420px, 94vw)', textAlign: 'center', boxSizing: 'border-box' }}>
        <button onClick={() => setReq(null)} aria-label={epzT('Закрыть')} style={{ position: 'absolute', top: 10, right: 14, background: 'transparent', border: 0, color: 'inherit', fontSize: 16, cursor: 'pointer', fontFamily: F.mono, opacity: 0.6 }}>✕</button>
        <div style={{ fontFamily: F.mono, fontSize: 9, letterSpacing: '0.2em', textTransform: 'uppercase', color: T.accentInk }}>{epzT('ваш размер')}</div>
        <div style={{ fontFamily: F.display, fontSize: 24, lineHeight: 1.15, marginTop: 8 }}>{epzT(req.title)}</div>
        {req.parts ? (
          <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div style={{ fontFamily: F.body, fontSize: 12.5, lineHeight: 1.5, opacity: 0.65, letterSpacing: 0, textTransform: 'none' }}>{epzT('Размер можно выбрать отдельно для каждой части комплекта')}</div>
            {req.parts.map((p, i) => (
              <div key={i}>
                <div style={{ fontFamily: F.mono, fontSize: 9, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.55, marginBottom: 9 }}>{epzT(p.label)}</div>
                <div style={{ display: 'flex', gap: 6, justifyContent: 'center', flexWrap: 'wrap' }}>
                  {p.sizes.map((s) => (
                    <button key={s} onClick={() => p.sizes.length > 1 && pickPart(i, s)} className="epz-wish-size-btn" style={{ ...btnStyle(sel[i] === s), cursor: p.sizes.length > 1 ? 'pointer' : 'default', opacity: p.sizes.length > 1 || sel[i] === s ? 1 : 0.6 }}>{s}</button>
                  ))}
                </div>
              </div>
            ))}
          </div>
        ) : (
          <div style={{ marginTop: 18, display: 'flex', gap: 6, justifyContent: 'center', flexWrap: 'wrap' }}>
            {req.sizes.map((s) => (
              <button key={s} onClick={() => pick(s)} className="epz-wish-size-btn" style={btnStyle(false)}>{s}</button>
            ))}
          </div>
        )}
        <style>{`.epz-wish-size-btn:hover { background: ${T.accent}; color: ${T.accentText}; border-color: ${T.accent}; }`}</style>
      </div>
    </div>
  );
}

// Hook: live counts + lists that re-render on any store change (this tab or others).
function useEpzStore() {
  const [cart, setCart] = React.useState(() => epzReadStore(EPZ_CART_KEY));
  const [wish, setWish] = React.useState(() => epzReadStore(EPZ_WISH_KEY));
  React.useEffect(() => {
    const sync = () => { setCart(epzReadStore(EPZ_CART_KEY)); setWish(epzReadStore(EPZ_WISH_KEY)); };
    window.addEventListener('epz-store', sync);
    window.addEventListener('storage', sync);
    return () => { window.removeEventListener('epz-store', sync); window.removeEventListener('storage', sync); };
  }, []);
  const cartCount = cart.reduce((s, c) => s + (c.qty || 1), 0);
  return {
    cart, wish, cartCount, wishCount: wish.length,
    addToCart: epzAddToCart, toggleWish: epzToggleWish,
    setCart: (v) => { epzWriteStore(EPZ_CART_KEY, v); },
  };
}

// ─── Site pages metadata ─────────────────────────────────────────────────────
const EPZ_PAGES = [
  { key: 'archive',   label: 'Главная',     href: '/' },
  { key: 'episodes',  label: 'Каталог',     href: '/catalog/' },
  { key: 'manifesto', label: 'Концепция',   href: '/manifesto/' },
  { key: 'lookbook',  label: 'Кампейн',     href: '/lookbook/' },
  { key: 'club',      label: 'За кулисами', href: '/#club' },
  { key: 'shipping',  label: 'Доставка',    href: '/delivery/' },
  { key: 'contact',   label: 'Контакты',    href: '/contacts/' },
];

// ─── Theme toggle ────────────────────────────────────────────────────────────
function ThemeToggle({ theme, setTheme }) {
  const F = EPZ_FONTS;
  useEpzLang();
  return (
    <button
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
      aria-label={`Сменить тему · сейчас ${theme === 'dark' ? 'тёмная' : 'светлая'}`}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        background: 'transparent', color: 'inherit',
        border: 0, padding: 4, cursor: 'pointer', opacity: 0.85,
      }}
      aria-label={theme === 'dark' ? 'Светлая тема' : 'Тёмная тема'}
    >
      <span style={{
        display: 'inline-flex', position: 'relative',
        width: 40, height: 19, borderRadius: 19,
        border: '1px solid currentColor',
        alignItems: 'center', flexShrink: 0,
      }}>
        {/* солнце — слева, залитое */}
        <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" style={{ position: 'absolute', left: 4, opacity: theme === 'dark' ? 0.45 : 1 }}>
          <circle cx="12" cy="12" r="4.5" />
          <path d="M12 2v2.2M12 19.8V22M2 12h2.2M19.8 12H22M4.9 4.9l1.6 1.6M17.5 17.5l1.6 1.6M19.1 4.9l-1.6 1.6M6.5 17.5l-1.6 1.6" />
        </svg>
        {/* луна — справа, залитая */}
        <svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor" style={{ position: 'absolute', right: 4, opacity: theme === 'dark' ? 1 : 0.45 }}>
          <path d="M20 13.5A8 8 0 0 1 10.5 4 8 8 0 1 0 20 13.5z" />
        </svg>
        {/* бегунок */}
        <span style={{
          position: 'absolute',
          left: theme === 'dark' ? 23 : 2,
          top: 2,
          width: 13, height: 13, borderRadius: 13,
          background: 'currentColor',
          transition: 'left 0.25s ease',
        }} />
      </span>
    </button>
  );
}

// ─── Themed ticket ───────────────────────────────────────────────────────────
function EpzTicketThemed({ children, T, style = {} }) {
  const F = EPZ_FONTS;
  return (
    <div style={{
      position: 'relative',
      background: T.ticketBg, color: T.ticketFg,
      padding: '18px 22px 22px',
      fontFamily: F.mono, fontSize: 11,
      letterSpacing: '0.14em', textTransform: 'uppercase',
      transition: 'background 0.3s ease, color 0.3s ease',
      ...style,
    }}>
      <div style={{
        position: 'absolute', left: 0, right: 0, top: '62%',
        borderTop: `1.5px dashed ${T.ticketFg}`, opacity: 0.4,
      }} />
      <div style={{
        position: 'absolute', top: '62%', left: -8,
        width: 16, height: 16, borderRadius: 16,
        background: T.ticketCutout, transform: 'translateY(-50%)',
        transition: 'background 0.3s ease',
      }} />
      <div style={{
        position: 'absolute', top: '62%', right: -8,
        width: 16, height: 16, borderRadius: 16,
        background: T.ticketCutout, transform: 'translateY(-50%)',
        transition: 'background 0.3s ease',
      }} />
      {children}
    </div>
  );
}

// ─── Language switch ─────────────────────────────────────────────────────────
function LangSwitch({ T }) {
  const F = EPZ_FONTS;
  const [lang, setLang] = useEpzLang();
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      fontFamily: F.mono, fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase',
    }}>
      {['RU', 'EN'].map((l, i) => (
        <React.Fragment key={l}>
          {i > 0 && <span style={{ opacity: 0.35 }}>/</span>}
          <button
            onClick={() => setLang(l)}
            style={{
              background: 'transparent', color: 'inherit', border: 0, padding: '2px 0',
              fontFamily: F.mono, fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase',
              cursor: 'pointer', opacity: lang === l ? 1 : 0.45,
            }}
          >{l}</button>
        </React.Fragment>
      ))}
    </div>
  );
}

// ─── Slide-out menu drawer ───────────────────────────────────────────────────
const EPZ_MENU_PRIMARY = [
  ['Каталог', '/catalog/'],
];
const EPZ_MENU_EPISODES = [
  ['Эльвира', '002', '/episode-002/'],
  ['Катрин', '001', '/episode-001/'],
  ['Хацумомо', '003', '/episode-003/'],
  ['Тони', '004', '/episode-004/'],
];
const EPZ_MENU_SECONDARY = [
  ['О бренде', '/manifesto/'],
  ['Уход за изделием', '/care/'],
  ['Доставка и возврат', '/delivery/'],
  ['Гарантия', '/delivery/?tab=warranty'], ['Вопросы', '/delivery/?tab=faq'],
];
const EPZ_MENU_TILES = [
  ['Эпизоды', '/assets/katrin-set.jpg', '/catalog/', 'center 14%'],
  ['О бренде', '/assets/hero-hatsumomo.jpg', '/manifesto/', 'center 20%'],
];
function EpzMenuDrawer({ open, onClose, T, current }) {
  const F = EPZ_FONTS;
  useEpzLang();
  return (
    <>
      <style>{`
        .epz-mega-row { font-family: ${EPZ_FONTS.display}; font-weight: 300; font-size: 34px; line-height: 1.1; }
        .epz-mega-row:hover, .epz-mega-ep:hover { color: #6E1A21; }
        .epz-mega-tile:hover .epz-mega-im { transform: scale(1.05); }
        @media (max-width: 860px) {
          .epz-mega-body { grid-template-columns: 1fr !important; }
          .epz-mega-tiles { grid-template-columns: 1fr 1fr !important; }
        }
      `}</style>
      {/* Backdrop */}
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 40, background: 'rgba(0,0,0,0.4)',
        opacity: open ? 1 : 0, pointerEvents: open ? 'auto' : 'none', transition: 'opacity 0.35s ease',
      }} />
      {/* Full-width mega-menu (выезжает сверху, под шапкой) */}
      <div className="epz-mega" style={{
        position: 'fixed', top: 0, left: 0, right: 0, zIndex: 45,
        background: T.bg, color: T.text, borderBottom: `1px solid ${T.border}`,
        transform: open ? 'translateY(0)' : 'translateY(-101%)',
        transition: 'transform 0.45s cubic-bezier(.7,0,.2,1)',
        boxShadow: open ? '0 40px 90px rgba(0,0,0,0.3)' : 'none',
        paddingTop: 72,
      }}>
        <div className="epz-mega-body" style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr 1.5fr', minHeight: 'min(560px, 64vh)' }}>
          {/* primary — как «покупателям»: метка сверху + кликабельные строки */}
          <div style={{ padding: '46px 48px', display: 'flex', flexDirection: 'column' }}>
            <div style={{ fontFamily: F.mono, fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 600, marginBottom: 18 }}>{epzT('каталог')}</div>
            <a href="/catalog/" className="epz-mega-ep" style={{ display: 'block', color: 'inherit', textDecoration: 'none', padding: '5px 0', fontFamily: F.display, fontSize: 28, fontWeight: 300, lineHeight: 1.15 }}>{epzT('Все изделия')}</a>
            {EPZ_MENU_EPISODES.map(([l, num, href]) => (
              <a key={l} href={href} className="epz-mega-ep" style={{ display: 'block', color: 'inherit', textDecoration: 'none', padding: '5px 0', fontFamily: F.display, fontSize: 28, fontWeight: 300, lineHeight: 1.15 }}>{l}</a>
            ))}
          </div>
          {/* secondary + город */}
          <div style={{ padding: '36px 24px 48px' }}>
            <div style={{ fontFamily: F.mono, fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', fontWeight: 600, marginBottom: 18 }}>{epzT('покупателям')}</div>
            {EPZ_MENU_SECONDARY.map(([l, href]) => (
              <a key={l} href={href} style={{ display: 'block', fontFamily: F.body, fontSize: 15, opacity: 0.74, color: 'inherit', textDecoration: 'none', padding: '7px 0', letterSpacing: '0.02em' }}>{epzT(l)}</a>
            ))}
          </div>
          {/* два кадра */}
          <div className="epz-mega-tiles" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0 }}>
            {EPZ_MENU_TILES.map(([label, img, href, pos]) => (
              <a key={label} href={href} className="epz-mega-tile" style={{ position: 'relative', overflow: 'hidden', background: '#000', color: '#EFE7D6', textDecoration: 'none', minHeight: 300 }}>
                <div className="epz-mega-im" style={{ position: 'absolute', inset: 0, backgroundImage: `url(${img})`, backgroundSize: 'cover', backgroundPosition: pos, transition: 'transform 0.7s ease' }} />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.5), transparent 55%)' }} />
                <div style={{ position: 'absolute', left: 0, right: 0, bottom: 22, textAlign: 'center', fontFamily: F.mono, fontSize: 13, letterSpacing: '0.22em', textTransform: 'uppercase' }}>{epzT(label)}</div>
              </a>
            ))}
          </div>
        </div>
      </div>
    </>
  );
}

// ─── Icons (stroke, currentColor) ────────────────────────────────────────────
function EpzIcon({ name, size = 19 }) {
  const s = { width: size, height: size, display: 'block' };
  const common = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' };
  if (name === 'search') return (
    <svg viewBox="0 0 24 24" style={s} {...common}><circle cx="11" cy="11" r="7" /><line x1="16.5" y1="16.5" x2="21" y2="21" /></svg>
  );
  if (name === 'profile') return (
    <svg viewBox="0 0 24 24" style={s} {...common}><circle cx="12" cy="8" r="4" /><path d="M4 21c0-4 3.5-6.5 8-6.5s8 2.5 8 6.5" /></svg>
  );
  if (name === 'heart') return (
    <svg viewBox="0 0 24 24" style={s} {...common}><path d="M12 20s-7-4.6-7-9.7C5 7.3 7 5.5 9.2 5.5c1.6 0 2.7.9 2.8 2 0.1-1.1 1.2-2 2.8-2C17 5.5 19 7.3 19 10.3 19 15.4 12 20 12 20z" /></svg>
  );
  if (name === 'heart-filled') return (
    <svg viewBox="0 0 24 24" style={s} fill="currentColor" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round"><path d="M12 20s-7-4.6-7-9.7C5 7.3 7 5.5 9.2 5.5c1.6 0 2.7.9 2.8 2 0.1-1.1 1.2-2 2.8-2C17 5.5 19 7.3 19 10.3 19 15.4 12 20 12 20z" /></svg>
  );
  if (name === 'bag') return (
    <svg viewBox="0 0 24 24" style={s} {...common}><path d="M6 8h12l-1 12H7L6 8z" /><path d="M9 8V6.5a3 3 0 0 1 6 0V8" /></svg>
  );
  return null;
}

// ─── Header icon button (with optional count badge) ──────────────────────────
function HeaderIcon({ name, label, href, onClick, count = 0, T }) {
  const F = EPZ_FONTS;
  const inner = (
    <span style={{ position: 'relative', display: 'inline-flex', color: 'inherit' }}>
      <EpzIcon name={name} />
      {count > 0 && (
        <span style={{
          position: 'absolute', top: -7, right: -9,
          minWidth: 15, height: 15, padding: '0 3px',
          borderRadius: 15, background: T.accent, color: T.accentText,
          fontFamily: F.mono, fontSize: 9, lineHeight: '15px', textAlign: 'center',
          letterSpacing: 0,
        }}>{count}</span>
      )}
    </span>
  );
  const baseStyle = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    background: 'transparent', color: 'inherit', border: 0, cursor: 'pointer',
    padding: 4, opacity: 0.9,
  };
  if (href) return <a href={href} aria-label={label} title={label} style={{ ...baseStyle, textDecoration: 'none' }}>{inner}</a>;
  return <button onClick={onClick} aria-label={label} title={label} style={baseStyle}>{inner}</button>;
}

// ─── Search overlay ──────────────────────────────────────────────────────────
function EpzSearchOverlay({ open, onClose, T }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const [q, setQ] = React.useState('');
  const inputRef = React.useRef(null);

  React.useEffect(() => {
    if (open && inputRef.current) setTimeout(() => inputRef.current.focus(), 80);
    if (!open) setQ('');
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open]);

  const query = q.trim().toLowerCase();
  const results = !query ? [] : epzSearchArticles(query);
  const suggestions = ['платье', 'тренч', 'шёлк', 'комплект', 'платок', 'шерсть'];

  return (
    <>
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 95, background: 'rgba(0,0,0,0.5)',
        opacity: open ? 1 : 0, pointerEvents: open ? 'auto' : 'none', transition: 'opacity 0.3s ease',
      }} />
      <div style={{
        position: 'fixed', top: 0, left: 0, right: 0, zIndex: 96,
        background: T.bg, color: T.text, borderBottom: `1px solid ${T.border}`,
        transform: open ? 'translateY(0)' : 'translateY(-100%)',
        transition: 'transform 0.4s cubic-bezier(.7,0,.2,1)',
        padding: '28px 32px 36px',
        boxShadow: open ? '0 30px 80px rgba(0,0,0,0.4)' : 'none',
        maxHeight: '80vh', overflowY: 'auto',
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 22 }}>
          <span style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: '0.24em', textTransform: 'uppercase', opacity: 0.6 }}>{epzT('Поиск по каталогу')}</span>
          <button onClick={onClose} aria-label="Закрыть поиск" style={{ background: 'transparent', color: 'inherit', border: 0, cursor: 'pointer', fontFamily: F.mono, fontSize: 16 }}>✕</button>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, borderBottom: `1px solid ${T.text}`, paddingBottom: 14 }}>
          <EpzIcon name="search" size={24} />
          <input ref={inputRef} value={q} onChange={(e) => setQ(e.target.value)} placeholder="что ищете?" style={{
            flex: 1, border: 0, background: 'transparent', color: T.text, outline: 'none',
            fontFamily: F.display, fontSize: 'clamp(28px, 4vw, 48px)', fontStyle: 'italic', fontWeight: 300,
          }} />
        </div>

        {!query && (
          <div style={{ marginTop: 22, display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
            <span style={{ fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.5 }}>{epzT('часто ищут ·')}</span>
            {suggestions.map((s) => (
              <button key={s} onClick={() => setQ(s)} style={{
                background: 'transparent', color: T.text, border: `1px solid ${T.border}`, padding: '6px 12px',
                fontFamily: F.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', cursor: 'pointer',
              }}>{s}</button>
            ))}
          </div>
        )}

        {query && (
          <div style={{ marginTop: 22 }}>
            <div style={{ fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.55, marginBottom: 16 }}>
              {results.length ? `найдено · ${results.length}` : 'ничего не найдено'}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 0 }}>
              {results.map((a, i) => {
                const ep = epzEpisode(a.episode);
                const img = epzArticleImage(a);
                return (
                  <a key={a.id} href={a.href || `/product/?id=${a.id}`} style={{
                    display: 'flex', gap: 14, alignItems: 'center', padding: '14px 16px',
                    border: `1px solid ${T.border}`, margin: '-0.5px', color: 'inherit', textDecoration: 'none',
                  }}>
                    <div style={{ width: 54, height: 68, flexShrink: 0, background: img ? `center 25%/cover no-repeat url(${img})` : T.bgFeatured, border: `1px solid ${T.border}` }}>
                      {!img && <EpzPlaceholder label="" ratio="auto" tone={T.placeholderTone} style={{ aspectRatio: 'auto', width: '100%', height: '100%' }} />}
                    </div>
                    <div>
                      <div style={{ fontSize: 9, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.55 }}>{epzT(ep.title)}</div>
                      <div style={{ fontFamily: F.display, fontSize: 22, lineHeight: 1.05, marginTop: 2 }}>{epzT(a.short || a.title)}</div>
                      <div style={{ fontFamily: F.display, fontSize: 14, marginTop: 4, opacity: 0.85 }}>{a.priceLabel || epzArticlePriceLabel(a)}</div>
                    </div>
                  </a>
                );
              })}
            </div>
          </div>
        )}
      </div>
    </>
  );
}

// ─── Header inline search — ввод прямо в шапке, результаты под ней ──────────
function EpzHdrSearch({ T }) {
  const F = EPZ_FONTS;
  const [q, setQ] = React.useState('');
  const [focus, setFocus] = React.useState(false);
  const [top, setTop] = React.useState(57);
  const ref = React.useRef(null);
  useEpzLang();
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') { setQ(''); setFocus(false); } };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);
  const onFocus = () => {
    try {
      const hdr = ref.current && ref.current.closest('header');
      if (hdr) setTop(Math.round(hdr.getBoundingClientRect().bottom));
    } catch (e) {}
    setFocus(true);
  };
  const query = q.trim().toLowerCase();
  const results = !query ? [] : epzSearchArticles(query);
  const showPanel = focus && query;
  return (
    <div ref={ref} style={{ display: 'inline-flex', alignItems: 'center' }}>
      <label className="epz-hdr-search" style={{
        display: 'inline-flex', alignItems: 'center', gap: 9, marginRight: 'clamp(20px, 6vw, 80px)',
        cursor: 'text', borderBottom: `1px solid ${focus ? 'currentColor' : 'transparent'}`, paddingBottom: 2,
        transition: 'border-color 0.2s',
      }}>
        <EpzIcon name="search" size={16} />
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          onFocus={onFocus}
          onBlur={() => setTimeout(() => setFocus(false), 200)}
          placeholder={epzT('Поиск')}
          className="epz-search-label"
          style={{
            width: focus || q ? 170 : 74, transition: 'width 0.25s ease',
            border: 0, background: 'transparent', color: 'inherit', outline: 'none',
            fontFamily: F.body, fontSize: 13, letterSpacing: '0.04em', padding: 0,
          }}
        />
      </label>
      {/* результаты */}
      <div style={{
        position: 'fixed', left: 0, right: 0, top: top, zIndex: 60,
        background: T.bg, color: T.text, borderTop: `1px solid ${T.border}`, borderBottom: `1px solid ${T.border}`,
        boxShadow: '0 30px 60px rgba(0,0,0,0.18)',
        padding: '18px 32px 24px', maxHeight: '60vh', overflowY: 'auto',
        opacity: showPanel ? 1 : 0, visibility: showPanel ? 'visible' : 'hidden',
        transition: 'opacity 0.2s ease, visibility 0.2s',
      }}>
        <div style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.55, marginBottom: 14 }}>
          {results.length ? `${epzT('найдено')} · ${results.length}` : epzT('ничего не найдено')}
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))', gap: 0 }}>
          {results.map((a) => {
            const ep = epzEpisode(a.episode);
            const img = epzArticleImage(a);
            return (
              <a key={a.id} href={a.href || `/product/?id=${a.id}`} style={{
                display: 'flex', gap: 14, alignItems: 'center', padding: '12px 16px',
                border: `1px solid ${T.border}`, margin: '-0.5px', color: 'inherit', textDecoration: 'none',
              }}>
                <div style={{ width: 48, height: 60, flexShrink: 0, backgroundColor: '#fff', backgroundImage: img ? `url(${img})` : 'none', backgroundSize: 'contain', backgroundPosition: 'center', backgroundRepeat: 'no-repeat', border: `1px solid ${T.border}` }} />
                <div>
                  <div style={{ fontFamily: F.display, fontSize: 19, lineHeight: 1.1 }}>{epzT(a.short || a.title)}</div>
                  <div style={{ fontFamily: F.display, fontSize: 13, marginTop: 3, opacity: 0.85 }}>{a.priceLabel || epzArticlePriceLabel(a)}</div>
                </div>
              </a>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// ─── Toast notifications (site-wide) ─────────────────────────────────────────
function epzToast(msg) {
  try { window.dispatchEvent(new CustomEvent('epz-toast', { detail: { msg } })); } catch (e) {}
}
function EpzToast({ T }) {
  const F = EPZ_FONTS;
  const [msg, setMsg] = React.useState(null);
  React.useEffect(() => {
    let timer;
    const onToast = (e) => {
      setMsg(e.detail && e.detail.msg);
      clearTimeout(timer);
      timer = setTimeout(() => setMsg(null), 2800);
    };
    window.addEventListener('epz-toast', onToast);
    return () => { window.removeEventListener('epz-toast', onToast); clearTimeout(timer); };
  }, []);
  return (
    <div aria-live="polite" style={{
      position: 'fixed', bottom: 24, right: 24, zIndex: 120,
      display: 'flex', alignItems: 'center', gap: 14,
      background: T.text, color: T.bg,
      padding: '14px 18px',
      fontFamily: F.mono, fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
      boxShadow: '0 12px 36px rgba(0,0,0,0.35)',
      transform: msg ? 'translateY(0)' : 'translateY(20px)',
      opacity: msg ? 1 : 0,
      pointerEvents: msg ? 'auto' : 'none',
      transition: 'opacity 0.3s ease, transform 0.3s ease',
      maxWidth: 'min(380px, 86vw)',
    }}>
      <span style={{ width: 8, height: 8, borderRadius: 8, background: T.accent, flexShrink: 0 }} />
      <span style={{ lineHeight: 1.4 }}>{msg || ''}</span>
      <a href="/cart/" style={{ color: 'inherit', textDecoration: 'underline', textUnderlineOffset: 3, whiteSpace: 'nowrap' }}>
        в корзину →
      </a>
    </div>
  );
}

// ─── Header ──────────────────────────────────────────────────────────────────
function EpzHeader({ theme, setTheme, T, current, cartCount }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const store = useEpzStore();

  React.useEffect(() => {
    document.body.style.overflow = (menuOpen || searchOpen) ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen, searchOpen]);

  return (
    <>
      <style>{`
        @keyframes epzCaret { 0%, 50% { opacity: 0.7; } 51%, 100% { opacity: 0; } }
        .epz-search-caret { animation: epzCaret 1.1s step-end infinite; }
        .epz-hdrmenu-tile:hover .epz-hdrmenu-im { transform: scale(1.05); }
        @media (max-width: 680px) {
          .epz-search-label { display: none !important; }
          .epz-search-caret { display: none !important; }
          .epz-hdr { padding: 14px 18px !important; }
          .epz-hdr-lockup { font-size: 15px !important; letter-spacing: 0.18em !important; }
          .epz-hdr-left { gap: 12px !important; }
          .epz-hdr-right { gap: 14px !important; }
          .epz-hdr-sep { display: none !important; }
          .epz-foot { grid-template-columns: 1fr 1fr !important; gap: 28px !important; padding: 44px 18px 28px !important; }
          .epz-foot-brand { grid-column: 1 / -1 !important; }
          .epz-foot-bottom { grid-column: 1 / -1 !important; flex-direction: column !important; gap: 10px !important; align-items: flex-start !important; }
          .epz-m1 { grid-template-columns: 1fr !important; }
          .epz-m2 { grid-template-columns: 1fr 1fr !important; }
          .epz-theme-label { display: none !important; }
          .epz-menu-drawer { width: 74vw !important; }
          .epz-tagline-plaque { display: none !important; }
          .epz-sec-pad { padding-left: 18px !important; padding-right: 18px !important; }
        }
        @media (max-width: 420px) {
          .epz-foot { grid-template-columns: 1fr !important; }
        }
      `}</style>
      <EpzCartDrawer T={T} />
      <EpzWelcomeBack T={T} />
      <EpzToast T={T} />
      <EpzLangPrompt T={T} />

      <header className="epz-hdr" style={{
        display: 'grid', gridTemplateColumns: '1fr auto 1fr',
        alignItems: 'center', padding: '10px 32px',
        borderBottom: `1px solid ${T.border}`,
        transition: 'border-color 0.3s ease, background 0.3s ease',
        background: T.bg, color: T.text,
        position: 'sticky', top: 0, zIndex: 50,
      }}>
        {/* Left — текстовая навигация + тема (иконка) */}
        <div className="epz-hdr-left" style={{ display: 'flex', alignItems: 'center', gap: 22 }}>
          <EpzHdrMenu T={T} label="Коллекция" tiles={[
            ['Каталог', '/catalog/', '/assets/hero-home.jpg', 'center 30%'],
            ['Эльвира', '/episode-002/', '/assets/art-002-pyjama-silk.jpg', 'center 18%'],
            ['Катрин', '/episode-001/', '/assets/katrin-set.jpg', 'center 14%'],
            ['Хацумомо', '/episode-003/', '/assets/hero-hatsumomo.jpg', 'center 20%'],
            ['Тони', '/episode-004/', '/assets/art-004-scarf-tony.jpg', 'center 25%'],
          ]} />
          <EpzHdrMenu T={T} label="Для вас" tiles={[
            ['О бренде', '/manifesto/', '/assets/founder-menu.png', 'center 22%'],
            ['Уход за изделием', '/care/', '/assets/care-menu.jpeg', 'center'],
            ['Доставка и возврат', '/delivery/', '/assets/art-001-cardigan.jpg', 'center 25%'],
            ['Гарантия', '/delivery/?tab=warranty', '/assets/art-003-campaign2.jpg', 'center 25%'],
            ['Вопросы', '/delivery/?tab=faq', '/assets/art-001-dress.jpg', 'center 25%'],
          ]} />
          <ThemeToggle theme={theme} setTheme={setTheme} />
        </div>

        {/* Center — logo only */}
        <a href="/" style={{ color: 'inherit', textDecoration: 'none' }}>
          <EpzLockup size={16} color={T.text} />
        </a>

        {/* Right — поиск (между лого и профилем) · profile · wishlist · cart */}
        <div className="epz-hdr-right" style={{ display: 'flex', justifyContent: 'flex-end', gap: 14, alignItems: 'center' }}>
          <EpzHdrSearch T={T} />
          <HeaderIcon name="profile" label="Профиль" href="/profile/" T={T} />
          <HeaderIcon name="heart" label="Избранное" href="/favorites/" count={store.wishCount} T={T} />
          <HeaderIcon name="bag" label="Корзина" onClick={() => window.dispatchEvent(new CustomEvent('epz-cart-open'))} count={cartCount != null ? cartCount : store.cartCount} T={T} />
        </div>
      </header>
      <EpzWishSizeModal T={T} />
    </>
  );
}

// ─── Header dropdown menu — полноширинная полоса кадров (реф Fara) ─────────
function EpzHdrMenu({ label, tiles, T }) {
  const F = EPZ_FONTS;
  const [open, setOpen] = React.useState(false);
  const [top, setTop] = React.useState(57);
  const ref = React.useRef(null);
  const doOpen = () => {
    try {
      const hdr = ref.current && ref.current.closest('header');
      if (hdr) setTop(Math.round(hdr.getBoundingClientRect().bottom));
    } catch (e) {}
    setOpen(true);
  };
  return (
    <div ref={ref} onMouseEnter={doOpen} onMouseLeave={() => setOpen(false)}>
      <button type="button" onClick={() => (open ? setOpen(false) : doOpen())} style={{
        background: 'transparent', color: 'inherit', border: 0, cursor: 'pointer', padding: '14px 0',
        fontFamily: F.mono, fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', opacity: open ? 1 : 0.8,
        borderBottom: open ? '1px solid currentColor' : '1px solid transparent',
      }}>{epzT(label)}</button>
      <div style={{
        position: 'fixed', left: 0, right: 0, top: top,
        background: T.bg, borderTop: `1px solid ${T.border}`, borderBottom: `1px solid ${T.border}`,
        boxShadow: '0 30px 60px rgba(0,0,0,0.18)', zIndex: 60,
        opacity: open ? 1 : 0, visibility: open ? 'visible' : 'hidden',
        transition: 'opacity 0.22s ease, visibility 0.22s',
      }}>
        <div style={{ display: 'grid', gridTemplateColumns: `repeat(${tiles.length}, 1fr)`, height: 'min(44vh, 420px)' }}>
          {tiles.map(([l, href, img, pos]) => (
            <a key={l} href={href} className="epz-hdrmenu-tile" style={{ position: 'relative', overflow: 'hidden', background: '#241a18', color: '#EFE7D6', textDecoration: 'none' }}>
              <div className="epz-hdrmenu-im" style={{ position: 'absolute', inset: 0, backgroundImage: `url(${img})`, backgroundSize: 'cover', backgroundPosition: pos || 'center 20%', transition: 'transform 0.6s ease' }} />
              <div style={{ position: 'absolute', inset: 0, background: 'rgba(20,17,14,0.18)' }} />
              <span style={{
                position: 'absolute', left: 0, right: 0, top: '50%', transform: 'translateY(-50%)', textAlign: 'center',
                fontFamily: F.mono, fontSize: 11, letterSpacing: '0.26em', textTransform: 'uppercase', fontWeight: 500,
                textShadow: '0 2px 12px rgba(0,0,0,0.65)', padding: '0 8px',
              }}>{epzT(l)}</span>
            </a>
          ))}
        </div>
      </div>
    </div>
  );
}

// ─── Locale-based language prompt (без переключателя в шапке) ─────────────────
// Если локаль браузера не русская — один раз предлагаем английский.
function EpzLangPrompt({ T }) {
  const F = EPZ_FONTS;
  const [show, setShow] = React.useState(false);
  React.useEffect(() => {
    try { if (localStorage.getItem('epz-lang-prompt-seen') === '1') return; } catch (e) { return; }
    let cancelled = false;
    const offerIf = (nonRu) => { if (!cancelled && nonRu) setShow(true); };
    const byNav = () => offerIf(!((navigator.language || '').toLowerCase().startsWith('ru')));
    try {
      fetch('https://ipapi.co/json/').then((r) => r.json()).then((d) => {
        const cc = ((d && d.country_code) || '').toUpperCase();
        if (cc) offerIf(cc !== 'RU'); else byNav();
      }).catch(byNav);
    } catch (e) { byNav(); }
    return () => { cancelled = true; };
  }, []);
  function choose(en) {
    try { localStorage.setItem('epz-lang-prompt-seen', '1'); } catch (e) {}
    if (en && typeof epzSetLang === 'function') epzSetLang('en');
    setShow(false);
  }
  if (!show) return null;
  return (
    <div style={{ position: 'fixed', left: '50%', bottom: 24, transform: 'translateX(-50%)', zIndex: 120, maxWidth: 'min(520px, 92vw)', background: T.bg, color: T.text, border: `1px solid ${T.border}`, boxShadow: '0 24px 70px rgba(0,0,0,0.35)', padding: '18px 20px', display: 'flex', alignItems: 'center', gap: 18, flexWrap: 'wrap' }}>
      <span style={{ fontFamily: F.body, fontSize: 13, lineHeight: 1.5, flex: 1, minWidth: 200 }}>This site is also available in English.</span>
      <div style={{ display: 'flex', gap: 10 }}>
        <button onClick={() => choose(true)} style={{ background: T.btnPrimary, color: T.btnPrimaryFg, border: 0, cursor: 'pointer', padding: '11px 16px', fontFamily: F.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase' }}>English</button>
        <button onClick={() => choose(false)} style={{ background: 'transparent', color: 'inherit', border: `1px solid ${T.border}`, cursor: 'pointer', padding: '11px 16px', fontFamily: F.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase' }}>Русский</button>
      </div>
    </div>
  );
}

// ─── Welcome-back banner (abandoned cart) ────────────────────────────────────
// On a fresh visit, if the cart already has items from a previous session, show
// a quiet "your look is still waiting" bar — once per session, no pressure.
function EpzWelcomeBack({ T }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const store = useEpzStore();
  const [show, setShow] = React.useState(false);

  React.useEffect(() => {
    let touched = false, seen = false;
    try { touched = localStorage.getItem('epz-cart-touched') === '1'; } catch (e) {}
    try { seen = sessionStorage.getItem('epz-welcome-seen') === '1'; } catch (e) {}
    const hasItems = (store.cart || []).length > 0;
    if (hasItems && touched && !seen) {
      const t = setTimeout(() => {
        setShow(true);
        try { sessionStorage.setItem('epz-welcome-seen', '1'); } catch (e) {}
      }, 1400);
      return () => clearTimeout(t);
    }
  }, []);

  React.useEffect(() => {
    const onTest = () => setShow(true);
    window.addEventListener('epz-welcome-test', onTest);
    return () => window.removeEventListener('epz-welcome-test', onTest);
  }, []);

  React.useEffect(() => {
    if (!show) return;
    const t = setTimeout(() => setShow(false), 9000);
    return () => clearTimeout(t);
  }, [show]);

  if (!show) return null;
  const count = (store.cart || []).reduce((s, c) => s + (c.qty || 1), 0);
  const first = store.cart && store.cart[0] ? epzArticle(store.cart[0].id) : null;

  return (
    <div style={{
      position: 'fixed', left: 24, bottom: 24, zIndex: 200, maxWidth: 340,
      background: T.accent, color: T.accentText, padding: '18px 20px',
      boxShadow: '0 20px 60px rgba(0,0,0,0.35)', animation: 'epzWBin 0.5s cubic-bezier(.7,0,.2,1)',
    }}>
      <style>{`@keyframes epzWBin{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}`}</style>
      <button onClick={() => setShow(false)} aria-label={epzT('Закрыть')} style={{ position: 'absolute', top: 10, right: 12, background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontFamily: F.mono, fontSize: 14, opacity: 0.7 }}>✕</button>
      <div style={{ fontFamily: F.display, fontSize: 22, fontStyle: 'italic', lineHeight: 1.1 }}>{epzT('Ваш образ ещё ждёт')}</div>
      <div style={{ marginTop: 8, fontFamily: F.body, fontSize: 13, lineHeight: 1.5, opacity: 0.85 }}>
        {first ? `${first.short || first.title}${count > 1 ? ` ${epzT('и ещё')} ${count - 1}` : ''} — ${epzT('партия пока в наличии')}` : epzT('партия пока в наличии')}
      </div>
      <button onClick={() => { setShow(false); window.dispatchEvent(new CustomEvent('epz-cart-open')); }} style={{
        marginTop: 14, background: 'transparent', color: 'inherit', border: `1px solid ${T.accentText}`,
        padding: '10px 16px', cursor: 'pointer', fontFamily: F.mono, fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase',
      }}>{epzT('вернуться к образу →')}</button>
    </div>
  );
}

// ─── Cart drawer (slide-in) ──────────────────────────────────────────────────
// Opens whenever something is added to the cart (listens for 'epz-cart-open').
function EpzCartDrawer({ T }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const store = useEpzStore();
  const [open, setOpen] = React.useState(false);
  const [lastAdded, setLastAdded] = React.useState(null); // {id, variant, size}
  const [crossDismissed, setCrossDismissed] = React.useState(false);
  const [restorable, setRestorable] = React.useState(null); // {id, variant, size, title}
  const [openBundles, setOpenBundles] = React.useState({}); // раскрытый состав комплекта
  // Free shipping threshold. NOTE: 100 000 ₽ — likely RU-only; foreign audience
  // will have different rules (TBD, to discuss with the owner).
  const FREE_SHIP = 100000;

  React.useEffect(() => {
    const openFn = (e) => {
      setOpen(true);
      if (e && e.detail && e.detail.id) { setLastAdded(e.detail); setCrossDismissed(false); }
    };
    window.addEventListener('epz-cart-open', openFn);
    return () => window.removeEventListener('epz-cart-open', openFn);
  }, []);

  // Auto-close ~5s after opening; cancel on hover so it won't vanish while reading.
  const [hovering, setHovering] = React.useState(false);
  React.useEffect(() => {
    if (!open || hovering) return;
    const t = setTimeout(() => setOpen(false), 5000);
    return () => clearTimeout(t);
  }, [open, hovering]);
  React.useEffect(() => {
    if (open) document.body.style.overflow = 'hidden';
    else document.body.style.overflow = '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const cart = store.cart;
  const { rows, subtotal, savings } = epzGroupCart(cart);
  const count = cart.reduce((s, c) => s + (c.qty || 1), 0);
  const freeLeft = Math.max(0, FREE_SHIP - subtotal);

  // Cross-sell: suggest the partner piece of the last-added item if it isn't
  // already in the cart (and the item is part of a bundle pairing).
  const inCart = (id, variant) => cart.some((c) => c.id === id && (c.variant || null) === (variant || null));
  let cross = null;
  if (lastAdded && !crossDismissed) {
    const cs = epzCrossSell(lastAdded.id, lastAdded.variant);
    if (cs && cs.card && !inCart(cs.addId, cs.addVariant)) cross = cs;
  }
  const addCross = () => {
    if (!cross) return;
    store.addToCart(cross.addId, { variant: cross.addVariant, size: cross.addSize, qty: 1 });
    setCrossDismissed(true);
  };

  const rememberLine = (line) => {
    const a = epzArticle(line.id);
    const title = (a && a.variantNames && line.variant && a.variantNames[line.variant]) || (a && (a.short || a.title)) || '';
    setRestorable({ single: true, title, parts: [{ id: line.id, variant: line.variant || null, size: line.size, qty: 1 }] });
  };
  const setQty = (idx, delta) => {
    const line = cart[idx];
    if (delta < 0 && (line.qty || 1) <= 1) rememberLine(line); // last unit → offer undo
    const next = cart.map((c, i) => i === idx ? { ...c, qty: Math.max(0, (c.qty || 1) + delta) } : c).filter((c) => c.qty > 0);
    store.setCart(next);
  };
  const removeAt = (idx) => { rememberLine(cart[idx]); store.setCart(cart.filter((_, i) => i !== idx)); };
  const removeIdxs = (idxs) => store.setCart(cart.filter((_, i) => !idxs.includes(i)));
  // Removing/reducing a bundle part: remember it so we can offer "вернуть комплект".
  const breakPart = (line, title, mode) => {
    setRestorable({ title, parts: [{ id: line.id, variant: line.variant || null, size: line.size, qty: 1 }] });
    if (mode === 'remove') removeAt(line.idx);
    else setQty(line.idx, -1);
  };
  const removeBundle = (r) => {
    setRestorable({ title: r.title, parts: r.parts.map((p) => ({ id: p.line.id, variant: p.line.variant || null, size: p.line.size, qty: p.consumed })) });
    removeIdxs(r.parts.map((p) => p.line.idx));
  };
  const restoreSet = () => {
    if (!restorable) return;
    restorable.parts.forEach((p) => store.addToCart(p.id, { variant: p.variant, size: p.size, qty: p.qty || 1 }));
    setRestorable(null);
  };
  // Hide the restore offer once that bundle is whole again.
  React.useEffect(() => {
    if (!restorable) return;
    if (restorable.single) {
      const p = restorable.parts[0];
      if (cart.some((c) => c.id === p.id && (c.variant || null) === (p.variant || null) && c.size === p.size)) setRestorable(null);
    } else if (rows.some((r) => r.kind === 'bundle' && epzT(r.title) === epzT(restorable.title))) setRestorable(null);
  }, [cart]);
  const setBundleQty = (idxs, delta) => {
    let next = cart.map((c, i) => idxs.includes(i) ? { ...c, qty: Math.max(0, (c.qty || 1) + delta) } : c);
    next = next.filter((c) => c.qty > 0);
    store.setCart(next);
  };

  return (
    <>
      <div onClick={() => setOpen(false)} style={{
        position: 'fixed', inset: 0, zIndex: 240, background: 'rgba(10,8,7,0.5)',
        opacity: open ? 1 : 0, pointerEvents: open ? 'auto' : 'none', transition: 'opacity 0.3s ease',
      }} />
      <aside aria-label="Корзина" onMouseEnter={() => setHovering(true)} onMouseLeave={() => setHovering(false)} style={{
        position: 'fixed', top: 0, right: 0, bottom: 0, zIndex: 241, width: 'min(440px, 96vw)',
        background: T.bg, color: T.text, borderLeft: `1px solid ${T.border}`,
        transform: open ? 'translateX(0)' : 'translateX(100%)', transition: 'transform 0.42s cubic-bezier(.7,0,.2,1)',
        display: 'flex', flexDirection: 'column', boxShadow: open ? '-30px 0 80px rgba(0,0,0,0.35)' : 'none',
      }}>
        {/* header */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '16px 24px 12px', flexShrink: 0 }}>
          <span style={{ fontFamily: F.display, fontSize: 23, fontWeight: 400 }}>{epzT('Корзина')}</span>
          <button onClick={() => setOpen(false)} aria-label="Закрыть" style={{ background: 'transparent', border: 0, color: 'inherit', fontSize: 19, cursor: 'pointer', fontFamily: F.mono, lineHeight: 1 }}>✕</button>
        </div>

        {/* lines */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 24px' }}>
          {rows.length === 0 ?
          <div style={{ padding: '60px 0', textAlign: 'center', opacity: 0.6, fontFamily: F.body, fontSize: 14, lineHeight: 1.7 }}>
            {epzT('Пока пусто')}<br />{epzT('Добавьте изделия из каталога')}
          </div> :
          rows.map((r, ri) => r.kind === 'bundle' ? (
            /* ── auto-combined set — как в чекауте: простая строка + раскрывающийся состав ── */
            <div key={'b' + r.set + ri} style={{ display: 'grid', gridTemplateColumns: '70px 1fr', gap: 13, padding: '13px 0', borderTop: `1px solid ${T.border}` }}>
              <div style={{ width: 70, height: 88, backgroundColor: '#ffffff', backgroundImage: (r.image || r.parts[0].img) ? `url(${r.image || r.parts[0].img})` : 'none', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'contain' }} />
              <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>
                <div style={{ fontFamily: F.display, fontSize: 16, lineHeight: 1.1 }}>{epzT(r.title)}</div>
                <div style={{ marginTop: 3, fontFamily: F.display, fontSize: 15 }}>{epzFmt(r.setPrice * r.nSets)}</div>
                <div style={{ marginTop: 4, display: 'flex', alignItems: 'center', gap: 6, fontFamily: F.mono, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', opacity: 0.7 }}>
                  {(() => { const cols = []; r.parts.forEach((p) => { if (p.a.color && !cols.find((c) => c[0] === p.a.color)) cols.push([p.a.color, p.a.colorHex]); }); return cols.map(([nm, hex], i) => (
                    <span key={nm} style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
                      <span style={{ width: 8, height: 8, borderRadius: '50%', background: hex || '#ccc', border: `1px solid ${T.border}`, flexShrink: 0 }} />
                      <span>{epzT(nm)}</span>{i < cols.length - 1 ? <span style={{ opacity: 0.5 }}>·</span> : null}
                    </span>
                  )); })()}
                  <span style={{ opacity: 0.6 }}>· {r.parts.map((p) => p.line.size).join(' · ')}</span>
                </div>
                <div style={{ marginTop: 8 }}>
                  <div style={{ display: 'inline-flex', alignItems: 'center', gap: 12, border: `1px solid ${T.border}`, padding: '4px 10px' }}>
                    <button onClick={() => r.nSets > 1 ? setBundleQty(r.parts.map((p) => p.line.idx), -1) : removeBundle(r)} aria-label={epzT('Меньше')} style={{ background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontFamily: F.mono, fontSize: 13, lineHeight: 1, padding: 0 }}>−</button>
                    <span style={{ fontFamily: F.mono, fontSize: 11, minWidth: 12, textAlign: 'center' }}>{r.nSets}</span>
                    <button onClick={() => setBundleQty(r.parts.map((p) => p.line.idx), 1)} aria-label={epzT('Больше')} style={{ background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontFamily: F.mono, fontSize: 13, lineHeight: 1, padding: 0 }}>+</button>
                  </div>
                </div>
                <button onClick={() => setOpenBundles((o) => ({ ...o, [ri]: !o[ri] }))} style={{ marginTop: 10, background: 'transparent', border: 0, color: T.accentInk, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 9, fontFamily: F.mono, fontSize: 9, letterSpacing: '0.14em', textTransform: 'uppercase', padding: 0, alignSelf: 'flex-start' }}>
                  <span>{openBundles[ri] ? epzT('скрыть состав') : epzT('состав комплекта')}</span>
                  <span style={{ display: 'inline-block', fontSize: 15, lineHeight: 1, transition: 'transform 0.2s', transform: openBundles[ri] ? 'rotate(180deg)' : 'none' }}>⌄</span>
                </button>
                {openBundles[ri] &&
                <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 12 }}>
                  {r.parts.map((p, pi) => (
                    <div key={pi} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                      <div style={{ width: 30, height: 38, flexShrink: 0, backgroundColor: '#ffffff', backgroundImage: p.img ? `url(${p.img})` : 'none', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'contain' }} />
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontFamily: F.display, fontSize: 14, lineHeight: 1.15 }}>{epzT((p.a.variantNames && p.line.variant && p.a.variantNames[p.line.variant]) || p.a.short || p.a.title)}</div>
                        <span style={{ display: 'block', fontFamily: F.mono, fontSize: 8, letterSpacing: '0.14em', textTransform: 'uppercase', opacity: 0.55, marginTop: 2 }}>{p.line.size}{p.consumed > 1 ? ` · ×${p.consumed}` : ''}</span>
                      </div>
                      <div style={{ fontFamily: F.display, fontSize: 13, opacity: 0.55, flexShrink: 0 }}>{epzFmt(p.price)}</div>
                    </div>
                  ))}
                </div>
                }
              </div>
            </div>
          ) : (
            /* ── single item ── */
            (() => {
              const l = r.line; const a = r.a;
              const left = epzBatchLeft(l.id + (l.variant || ''));
              return (
            <div key={l.id + (l.variant || '') + l.size} style={{ display: 'grid', gridTemplateColumns: '70px 1fr', gap: 13, padding: '13px 0', borderTop: `1px solid ${T.border}` }}>
              <a href={a.href || `/product/?id=${l.id}`} style={{ display: 'block', width: 70, height: 88, backgroundColor: '#ffffff', backgroundImage: r.img ? `url(${r.img})` : 'none', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'contain' }}>
                {!r.img && <span style={{ display: 'flex', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', fontFamily: F.mono, fontSize: 8, letterSpacing: '0.16em', opacity: 0.5, textTransform: 'uppercase' }}>фото</span>}
              </a>
              <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10 }}>
                  <a href={a.href || `/product/?id=${l.id}`} style={{ fontFamily: F.display, fontSize: 16, lineHeight: 1.1, color: 'inherit', textDecoration: 'none' }}>
                    {epzT((a.variantNames && l.variant && a.variantNames[l.variant]) || a.short || a.title)}
                  </a>
                </div>
                <div style={{ marginTop: 3, fontFamily: F.display, fontSize: 15 }}>{epzFmt(r.price)}</div>
                <div style={{ marginTop: 4, display: 'flex', alignItems: 'center', gap: 6, fontFamily: F.mono, fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase', opacity: 0.7 }}>
                  {a.color ? <>
                    <span style={{ width: 8, height: 8, borderRadius: '50%', background: a.colorHex || '#ccc', border: `1px solid ${T.border}`, flexShrink: 0 }} />
                    <span>{epzT(a.color)}</span>
                    <span style={{ opacity: 0.5 }}>·</span>
                  </> : null}
                  <span>{l.size}</span>
                </div>
                <div style={{ marginTop: 7 }}>
                  <div style={{ fontFamily: F.mono, fontSize: 8, letterSpacing: '0.14em', textTransform: 'uppercase', color: T.accentInk, opacity: 0.95 }}>
                    {epzT('осталось')} {left} {epzT('из')} {EPZ_BATCH_TOTAL}
                  </div>
                  <div style={{ marginTop: 4, height: 2, background: T.border, position: 'relative', overflow: 'hidden' }}>
                    <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: `${((EPZ_BATCH_TOTAL - left) / EPZ_BATCH_TOTAL) * 100}%`, background: T.accent }} />
                  </div>
                </div>
                <div style={{ marginTop: 'auto', display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 8 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 14, border: `1px solid ${T.border}`, padding: '5px 10px' }}>
                    <button onClick={() => setQty(l.idx, -1)} aria-label="Меньше" style={{ background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontFamily: F.mono, fontSize: 14, lineHeight: 1, padding: 0 }}>−</button>
                    <span style={{ fontFamily: F.mono, fontSize: 12, minWidth: 14, textAlign: 'center' }}>{l.qty}</span>
                    <button onClick={() => setQty(l.idx, 1)} aria-label="Больше" style={{ background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontFamily: F.mono, fontSize: 14, lineHeight: 1, padding: 0 }}>+</button>
                  </div>
                </div>
              </div>
            </div>
              );
            })()
          ))}
        </div>

        {/* restore set — re-add a removed bundle part to reform the set */}
        {restorable && !cross &&
        <div style={{ flexShrink: 0, borderTop: `1px solid ${T.border}`, background: T.bgAlt, padding: '12px 24px' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
            <div style={{ minWidth: 0 }}>
              <div style={{ fontFamily: F.mono, fontSize: 8, letterSpacing: '0.16em', textTransform: 'uppercase', color: T.accentInk, marginBottom: 3 }}>✦ {restorable.single ? epzT('товар удалён') : epzT('комплект распался')}</div>
              <div style={{ fontFamily: F.display, fontSize: 15, lineHeight: 1.1 }}>{epzT(restorable.title)}</div>
            </div>
            <button onClick={restoreSet} style={{ flexShrink: 0, background: T.accent, color: T.accentText, border: 0, cursor: 'pointer', padding: '10px 14px', fontFamily: F.mono, fontSize: 9, letterSpacing: '0.16em', textTransform: 'uppercase' }}>{restorable.single ? epzT('вернуть товар') : epzT('вернуть комплект')}</button>
          </div>
        </div>
        }

        {/* cross-sell — partner piece of the last added item */}
        {cross &&
        <div style={{ flexShrink: 0, borderTop: `1px solid ${T.border}`, background: T.bgAlt, padding: '12px 24px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <a href={cross.card.href} style={{ display: 'block', width: 46, height: 58, flexShrink: 0, backgroundColor: '#ffffff', backgroundImage: epzArticleImage(cross.card) ? `url(${epzArticleImage(cross.card)})` : 'none', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: cross.card.gallery ? 'contain' : 'cover' }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: F.mono, fontSize: 8, letterSpacing: '0.16em', textTransform: 'uppercase', color: T.accentInk, marginBottom: 3 }}>{epzT('образ целиком')}</div>
              <div style={{ fontFamily: F.display, fontSize: 15, lineHeight: 1.1 }}>{cross.card.short || cross.card.title}</div>
              <div style={{ fontFamily: F.mono, fontSize: 9, letterSpacing: '0.06em', opacity: 0.7, marginTop: 2 }}>+{epzFmt(cross.card.price)}</div>
            </div>
            <button onClick={addCross} aria-label={epzT('добавить')} style={{ flexShrink: 0, background: T.accent, color: T.accentText, border: 0, cursor: 'pointer', padding: '10px 14px', fontFamily: F.mono, fontSize: 9, letterSpacing: '0.16em', textTransform: 'uppercase' }}>+ {epzT('добавить')}</button>
          </div>
        </div>
        }

        {/* footer */}
        {rows.length > 0 &&
        <div style={{ flexShrink: 0, borderTop: `1px solid ${T.border}` }}>
          <div style={{ padding: '11px 24px', borderBottom: `1px solid ${T.border}` }}>
            <div style={{ fontFamily: F.mono, fontSize: 9, letterSpacing: '0.16em', textTransform: 'uppercase', opacity: 0.7 }}>
              {freeLeft === 0 ? epzT('✦ бесплатная доставка по России') : `${epzT('до бесплатной доставки —')} ${epzFmt(freeLeft)}`}
            </div>
            <div style={{ marginTop: 8, height: 3, background: T.border, position: 'relative', overflow: 'hidden' }}>
              <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: `${Math.min(100, (subtotal / FREE_SHIP) * 100)}%`, background: T.accent, transition: 'width 0.4s ease' }} />
            </div>
          </div>
          <div style={{ padding: '11px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <span style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.7 }}>{epzT('итого')} · {count} {epzIsEN() ? (count === 1 ? 'item' : 'items') : (count % 10 === 1 && count % 100 !== 11 ? 'вещь' : (count % 10 >= 2 && count % 10 <= 4 && (count % 100 < 10 || count % 100 >= 20) ? 'вещи' : 'вещей'))}</span>
            <span style={{ fontFamily: F.display, fontSize: 23, lineHeight: 1 }}>{epzFmt(subtotal)}</span>
          </div>
          <div style={{ padding: '0 24px 18px' }}>
            <a href="/checkout/" style={{ display: 'block', textAlign: 'center', background: T.btnPrimary, color: T.btnPrimaryFg, padding: '15px 24px', fontFamily: F.mono, fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', textDecoration: 'none' }}>
              {epzT('оформить заказ')}
            </a>
            <div style={{ marginTop: 9, textAlign: 'center', fontFamily: F.mono, fontSize: 9, letterSpacing: '0.1em', textTransform: 'uppercase', opacity: 0.55 }}>
              {epzT('или 4 платежа по')} {epzFmt(Math.round(subtotal / 4))}
            </div>
          </div>
        </div>
        }
      </aside>
    </>
  );
}

// ─── Breadcrumbs ─────────────────────────────────────────────────────────────
function EpzCrumbs({ T, items, right }) {
  const F = EPZ_FONTS;
  return (
    <nav aria-label="Хлебные крошки" style={{
      padding: '13px 32px', borderBottom: `1px solid ${T.border}`,
      fontFamily: F.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase',
      display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap', color: T.text,
    }}>
      {items.map((it, i) => {
        const last = i === items.length - 1;
        return (
          <React.Fragment key={i}>
            {it.href && !last ?
            <a href={it.href} style={{ color: 'inherit', textDecoration: 'none', opacity: 0.55, maxWidth: 260, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{it.label}</a> :
            <span style={{ opacity: last ? 1 : 0.55, maxWidth: 260, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{it.label}</span>
            }
            {!last && <span style={{ opacity: 0.4 }}>/</span>}
          </React.Fragment>
        );
      })}
      {right && <span style={{ marginLeft: 'auto', display: 'inline-flex', alignItems: 'center' }}>{right}</span>}
    </nav>
  );
}

// ─── Footer ──────────────────────────────────────────────────────────────────
function EpzFooter({ T }) {
  const F = EPZ_FONTS;
  useEpzLang();
  const [email, setEmail] = React.useState('');
  const [agree, setAgree] = React.useState(false);
  const [sent, setSent] = React.useState(false);
  function subscribe(ev) {
    ev.preventDefault();
    if (!email || !agree) return;
    setSent(true);
    epzToast(epzT('Промокод на −10% отправлен на почту'));
  }
  const head = { fontFamily: F.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', fontWeight: 600, color: T.text, marginBottom: 14 };
  const link = { color: 'inherit', textDecoration: 'none', fontFamily: F.body, fontSize: 13, letterSpacing: 0, opacity: 0.75, display: 'block' };
  const lbl = { fontFamily: F.mono, fontSize: 9, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.45, marginBottom: 6 };
  const cols = [
    ['бренд', [['О бренде', '/manifesto/'], ['Уход за изделием', '/care/']]],
    ['помощь', [['Доставка и возврат', '/delivery/'], ['Гарантия', '/delivery/?tab=warranty'], ['Отслеживание заказа', '/tracking/'], ['Вопросы', '/delivery/?tab=faq'], ['Контакты', '/contacts/']]],
    ['правовая информация', [['Политика конфиденциальности', '/delivery/'], ['Условия', '/delivery/'], ['Оферта', '/delivery/']]],
  ];
  const socials = [
    ['Instagram', 'https://instagram.com/theepizode', (
      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3.5" y="3.5" width="17" height="17" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.1" cy="6.9" r="1.05" fill="currentColor" stroke="none"/></svg>
    )],
    ['Pinterest', 'https://pinterest.com/theepizode', (
      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><circle cx="12" cy="12" r="8.5"/><path d="M9.2 20.2 12 9.5"/><path d="M10.6 7.6c2.4-1.5 5.4-.3 5.4 2.3 0 2.7-2 4.4-4 4.1-1.1-.2-1.7-.9-2-1.7"/></svg>
    )],
    ['YouTube', 'https://youtube.com/@theepizode', (
      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"><rect x="2.5" y="6" width="19" height="12.5" rx="3.5"/><path d="M10 9.5v5.5l4.8-2.75L10 9.5z" fill="currentColor" stroke="none"/></svg>
    )],
    ['TikTok', 'https://tiktok.com/@theepizode', (
      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><path d="M14.5 3.5v10.8a4 4 0 1 1-4-4"/><path d="M14.5 5.2c.8 2.2 2.4 3.6 4.8 3.9"/></svg>
    )],
  ];
  return (
    <footer className="epz-foot2" style={{
      position: 'relative', overflow: 'hidden',
      padding: 'clamp(36px, 4.5vw, 56px) 32px 0',
      background: T.bg, color: T.text,
      transition: 'background 0.3s ease, color 0.3s ease, border-color 0.3s ease',
    }}>
      <style>{`
        @media (max-width: 980px) { .epz-foot2-grid { grid-template-columns: 1fr !important; } .epz-foot2-cols { grid-template-columns: 1fr 1fr !important; } }
        @media (max-width: 560px) { .epz-foot2-cols { grid-template-columns: 1fr !important; } }
      `}</style>
      <div className="epz-foot2-grid" style={{ display: 'grid', gridTemplateColumns: '1.1fr 1.6fr', gap: 'clamp(32px, 4.5vw, 60px)' }}>
        {/* левая колонка: подписка + страна/язык */}
        <div>
          {sent ? (
            <div>
              <div style={{ fontFamily: F.display, fontSize: 26, fontStyle: 'italic', lineHeight: 1.15 }}>{epzT('Спасибо! Теперь вы узнаете о премьерах первыми.')}</div>
            </div>
          ) : (
            <>
              <div style={{ fontFamily: F.body, fontSize: 13.5, opacity: 0.6, marginBottom: 20 }}>{epzT('Новая коллекция и ранний доступ к предзаказу')}</div>
              <form onSubmit={subscribe}>
                <div style={{ display: 'flex', alignItems: 'center', borderBottom: `1px solid ${T.text}`, maxWidth: 360 }}>
                  <input type="email" required value={email} onChange={(ev) => setEmail(ev.target.value)} placeholder="вашa@почта.ru" style={{
                    flex: 1, border: 0, background: 'transparent', color: T.text, outline: 'none',
                    padding: '11px 2px', fontFamily: F.body, fontSize: 13, minWidth: 0,
                  }} />
                  <button type="submit" aria-label={epzT('подписаться')} style={{ border: 0, background: 'transparent', color: T.accentInk, cursor: 'pointer', fontFamily: F.body, fontSize: 18, lineHeight: 1, padding: '11px 2px 11px 14px' }}>→</button>
                </div>
              </form>
              <label style={{ marginTop: 12, display: 'flex', alignItems: 'flex-start', gap: 10, cursor: 'pointer', maxWidth: 400 }}>
                <input type="checkbox" checked={agree} onChange={(ev) => setAgree(ev.target.checked)} style={{ position: 'absolute', opacity: 0, width: 13, height: 13 }} />
                <span aria-hidden="true" style={{ width: 13, height: 13, marginTop: 2, flexShrink: 0, borderRadius: 3, border: `1.5px solid ${agree ? T.accent : T.border}`, background: agree ? T.accent : 'transparent', color: T.accentText, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 9, lineHeight: 1, transition: 'background 0.15s, border-color 0.15s' }}>{agree ? '✓' : ''}</span>
                <span style={{ fontFamily: F.body, fontSize: 11.5, opacity: 0.65, lineHeight: 1.5 }}>
                  {epzT('Согласен получать письма от THE EPIZODE и принимаю')}{' '}
                  <a href="/delivery/" style={{ color: 'inherit', textDecorationStyle: 'dotted' }}>{epzT('политику конфиденциальности')}</a>
                </span>
              </label>
            </>
          )}
          {/* страна и язык — под почтой */}
          <div style={{ marginTop: 28, display: 'inline-flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <span style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', fontWeight: 600, marginRight: 6 }}>{epzT('страна и язык')}</span>
            <label style={{ position: 'relative', display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontFamily: F.body, fontSize: 13 }}>
              <span>{epzT('Россия')}</span><span style={{ opacity: 0.4 }}>|</span><span>₽ RUB</span><span style={{ opacity: 0.4 }}>|</span><span>{epzT('Русский')}</span>
              <span style={{ fontSize: 10, opacity: 0.6 }}>▾</span>
              <select aria-label={epzT('Страна и язык')} defaultValue="ru" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: 0, cursor: 'pointer', border: 0 }}>
                <option value="ru">Россия · ₽ RUB · Русский</option>
                <option value="eu">Европа · € EUR · English</option>
                <option value="us">США · $ USD · English</option>
                <option value="cis">СНГ · ₽ RUB · Русский</option>
                <option value="world">Остальной мир · English</option>
              </select>
            </label>
          </div>
        </div>

        {/* правая колонка: ссылки + соцсети */}
        <div>
          <div className="epz-foot2-cols" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 32 }}>
            {cols.map(([title, links]) => (
              <div key={title}>
                <div style={head}>{epzT(title)}</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {links.map(([l, href]) => (
                    <a key={l} href={href} style={link}>{epzT(l)}</a>
                  ))}
                </div>
              </div>
            ))}
          </div>
          <div style={{ marginTop: 26, display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 10 }}>
            {socials.map(([name, href, icon]) => (
              <a key={name} href={href} target="_blank" rel="noopener" aria-label={name} title={name} style={socBtn(T)}>{icon}</a>
            ))}
          </div>
        </div>
      </div>

      {/* giant wordmark (real logo, full-bleed) */}
      <div aria-hidden="true" style={{
        marginTop: 'clamp(24px, 3.5vw, 44px)', width: '100%', aspectRatio: '698.9 / 104.61',
        background: T.accent,
        WebkitMaskImage: 'url(/assets/logo-epizode.svg)', maskImage: 'url(/assets/logo-epizode.svg)',
        WebkitMaskRepeat: 'no-repeat', maskRepeat: 'no-repeat',
        WebkitMaskSize: '100% 100%', maskSize: '100% 100%',
        WebkitMaskPosition: 'center bottom', maskPosition: 'center bottom',
      }} />

      {/* legal */}
      <div style={{ padding: '18px 0 28px', display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12, fontFamily: F.mono, fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', opacity: 0.5 }}>
        <span>© the epizode · 2026</span>
        <span>Создано в Москве</span>
      </div>
    </footer>
  );
}

function socBtn(T) {
  return { width: 34, height: 34, borderRadius: '50%', border: `1px solid ${T.accentInk}`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: T.accentInk, textDecoration: 'none' };
}

Object.assign(window, {
  EPZ_THEME, EPZ_PAGES,
  useEpzTheme, useEpzStore, useEpzLang, epzT, epzSetLang, epzIsEN,
  epzReadStore, epzWriteStore, epzAddToCart, epzToggleWish, epzCartLineKey,
  epzWishAdd, epzWishSizeGet, epzWishSizeSet, EPZ_WISH_SIZE_KEY,
  EPZ_CART_KEY, EPZ_WISH_KEY,
  ThemeToggle, LangSwitch, EpzTicketThemed,
  EpzIcon, HeaderIcon, EpzSearchOverlay,
  epzToast, EpzToast,
  EpzMenuDrawer, EpzHeader, EpzFooter, EpzCrumbs, EpzCartDrawer, EpzWelcomeBack,
});
