// ── Shell: announcement bar, nav (with Men/Women), footer ────────────

// ── IP geo → language / currency defaults ────────────────────────────
const GEO_LANG_MAP = {
  US:'en',  GB:'en',  AU:'en',  NZ:'en',  IE:'en',  ZA:'en',
  NG:'en',  KE:'en',  GH:'en',  SG:'en',  PH:'en',  JM:'en',
  CN:'zh-CN', TW:'zh-CN', HK:'zh-CN', MO:'zh-CN',
  ES:'es',  MX:'es',  AR:'es',  CL:'es',  CO:'es',  PE:'es',
  VE:'es',  EC:'es',  GT:'es',  CU:'es',  BO:'es',  DO:'es',
  HN:'es',  PY:'es',  SV:'es',  NI:'es',  CR:'es',  PA:'es',  UY:'es',
  IN:'hi',
  SA:'ar',  AE:'ar',  EG:'ar',  MA:'ar',  KW:'ar',  QA:'ar',
  BH:'ar',  DZ:'ar',  TN:'ar',  LY:'ar',  IQ:'ar',  SY:'ar',
  JO:'ar',  LB:'ar',  YE:'ar',  OM:'ar',  SD:'ar',
  FR:'fr',  BE:'fr',  LU:'fr',  CI:'fr',  SN:'fr',  CM:'fr',
  ML:'fr',  BF:'fr',  NE:'fr',  TG:'fr',  GA:'fr',  CG:'fr',  CD:'fr',
  BD:'bn',
  RU:'ru',  BY:'ru',  KZ:'ru',  KG:'ru',  TJ:'ru',
  PT:'pt',  BR:'pt',  AO:'pt',  MZ:'pt',
  ID:'id',  MY:'id',
  DE:'de',  AT:'de',
  JP:'ja',
  TR:'tr',
  KR:'ko',
  IT:'it',
  PK:'ur',
};

const GEO_CURRENCY_SUPPORT = new Set(['USD','EUR','GBP','CAD','AUD','AED','PKR','INR']);

const LANGUAGES = [
  { code: 'en',   label: 'EN', name: 'English'           },
  { code: 'zh-CN',label: 'ZH', name: '中文 (简体)'         },
  { code: 'es',   label: 'ES', name: 'Español'           },
  { code: 'hi',   label: 'HI', name: 'हिन्दी'              },
  { code: 'ar',   label: 'AR', name: 'العربية'           },
  { code: 'fr',   label: 'FR', name: 'Français'          },
  { code: 'bn',   label: 'BN', name: 'বাংলা'             },
  { code: 'ru',   label: 'RU', name: 'Русский'           },
  { code: 'pt',   label: 'PT', name: 'Português'         },
  { code: 'id',   label: 'ID', name: 'Bahasa Indonesia'  },
  { code: 'de',   label: 'DE', name: 'Deutsch'           },
  { code: 'ja',   label: 'JA', name: '日本語'             },
  { code: 'tr',   label: 'TR', name: 'Türkçe'            },
  { code: 'ko',   label: 'KO', name: '한국어'             },
  { code: 'it',   label: 'IT', name: 'Italiano'          },
  { code: 'ur',   label: 'UR', name: 'اردو'              },
  { code: 'pa',   label: 'PA', name: 'ਪੰਜਾਬੀ'            },
  { code: 'ps',   label: 'PS', name: 'پښتو'             },
  { code: 'sd',   label: 'SD', name: 'سنڌي'             },
  { code: 'srki', label: 'SK', name: 'سرائیکی', gtCode: 'pa' }, // Saraiki — closest: Punjabi
];

function LanguageSelector({ dropUp } = {}) {
  const [open, setOpen] = React.useState(false);
  const [active, setActive] = React.useState(LANGUAGES[0]);
  const ref = React.useRef(null);
  const userSetRef = React.useRef(false);

  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, []);

  React.useEffect(() => {
    const onGeo = (e) => {
      if (userSetRef.current) return;
      const lang = LANGUAGES.find(l => l.code === e.detail.langCode);
      if (lang) {
        setActive(lang);
        window.loSetLanguage && window.loSetLanguage(lang.gtCode || lang.code);
      }
    };
    window.addEventListener('lo-geo-ready', onGeo);
    return () => window.removeEventListener('lo-geo-ready', onGeo);
  }, []);

  const select = (lang) => {
    userSetRef.current = true;
    try { sessionStorage.setItem('jt_pref_set', '1'); } catch(_) {}
    setActive(lang);
    setOpen(false);
    window.loSetLanguage && window.loSetLanguage(lang.gtCode || lang.code);
  };

  const rtlCodes = ['ar', 'ur', 'ps', 'sd', 'srki'];

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button className="mono" onClick={() => setOpen(o => !o)}
        style={{ color: 'var(--fg-2)', display: 'flex', alignItems: 'center', gap: 5, fontSize: 11 }}>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
          <circle cx="12" cy="12" r="10"/>
          <path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10A15.3 15.3 0 0 1 8 12a15.3 15.3 0 0 1 4-10z"/>
        </svg>
        {active.label}
        <svg width="8" height="5" viewBox="0 0 8 5" fill="none">
          <path d="M1 1l3 3 3-3" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
        </svg>
      </button>
      {open && (
        <div style={{
          position: 'absolute', ...(dropUp ? { bottom: '100%', marginBottom: 8, left: 0 } : { top: '100%', marginTop: 8, right: 0 }),
          background: 'var(--bg)', border: '.5px solid var(--line)',
          minWidth: 210, zIndex: 500,
          boxShadow: '0 8px 32px rgba(0,0,0,.45)',
          maxHeight: 340, overflowY: 'auto',
        }}>
          {LANGUAGES.map(lang => (
            <button key={lang.code} onClick={() => select(lang)}
              className="mono"
              style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                width: '100%', padding: '10px 16px', textAlign: 'left',
                color: lang.code === active.code ? 'var(--fg)' : 'var(--fg-2)',
                background: lang.code === active.code ? 'color-mix(in srgb, var(--fg) 5%, transparent)' : 'transparent',
                fontSize: 11, gap: 12,
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'color-mix(in srgb, var(--fg) 8%, transparent)'}
              onMouseLeave={e => e.currentTarget.style.background = lang.code === active.code ? 'color-mix(in srgb, var(--fg) 5%, transparent)' : 'transparent'}>
              <span style={{ flexShrink: 0 }}>{lang.label}</span>
              <span style={{
                direction: rtlCodes.includes(lang.code) ? 'rtl' : 'ltr',
                color: lang.code === active.code ? 'var(--fg)' : 'var(--fg-3)',
                textAlign: 'right', flex: 1,
              }}>{lang.name}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// Detects mobile viewport — re-renders on resize
function useMobile(bp = 768) {
  const [mobile, setMobile] = React.useState(
    typeof window !== 'undefined' && window.innerWidth <= bp
  );
  React.useEffect(() => {
    const h = () => setMobile(window.innerWidth <= bp);
    window.addEventListener('resize', h, { passive: true });
    return () => window.removeEventListener('resize', h);
  }, [bp]);
  return mobile;
}

function AnnouncementBar() {
  const cfg = (typeof window !== 'undefined' && window.SALE_CONFIG) || {};
  const plan = (typeof window !== 'undefined' && window.activeSalePlan) ? window.activeSalePlan(cfg) : null;
  const sitewide = Math.max(cfg.sitewide || 0, (plan && plan.pct) || 0);
  const categories = cfg.categories || {};
  const items = cfg.items || {};

  const hasSale = sitewide > 0 || Object.keys(categories).length > 0 || Object.keys(items).length > 0;

  let saleText = '';
  if (plan && plan.pct > 0) {
    saleText = (plan.label ? plan.label.toUpperCase() + ' · ' : '') + sitewide + '% OFF';
  } else if (sitewide > 0) {
    saleText = `${sitewide}% OFF — SITEWIDE`;
  } else if (Object.keys(categories).length > 0) {
    const maxPct = Math.max(...Object.values(categories));
    const names = Object.keys(categories).map(k => k.toUpperCase()).join(' · ');
    saleText = `Up to ${maxPct}% OFF — ${names}`;
  } else if (Object.keys(items).length > 0) {
    saleText = 'Sale — selected styles';
  }

  const messages = hasSale && saleText
    ? [
        'Free worldwide shipping — no minimum',
        saleText,
        'Made-to-measure in 2–4 weeks',
        saleText,
      ]
    : [
        'Free worldwide shipping — no minimum',
        'Quality-checked & photographed before shipping',
        'Made-to-measure in 2–4 weeks',
      ];

  const Item = ({ t }) => (
    <>
      <span>{t}</span>
      <svg width="6" height="6" viewBox="0 0 6 6"><circle cx="3" cy="3" r="1.4" fill="currentColor" /></svg>
    </>
  );
  return (
    <div className={`announce${hasSale && saleText ? ' announce--sale' : ''}`} aria-label="Announcements">
      <div className="announce-track">
        <span className="announce-copy">
          {messages.map((m, i) => <React.Fragment key={i}><Item t={m} /></React.Fragment>)}
        </span>
        <span className="announce-copy" aria-hidden="true">
          {messages.map((m, i) => <React.Fragment key={'b' + i}><Item t={m} /></React.Fragment>)}
        </span>
      </div>
    </div>
  );
}

function Nav({ screen, goTo, cartCount, openCart, openSearch }) {
  const [megaOpen, setMegaOpen] = React.useState(null);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [menuTop, setMenuTop] = React.useState(94);
  const [accountOpen, setAccountOpen] = React.useState(false);
  const navRef = React.useRef(null);
  const accountRef = React.useRef(null);

  // Close account dropdown on outside click
  React.useEffect(() => {
    const h = (e) => { if (accountRef.current && !accountRef.current.contains(e.target)) setAccountOpen(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, []);

  const nav = (s, opts) => { setMenuOpen(false); setMegaOpen(null); goTo(s, opts); };

  // Close mobile menu on resize back to desktop
  React.useEffect(() => {
    const h = () => { if (window.innerWidth > 768) setMenuOpen(false); };
    window.addEventListener('resize', h, { passive: true });
    return () => window.removeEventListener('resize', h);
  }, []);

  // Lock body scroll when mobile menu is open
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen]);

  // Capture exact nav bottom so the portal sits flush below it
  React.useEffect(() => {
    if (menuOpen && navRef.current) {
      setMenuTop(navRef.current.getBoundingClientRect().bottom);
    }
  }, [menuOpen]);

  return (
    <>
      <header ref={navRef} className="nav" data-screen-label="" onMouseLeave={() => setMegaOpen(null)}>
        <div className="nav-inner">

          {/* Desktop links — hidden on mobile via CSS */}
          <nav className="nav-links" aria-label="Primary">
            <a className={`nav-link ${megaOpen === 'men' || screen === 'collection' ? 'active' : ''}`}
               href="/collection?gender=Men"
               onMouseEnter={() => setMegaOpen('men')}
               onClick={(e) => { e.preventDefault(); nav('collection', { gender: 'Men' }); }}>Men</a>
            <a className={`nav-link ${megaOpen === 'women' ? 'active' : ''}`}
               href="/collection?gender=Women"
               onMouseEnter={() => setMegaOpen('women')}
               onClick={(e) => { e.preventDefault(); nav('collection', { gender: 'Women' }); }}>Women</a>
            <a className="nav-link"
               href="/luxury"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('collection', { season: 'Luxury' }); }}
               style={{ color: 'var(--crimson, #A31620)' }}>Luxury</a>
            <a className={`nav-link ${screen === 'collections' ? 'active' : ''}`}
               href="/collections"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('collections'); }}>Collections</a>
            <a className="nav-link"
               href="/bespoke"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); setMegaOpen(null); window.openBespoke && window.openBespoke(); }}
               style={{ color: 'var(--crimson, #A31620)', letterSpacing: '.08em' }}>Bespoke</a>
            <a className={`nav-link ${screen === 'journal' ? 'active' : ''}`}
               href="/journal"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('journal'); }}>Journal</a>
            <a className={`nav-link ${screen === 'faq' ? 'active' : ''}`}
               href="/faq"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('faq'); }}>FAQ</a>
            <a className={`nav-link ${screen === 'about' ? 'active' : ''}`}
               href="/about"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('about'); }}>About</a>
            <a className={`nav-link ${screen === 'contact' ? 'active' : ''}`}
               href="/contact"
               onMouseEnter={() => setMegaOpen(null)}
               onClick={(e) => { e.preventDefault(); nav('contact'); }}>Contact</a>
          </nav>

          {/* Mobile hamburger — visible via CSS on ≤768px */}
          <button className="nav-hamburger icon-btn" aria-label={menuOpen ? 'Close menu' : 'Open menu'}
            onClick={() => setMenuOpen((o) => !o)}>
            {menuOpen
              ? <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.3">
                  <line x1="3" y1="3" x2="15" y2="15" /><line x1="15" y1="3" x2="3" y2="15" />
                </svg>
              : <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.4">
                  <line x1="3" y1="5" x2="15" y2="5" strokeLinecap="round" />
                  <line x1="3" y1="9" x2="15" y2="9" strokeLinecap="round" />
                  <line x1="3" y1="13" x2="15" y2="13" strokeLinecap="round" />
                </svg>}
          </button>

          {/* Brand — always center */}
          <a className="brand" href="/" onClick={(e) => { e.preventDefault(); nav('home'); }} aria-label="JT Atelier home"
            style={{ justifySelf: 'center' }}>
            <img src="assets/logo.png" alt=""
              style={{ width: 36, height: 36, objectFit: 'contain',
                filter: 'drop-shadow(0 0 10px rgba(212,175,55,.22))' }} />
            <span style={{ letterSpacing: '.04em' }}>JT <span style={{ color: 'var(--crimson)', letterSpacing: '.2em' }}>ATELIER</span></span>
          </a>

          {/* Actions */}
          <div className="nav-actions">
            <span className="nav-hide-mobile"><LanguageSelector /></span>
            <span className="nav-hide-mobile"><CurrencySelector /></span>
            <button className="icon-btn" onClick={openSearch} aria-label="Search">
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.3">
                <circle cx="8" cy="8" r="5.5" />
                <line x1="12.2" y1="12.2" x2="16" y2="16" strokeLinecap="round" />
              </svg>
            </button>
            <div ref={accountRef} className="nav-hide-mobile" style={{ position: 'relative' }}>
              <button className="icon-btn" aria-label="Account" onClick={() => setAccountOpen(o => !o)}
                style={{ color: accountOpen ? 'var(--fg)' : 'var(--fg-2)' }}>
                <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.3">
                  <circle cx="9" cy="6.5" r="3.2" />
                  <path d="M2.5 16c.8-3.4 3.4-5.2 6.5-5.2s5.7 1.8 6.5 5.2" strokeLinecap="round" />
                </svg>
              </button>
              {accountOpen && (
                <div style={{
                  position: 'absolute', top: '100%', right: 0, marginTop: 10,
                  background: 'var(--bg)', border: '.5px solid var(--line)',
                  minWidth: 220, zIndex: 500,
                  boxShadow: '0 8px 32px rgba(0,0,0,.45)',
                }}>
                  <button onClick={() => { setAccountOpen(false); goTo('account'); }}
                    style={{ display: 'flex', flexDirection: 'column', gap: 3, width: '100%', padding: '14px 18px', textAlign: 'left', background: 'transparent', borderBottom: '.5px solid var(--line-2)', cursor: 'pointer' }}
                    onMouseEnter={e => e.currentTarget.style.background = 'color-mix(in srgb, var(--fg) 5%, transparent)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <span style={{ fontSize: 13, color: 'var(--fg)', letterSpacing: '.02em' }}>My Account</span>
                    <span style={{ fontSize: 10, color: 'var(--fg-3)', letterSpacing: '.1em', textTransform: 'uppercase', fontFamily: 'var(--font-mono)' }}>Order history &amp; tracking</span>
                  </button>
                  <button onClick={() => { setAccountOpen(false); goTo('affiliate-portal'); }}
                    style={{ display: 'flex', flexDirection: 'column', gap: 3, width: '100%', padding: '14px 18px', textAlign: 'left', background: 'transparent', cursor: 'pointer' }}
                    onMouseEnter={e => e.currentTarget.style.background = 'color-mix(in srgb, var(--fg) 5%, transparent)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <span style={{ fontSize: 13, color: 'var(--fg)', letterSpacing: '.02em' }}>Affiliate Portal</span>
                    <span style={{ fontSize: 10, color: 'var(--fg-3)', letterSpacing: '.1em', textTransform: 'uppercase', fontFamily: 'var(--font-mono)' }}>Partner dashboard</span>
                  </button>
                </div>
              )}
            </div>
            <button className="icon-btn" onClick={openCart} aria-label="Cart">
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.3">
                <path d="M3.2 5.2h11.6l-1.1 9.6a1 1 0 0 1-1 .9H5.3a1 1 0 0 1-1-.9L3.2 5.2Z" />
                <path d="M6.4 7.2V4.6a2.6 2.6 0 0 1 5.2 0v2.6" />
              </svg>
              {cartCount > 0 && <span className="cart-count" key={cartCount}>{cartCount}</span>}
            </button>
          </div>
        </div>

        <MegaMenu open={megaOpen} goTo={goTo} close={() => setMegaOpen(null)} />
      </header>

      {/* Mobile menu — portalled into document.body to escape the header's
          backdrop-filter stacking context (which traps position:fixed children) */}
      {menuOpen && ReactDOM.createPortal(
        <div className="mobile-menu" style={{ top: menuTop }}>
          {[
            { label: 'Men',     action: () => nav('collection', { gender: 'Men' }) },
            { label: 'Women',   action: () => nav('collection', { gender: 'Women' }) },
            { label: <><em style={{color:'var(--gold,#d4af37)'}}>Luxury</em></>, action: () => nav('collection', { season: 'Luxury' }) },
            { label: 'Collections', action: () => nav('collections') },
            { label: <><em style={{color:'var(--crimson,#A31620)'}}>Bespoke</em></>, action: () => { setMenuOpen(false); window.openBespoke && window.openBespoke(); } },
            { label: 'Journal', action: () => nav('journal') },
            { label: 'FAQ',     action: () => nav('faq') },
            { label: 'About',   action: () => nav('about') },
            { label: 'Contact', action: () => nav('contact') },
            { label: 'My Account',       action: () => nav('account') },
            { label: 'Affiliate Portal', action: () => nav('affiliate-portal') },
          ].map((item, i) => (
            <div key={i} className="mobile-nav-link" onClick={item.action}>
              <span>{item.label}</span>
              <span className="arrow">→</span>
            </div>
          ))}

          <div className="mobile-menu-foot">
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <span className="mono" style={{ color: 'var(--fg-3)' }}>Language</span>
              <LanguageSelector />
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <span className="mono" style={{ color: 'var(--fg-3)' }}>Currency</span>
              <CurrencySelector />
            </div>
            <a href="https://wa.me/12345678901" target="_blank" rel="noopener"
              className="mono"
              style={{ color: 'var(--fg-2)', display: 'flex', alignItems: 'center', gap: 8 }}>
              <svg width="16" height="16" viewBox="0 0 32 32" fill="currentColor">
                <path d="M16 .5C7.44.5.5 7.44.5 16c0 2.72.69 5.27 1.9 7.5L.5 31.5l8.27-1.87A15.47 15.47 0 0016 31.5C24.56 31.5 31.5 24.56 31.5 16S24.56.5 16 .5zm0 28.3c-2.46 0-4.76-.66-6.74-1.8l-.48-.29-4.91 1.11 1.14-4.77-.32-.5A12.47 12.47 0 013.47 16C3.47 9.09 9.09 3.47 16 3.47S28.53 9.09 28.53 16 22.91 28.8 16 28.8zm6.84-9.33c-.37-.19-2.2-1.09-2.54-1.21-.34-.13-.58-.19-.83.19-.24.37-.95 1.21-1.16 1.46-.21.25-.43.28-.8.09-.37-.19-1.57-.58-2.99-1.84-1.1-.98-1.85-2.2-2.07-2.57-.21-.37-.02-.57.16-.75.17-.17.37-.43.56-.65.19-.21.25-.37.38-.62.12-.25.06-.46-.03-.65-.09-.19-.83-2.01-1.14-2.76-.3-.72-.61-.62-.83-.63h-.71c-.25 0-.65.09-.99.46-.34.37-1.3 1.27-1.3 3.1s1.33 3.6 1.52 3.85c.18.25 2.62 4 6.36 5.61.89.38 1.58.61 2.12.78.89.28 1.7.24 2.34.15.71-.11 2.2-.9 2.51-1.77.31-.87.31-1.62.22-1.77-.09-.16-.34-.25-.71-.44z"/>
              </svg>
              Chat on WhatsApp
            </a>
            {CONTACT.email && (
              <a href={`mailto:${CONTACT.email}`} className="mono"
                style={{ color: 'var(--fg-2)' }}>
                {CONTACT.email}
              </a>
            )}
          </div>
        </div>,
        document.body
      )}
    </>
  );
}

function MegaMenu({ open, goTo, close }) {
  if (!open) return null;
  const loPrice = useCurrency();
  const CATS = {
    men: [
      ['Biker Jackets',      'Biker',       'Men'],
      ['Bomber Jackets',     'Bomber',      'Men'],
      ['Café Racer',         'Café Racer',  'Men'],
      ['Aviator Jackets',    'Aviator',     'Men'],
      ['Blazers & Suits',    'Blazer',      'Men'],
      ['Leather Coats',      'Coat',        'Men'],
      ['Leather Vests',      'Vest',        'Men'],
      ['Hooded Jackets',     'Hooded',      'Men'],
      ['Countryside',        'Countryside', 'Men'],
      ['Leather Pants',      'Pants',       'Men'],
      ['Sets',               'Sets',        'Men'],
    ],
    women: [
      ['Biker Jackets',     'Biker',      'Women'],
      ['Café Racer',        'Café Racer', 'Women'],
      ['Long Coats',        'Coat',       'Women'],
      ['Blazers',           'Blazer',     'Women'],
      ['Leather Vests',     'Vest',       'Women'],
      ['Bomber Jackets',    'Bomber',     'Women'],
      ['Hooded Jackets',    'Hooded',     'Women'],
      ['Leather Pants',     'Pants',      'Women'],
      ['Sets',              'Sets',       'Women'],
      ['Skirts & Shorts',   'Skirts',     'Women'],
    ],
  };
  const cats = CATS[open] || [];
  const featured = PRODUCTS.filter((p) => p.gender === (open === 'men' ? 'Men' : 'Women')).slice(0, 2);

  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, top: '100%',
      background: 'color-mix(in srgb, var(--bg) 96%, transparent)',
      backdropFilter: 'blur(20px) saturate(140%)',
      borderTop: '.5px solid var(--line)',
      borderBottom: '.5px solid var(--line)',
      animation: 'mmIn .25s ease',
      zIndex: 90,
    }}>
      <style>{`@keyframes mmIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}`}</style>
      <div className="container" style={{
        display: 'grid', gridTemplateColumns: '1.2fr 2fr', gap: 60,
        padding: '40px 0 48px',
      }}>
        <div>
          <div className="eyebrow" style={{ marginBottom: 20 }}>
            ◇ &nbsp; {open === 'men' ? "Men's leatherwear" : "Women's leatherwear"}
          </div>
          <div className="display" style={{ fontSize: 64, lineHeight: 1, marginBottom: 18 }}>
            {open === 'men' ? <>Built to <em>weather.</em></> : <>Cut to <em>occasion.</em></>}
          </div>
          <p style={{ fontSize: 13, color: 'var(--fg-2)', lineHeight: 1.6, maxWidth: 360 }}>
            {open === 'men'
              ? "Bikers, bombers, café racers and coats. Full-grain leather, made-to-measure in 2–4 weeks."
              : "Tailored jackets, blazers, coats and vests cut closer to the body. Top-grain leather, smaller hardware."}
          </p>
          <button className="btn sm" style={{ marginTop: 24 }}
            onClick={() => { close(); goTo('collection', { gender: open === 'men' ? 'Men' : 'Women' }); }}>
            Shop all {open === 'men' ? "men's" : "women's"} <span className="arrow">→</span>
          </button>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 24 }}>
          <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 12, gridColumn: 'span 2' }}>
            {cats.map(([label, cat, gender]) => (
              <li key={label}>
                <a className="mono"
                  href={`/collection?gender=${encodeURIComponent(gender)}&cat=${encodeURIComponent(cat)}`}
                  style={{ color: 'var(--fg)', cursor: 'pointer' }}
                  onMouseEnter={(e) => e.currentTarget.style.color = 'var(--fg-2)'}
                  onMouseLeave={(e) => e.currentTarget.style.color = 'var(--fg)'}
                  onClick={(e) => { e.preventDefault(); close(); goTo('collection', { gender, category: cat }); }}>
                  {label}
                </a>
              </li>
            ))}
          </ul>
          {featured.map((p) => (
            <div key={p.id} className="card" onClick={() => { close(); goTo('product', { product: p }); }}
              style={{ cursor: 'pointer' }}>
              <div style={{
                aspectRatio: '3/4', overflow: 'hidden', background: 'var(--surface)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {p.images && p.images[0]
                  ? <img src={p.images[0]} alt={p.frenchName || p.name}
                      style={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block' }} />
                  : <Editorial product={p} ratio="3/4" style={{ aspectRatio: '3/4' }} />
                }
              </div>
              <div style={{
                paddingTop: 12, display: 'flex', justifyContent: 'space-between',
                fontFamily: 'var(--font-mono)', fontSize: 10,
                letterSpacing: '.14em', textTransform: 'uppercase',
              }}>
                <span>{p.frenchName || p.name}</span>
                <span style={{ color: 'var(--fg-2)' }}>{loPrice(p.price)}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── Email capture strip ──────────────────────────────────────────────
function EmailCapture() {
  const [email, setEmail] = React.useState('');
  const [done, setDone] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      setErr('Please enter a valid email address.');
      return;
    }
    setErr('');
    setBusy(true);
    try {
      const r = await fetch('/api/subscribe', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, source: 'newsletter' }),
      });
      const d = await r.json();
      if (!r.ok) {
        setErr(d.error || 'Something went wrong. Please try again.');
        return;
      }
      setDone(true);
    } catch {
      setErr('Something went wrong. Please try again.');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{
      background: 'var(--surf)',
      borderTop: '.5px solid var(--line)',
      borderBottom: '.5px solid var(--line)',
      padding: '80px 0',
      marginTop: 120,
    }}>
      <div className="container email-capture-grid" style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 60,
        alignItems: 'center', flexWrap: 'wrap',
      }}>
        <div>
          <div className="eyebrow" style={{ marginBottom: 14 }}>◇ &nbsp; The edit</div>
          <h2 className="display" style={{ fontSize: 'clamp(40px, 5vw, 72px)', margin: 0, lineHeight: 1 }}>
            New drops, first.<br />
            <em className="gradient-text">No noise.</em>
          </h2>
          <p style={{ fontSize: 14, color: 'var(--fg-2)', lineHeight: 1.7, marginTop: 20, maxWidth: 380 }}>
            We send one email per drop — new collections, bespoke availability, and
            care guides from the atelier. Nothing else.
          </p>
        </div>
        <div>
          {done ? (
            <div style={{ textAlign: 'center', padding: '32px 0' }}>
              <div className="display" style={{ fontSize: 48 }}><em>✓</em></div>
              <div className="mono" style={{ color: 'var(--fg-2)', marginTop: 12 }}>
                You're in. We'll be in touch.
              </div>
              <div className="mono" style={{ marginTop: 16, fontSize: 11 }}>
                Use code{' '}
                <span style={{
                  display: 'inline-block', padding: '4px 12px',
                  border: '1px solid var(--crimson)', color: 'var(--crimson)',
                  letterSpacing: '.18em', fontWeight: 700,
                }}>WELCOME10</span>
                {' '}at checkout for 10% off your first order.
              </div>
            </div>
          ) : (
            <form onSubmit={submit}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                <div style={{ display: 'flex', gap: 0 }}>
                  <input
                    type="email"
                    value={email}
                    onChange={e => { setEmail(e.target.value); setErr(''); }}
                    placeholder="your@email.com"
                    disabled={busy}
                    style={{
                      flex: 1, padding: '16px 20px',
                      background: 'transparent',
                      border: '.5px solid var(--line-2)',
                      borderRight: 'none',
                      color: 'var(--fg)',
                      fontFamily: 'var(--font-mono)', fontSize: 11,
                      letterSpacing: '.14em',
                      outline: 'none',
                      opacity: busy ? 0.5 : 1,
                    }}
                    onFocus={e => e.target.style.borderColor = 'var(--fg)'}
                    onBlur={e => e.target.style.borderColor = ''}
                  />
                  <button type="submit" className="btn" disabled={busy} style={{ padding: '16px 28px', flexShrink: 0, opacity: busy ? 0.6 : 1 }}>
                    {busy ? '…' : <span>Join <span className="arrow">→</span></span>}
                  </button>
                </div>
                {err && (
                  <div className="mono" style={{ color: 'var(--fg-3)', fontSize: 10 }}>{err}</div>
                )}
                <div className="mono" style={{ color: 'var(--fg-3)', fontSize: 10 }}>
                  10% off your first order · Unsubscribe any time
                </div>
              </div>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Currency selector ────────────────────────────────────────────────
const CURRENCIES = [
  { code: 'USD', symbol: '$',   label: 'US Dollar',         rate: 1       },
  { code: 'EUR', symbol: '€',   label: 'Euro',              rate: 0.92    },
  { code: 'GBP', symbol: '£',   label: 'British Pound',     rate: 0.79    },
  { code: 'CAD', symbol: 'C$',  label: 'Canadian Dollar',   rate: 1.37    },
  { code: 'AUD', symbol: 'A$',  label: 'Australian Dollar', rate: 1.55    },
  { code: 'AED', symbol: 'د.إ', label: 'UAE Dirham',        rate: 3.67    },
  { code: 'PKR', symbol: '₨',   label: 'Pakistani Rupee',   rate: 280.50  },
  { code: 'INR', symbol: '₹',   label: 'Indian Rupee',      rate: 84.20   },
];

// Expose a global convert function so ProductCard / Product can use it
function initCurrency() {
  window.LO_CURRENCY = window.LO_CURRENCY || { code: 'USD', symbol: '$', rate: 1 };
  window.loPrice = function(usdPrice) {
    const c = window.LO_CURRENCY;
    const converted = Math.round(usdPrice * c.rate);
    return c.symbol + converted.toLocaleString();
  };
}
initCurrency();

// ── Geo-detect on first load → auto-set language + currency ──────────
(async function initGeoDefaults() {
  try { if (sessionStorage.getItem('jt_pref_set')) return; } catch(_) {}
  try {
    let geo;
    try {
      const hit = localStorage.getItem('jt_geo');
      if (hit) {
        const parsed = JSON.parse(hit);
        if (Date.now() - parsed.ts < 86400000) geo = parsed;
      }
    } catch(_) {}

    if (!geo) {
      const ctrl = new AbortController();
      const tid  = setTimeout(() => ctrl.abort(), 5000);
      let res;
      try { res = await fetch('https://ipapi.co/json/', { signal: ctrl.signal }); }
      finally { clearTimeout(tid); }
      if (!res || !res.ok) return;
      const d = await res.json();
      if (d.error) return;
      geo = { cc: d.country_code, cur: d.currency, ts: Date.now() };
      try { localStorage.setItem('jt_geo', JSON.stringify(geo)); } catch(_) {}
    }

    const langCode = GEO_LANG_MAP[geo.cc] || 'en';
    const currCode = GEO_CURRENCY_SUPPORT.has(geo.cur) ? geo.cur : 'USD';
    window.dispatchEvent(new CustomEvent('lo-geo-ready', { detail: { langCode, currCode } }));
  } catch(_) { /* network fail — stay at defaults */ }
})();

// Hook: subscribe to currency changes and return a live price formatter.
// Use this in any component that displays prices so they update automatically.
function useCurrency() {
  const [, tick] = React.useReducer((n) => n + 1, 0);
  React.useEffect(() => {
    const h = () => tick();
    window.addEventListener('lo-currency-change', h);
    return () => window.removeEventListener('lo-currency-change', h);
  }, []);
  return (usdPrice) => window.loPrice(usdPrice);
}

function CurrencySelector({ dropUp } = {}) {
  const [open, setOpen] = React.useState(false);
  const [active, setActive] = React.useState(window.LO_CURRENCY || CURRENCIES[0]);
  const ref = React.useRef(null);
  const userSetRef = React.useRef(false);

  React.useEffect(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  React.useEffect(() => {
    const onGeo = (e) => {
      if (userSetRef.current) return;
      const c = CURRENCIES.find(c => c.code === e.detail.currCode);
      if (c) {
        window.LO_CURRENCY = c;
        window.loPrice = (usdPrice) => c.symbol + Math.round(usdPrice * c.rate).toLocaleString();
        setActive(c);
        window.dispatchEvent(new CustomEvent('lo-currency-change', { detail: c }));
      }
    };
    window.addEventListener('lo-geo-ready', onGeo);
    return () => window.removeEventListener('lo-geo-ready', onGeo);
  }, []);

  const select = (c) => {
    userSetRef.current = true;
    try { sessionStorage.setItem('jt_pref_set', '1'); } catch(_) {}
    window.LO_CURRENCY = c;
    window.loPrice = (usdPrice) => c.symbol + Math.round(usdPrice * c.rate).toLocaleString();
    setActive(c);
    setOpen(false);
    window.dispatchEvent(new CustomEvent('lo-currency-change', { detail: c }));
  };

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button className="mono" onClick={() => setOpen(o => !o)}
        style={{ color: 'var(--fg-2)', display: 'flex', alignItems: 'center', gap: 5, fontSize: 11 }}>
        {active.code}
        <svg width="8" height="5" viewBox="0 0 8 5" fill="none">
          <path d="M1 1l3 3 3-3" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round"/>
        </svg>
      </button>
      {open && (
        <div style={{
          position: 'absolute', ...(dropUp ? { bottom: '100%', marginBottom: 8, left: 0 } : { top: '100%', marginTop: 8, right: 0 }),
          background: 'var(--bg)',
          border: '.5px solid var(--line)',
          minWidth: 200, zIndex: 500,
          boxShadow: '0 8px 32px rgba(0,0,0,.4)',
        }}>
          {CURRENCIES.map(c => (
            <button key={c.code} onClick={() => select(c)}
              className="mono"
              style={{
                display: 'flex', justifyContent: 'space-between',
                width: '100%', padding: '12px 16px', textAlign: 'left',
                color: c.code === active.code ? 'var(--fg)' : 'var(--fg-2)',
                background: c.code === active.code ? 'color-mix(in srgb, var(--fg) 5%, transparent)' : 'transparent',
                fontSize: 11,
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'color-mix(in srgb, var(--fg) 8%, transparent)'}
              onMouseLeave={e => e.currentTarget.style.background = c.code === active.code ? 'color-mix(in srgb, var(--fg) 5%, transparent)' : 'transparent'}>
              <span>{c.code} · {c.label}</span>
              <span style={{ color: 'var(--fg-3)' }}>{c.symbol}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Social video feed ────────────────────────────────────────────────
// Curated TikTok + Instagram videos. Links are entered in the admin
// "Socials" tab and stored in the DB — this never scrapes the accounts.
// Each pasted URL is turned into a native embed iframe (no third-party
// embed.js, no tracking pixels).
function socialEmbed(item) {
  const url = (item && item.url) || '';
  if (item.platform === 'tiktok') {
    const m = url.match(/\/video\/(\d+)/) || url.match(/[?&]item_id=(\d+)/);
    if (m) return { kind: 'tiktok', src: 'https://www.tiktok.com/embed/v2/' + m[1] };
    return null;
  }
  if (item.platform === 'instagram') {
    const m = url.match(/instagram\.com\/(p|reel|tv|reels)\/([A-Za-z0-9_-]+)/);
    if (m) {
      const type = m[1] === 'reels' ? 'reel' : m[1];
      return { kind: 'instagram', src: 'https://www.instagram.com/' + type + '/' + m[2] + '/embed' };
    }
    return null;
  }
  return null;
}

function SocialFeed() {
  const [items, setItems] = React.useState(null);

  React.useEffect(() => {
    let alive = true;
    fetch('/api/admin?a=get-social-feed')
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (alive) setItems((d && d.items) || []); })
      .catch(() => { if (alive) setItems([]); });
    return () => { alive = false; };
  }, []);

  if (!items || !items.length) return null;
  const cards = items.map(socialEmbed).filter(Boolean);
  if (!cards.length) return null;

  return (
    <section style={{
      borderTop: '.5px solid var(--line)',
      padding: 'clamp(64px,9vw,110px) 0 clamp(48px,7vw,90px)',
    }}>
      <div className="container">
        <div style={{ textAlign: 'center', marginBottom: 'clamp(36px,5vw,64px)' }}>
          <div className="eyebrow" style={{ marginBottom: 16 }}>◇ &nbsp; The feed</div>
          <h2 className="display" style={{ fontSize: 'clamp(36px,5vw,68px)', margin: 0, lineHeight: 1 }}>
            <em>Seen on social.</em>
          </h2>
          <p style={{ fontSize: 13, color: 'var(--fg-2)', lineHeight: 1.7, marginTop: 16, maxWidth: 420, marginLeft: 'auto', marginRight: 'auto' }}>
            A few of our favourite moments from TikTok and Instagram.
          </p>
        </div>
        <div style={{
          display: 'flex', gap: 'clamp(16px,2vw,28px)',
          overflowX: 'auto', paddingBottom: 12,
          scrollSnapType: 'x mandatory',
          justifyContent: cards.length <= 3 ? 'center' : 'flex-start',
          WebkitOverflowScrolling: 'touch',
        }}>
          {cards.map((c, i) => (
            <div key={i} style={{
              flex: '0 0 auto', width: 'min(86vw, 325px)',
              scrollSnapAlign: 'center',
              border: '.5px solid var(--line)',
              background: 'var(--surf)',
              borderRadius: 4, overflow: 'hidden',
            }}>
              <iframe
                src={c.src}
                title={c.kind === 'tiktok' ? 'TikTok video' : 'Instagram video'}
                loading="lazy"
                allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
                allowFullScreen
                scrolling="no"
                style={{
                  width: '100%',
                  height: c.kind === 'tiktok' ? 575 : 640,
                  border: 'none', display: 'block', background: 'var(--surf)',
                }}
              />
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Footer({ openNewsletter, goTo }) {
  return (
    <footer style={{
      borderTop: '.5px solid var(--line)',
      padding: '100px 0 40px',
      marginTop: 120,
    }}>
      <div className="container">
        {/* Visual masthead */}
        <div className="footer-masthead" style={{
          display: 'flex', alignItems: 'flex-end', gap: 'clamp(20px, 3vw, 48px)',
          margin: '0 0 80px',
        }}>
          <img src="assets/logo.png" alt=""
            style={{
              width: 'clamp(120px, 14vw, 220px)', height: 'auto',
              flexShrink: 0,
              filter: 'drop-shadow(0 0 24px rgba(212,175,55,.18))',
            }} />
          <div style={{
            fontWeight: 400,
            lineHeight: .9,
          }}>
            <div className="wordmark" style={{
              fontSize: 'clamp(64px, 14vw, 240px)',
              letterSpacing: '-.01em',
              lineHeight: 1,
            }}>JT</div>
            <div style={{
              fontSize: 'clamp(18px, 3.8vw, 64px)',
              letterSpacing: '.28em',
              textTransform: 'uppercase',
              color: 'var(--crimson)',
              fontFamily: 'var(--font-display)',
              marginTop: '0.12em',
            }}>ATELIER</div>
          </div>
        </div>

        <div className="footer-links-grid" style={{
          display: 'grid',
          gridTemplateColumns: '1.6fr 1fr 1fr 1fr 1.2fr',
          gap: 50, alignItems: 'start',
          paddingBottom: 80,
        }}>
          <div>
            <p style={{
              fontSize: 13, lineHeight: 1.7, color: 'var(--fg-2)',
              maxWidth: 320, margin: 0,
            }}>
              A made-to-order atelier for bespoke leather outerwear.
            </p>
            <button className="btn ghost sm" style={{ marginTop: 28 }} onClick={openNewsletter}>
              Join the studio list <span className="arrow">→</span>
            </button>
          </div>

          <div>
            <div className="eyebrow" style={{ marginBottom: 22 }}>Shop</div>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 12 }}>
              {[
                ['Men',          () => goTo('collection', { gender: 'Men' }),             '/collection?gender=Men'],
                ['Women',        () => goTo('collection', { gender: 'Women' }),           '/collection?gender=Women'],
                ['Luxury Edit',  () => goTo('collection', { season: 'Luxury' }),          '/luxury'],
                ['Bikers',       () => goTo('collection', { category: 'Biker' }),         '/collection?cat=Biker'],
                ['Bombers',      () => goTo('collection', { category: 'Bomber' }),        '/collection?cat=Bomber'],
                ['Café Racers',  () => goTo('collection', { category: 'Café Racer' }),   '/collection?cat=Caf%C3%A9+Racer'],
                ['Aviators',     () => goTo('collection', { category: 'Aviator' }),       '/collection?cat=Aviator'],
                ['Coats',        () => goTo('collection', { category: 'Coat' }),          '/collection?cat=Coat'],
                ['Vests',        () => goTo('collection', { category: 'Vest' }),          '/collection?cat=Vest'],
                ['Leather Pants',() => goTo('collection', { category: 'Pants' }),         '/collection?cat=Pants'],
                ['Sets',         () => goTo('collection', { category: 'Sets' }),          '/collection?cat=Sets'],
                ['Skirts',       () => goTo('collection', { category: 'Skirts' }),        '/collection?cat=Skirts'],
              ].map(([l, fn, href]) => (
                <li key={l}><a href={href} style={{ fontSize: 13, opacity: .82, cursor: 'pointer' }}
                  onMouseEnter={(e) => e.currentTarget.style.opacity = 1}
                  onMouseLeave={(e) => e.currentTarget.style.opacity = .82}
                  onClick={(e) => { e.preventDefault(); fn(); }}>{l}</a></li>
              ))}
            </ul>
          </div>

          <div>
            <div className="eyebrow" style={{ marginBottom: 22 }}>Studio</div>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 12 }}>
              {[
                ['Our story',         () => goTo('about'),                               '/about'],
                ['Bespoke programme', () => window.openBespoke && window.openBespoke(),  '/bespoke'],
                ['Journal',           () => goTo('journal'),                             '/journal'],
                ['Contact us',        () => goTo('contact'),                             '/contact'],
              ].map(([label, fn, href]) => (
                <li key={label}><a href={href} style={{ fontSize: 13, opacity: .82, cursor: 'pointer' }}
                  onMouseEnter={(e) => e.currentTarget.style.opacity = 1}
                  onMouseLeave={(e) => e.currentTarget.style.opacity = .82}
                  onClick={(e) => { e.preventDefault(); fn(); }}>{label}</a></li>
              ))}
            </ul>
          </div>

          <div>
            <div className="eyebrow" style={{ marginBottom: 22 }}>Service</div>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 12 }}>
              {[
                ['Sizing guide',   () => goTo('sizing'),   '/sizing'],
                ['Free shipping',  () => goTo('shipping'), '/shipping'],
                ['Returns policy', () => goTo('returns'),  '/returns'],
                ['Track my order', () => goTo('contact'),  '/contact'],
                ['FAQs',           () => goTo('faq'),      '/faq'],
              ].map(([label, fn, href]) => (
                <li key={label}><a href={href} style={{ fontSize: 13, opacity: .82, cursor: 'pointer' }}
                  onMouseEnter={(e) => e.currentTarget.style.opacity = 1}
                  onMouseLeave={(e) => e.currentTarget.style.opacity = .82}
                  onClick={(e) => { e.preventDefault(); fn(); }}>{label}</a></li>
              ))}
            </ul>
          </div>

          <div>
            <div className="eyebrow" style={{ marginBottom: 22 }}>Atelier</div>
            <address style={{ fontStyle: 'normal', fontSize: 13, lineHeight: 1.65, color: 'var(--fg-2)' }}>
              {CONTACT.address1}<br />
              {CONTACT.address2}
            </address>
            <div style={{ marginTop: 18, display: 'flex', flexDirection: 'column', gap: 6 }}>
              <a href={`mailto:${CONTACT.email}`}
                style={{ fontSize: 13, color: 'var(--fg)', textDecoration: 'none' }}
                onMouseEnter={(e) => e.currentTarget.style.opacity = .7}
                onMouseLeave={(e) => e.currentTarget.style.opacity = 1}>
                {CONTACT.email}
              </a>
              {CONTACT.phone && (
                <a href={`tel:${CONTACT.phone.replace(/[^+\d]/g, '')}`}
                  style={{ fontSize: 13, color: 'var(--fg)', textDecoration: 'none' }}>
                  {CONTACT.phone}
                </a>
              )}
            </div>
            <div className="mono" style={{ color: 'var(--fg-2)', marginTop: 16, lineHeight: 1.8 }}>
              {CONTACT.hoursWk}<br />
              {CONTACT.hoursSu}<br />
              WhatsApp support
            </div>
          </div>
        </div>

        <div className="rule" />

        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          padding: '28px 0 0', flexWrap: 'wrap', gap: 18,
        }}>
          <div className="mono" style={{ color: 'var(--fg-3)' }}>
            © 2026 JT Atelier · All rights reserved
          </div>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
            {[
              ['Privacy Policy', () => goTo('privacy'),  '/privacy'],
              ['Returns',        () => goTo('returns'),  '/returns'],
              ['Shipping',       () => goTo('shipping'), '/shipping'],
              ['Terms',          () => goTo('terms'),    '/terms'],
            ].map(([l, fn, href]) => (
              <a key={l} href={href}
                className="mono" style={{ color: 'var(--fg-3)', fontSize: 9.5 }}
                onMouseEnter={(e) => e.currentTarget.style.color = 'var(--fg)'}
                onMouseLeave={(e) => e.currentTarget.style.color = ''}
                onClick={(e) => { e.preventDefault(); fn(); }}>{l}</a>
            ))}
          </div>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
            {SOCIAL.map((s) => (
              <a key={s.id} href={s.url} target="_blank" rel="noopener noreferrer"
                style={{ color: 'var(--fg-3)' }}
                onMouseEnter={(e) => e.currentTarget.style.color = 'var(--fg)'}
                onMouseLeave={(e) => e.currentTarget.style.color = ''}>
                <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-label={s.label}>
                  {s.icon}
                </svg>
              </a>
            ))}
          </div>
        </div>
      </div>
    </footer>
  );
}

// ── WhatsApp floating button ──────────────────────────────────────────
// Update WA_NUMBER to the business WhatsApp number (digits only, with country code)
const WA_NUMBER = '923402730579';

function WhatsApp() {
  return (
    <a href={`https://wa.me/${WA_NUMBER}?text=Hi%2C%20I%27m%20interested%20in%20a%20JT%20Atelier%20piece.`}
      className="wa-btn"
      target="_blank" rel="noopener noreferrer"
      aria-label="Chat on WhatsApp">
      <svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
        <path d="M16 .5C7.44.5.5 7.44.5 16c0 2.72.69 5.27 1.9 7.5L.5 31.5l8.27-1.87A15.47 15.47 0 0016 31.5C24.56 31.5 31.5 24.56 31.5 16S24.56.5 16 .5zm0 28.3c-2.46 0-4.76-.66-6.74-1.8l-.48-.29-4.91 1.11 1.14-4.77-.32-.5A12.47 12.47 0 013.47 16C3.47 9.09 9.09 3.47 16 3.47S28.53 9.09 28.53 16 22.91 28.8 16 28.8zm6.84-9.33c-.37-.19-2.2-1.09-2.54-1.21-.34-.13-.58-.19-.83.19-.24.37-.95 1.21-1.16 1.46-.21.25-.43.28-.8.09-.37-.19-1.57-.58-2.99-1.84-1.1-.98-1.85-2.2-2.07-2.57-.21-.37-.02-.57.16-.75.17-.17.37-.43.56-.65.19-.21.25-.37.38-.62.12-.25.06-.46-.03-.65-.09-.19-.83-2.01-1.14-2.76-.3-.72-.61-.62-.83-.63h-.71c-.25 0-.65.09-.99.46-.34.37-1.3 1.27-1.3 3.1s1.33 3.6 1.52 3.85c.18.25 2.62 4 6.36 5.61.89.38 1.58.61 2.12.78.89.28 1.7.24 2.34.15.71-.11 2.2-.9 2.51-1.77.31-.87.31-1.62.22-1.77-.09-.16-.34-.25-.71-.44z"/>
      </svg>
      <span className="wa-tooltip">Chat with us</span>
    </a>
  );
}

// ── Phase 1: Editorial "Alta Moda"-style chrome (flag-gated: ?ux=editorial) ──
// Additive overlay. Default OFF. Visit ?ux=editorial to enable (sticky via
// localStorage), ?ux=off to disable. Hides the normal nav + announcement bar
// and shows: left scroll rail, top-left MENU overlay, bottom-left language,
// top-right wordmark + bag/search. No effect on data, checkout, or SEO.
function uxEditorialOn() {
  try {
    const p = new URLSearchParams(location.search).get('ux');
    if (p === 'off' || p === 'classic') { localStorage.setItem('jta_ux', 'off'); return false; }
    if (p === 'editorial') { localStorage.removeItem('jta_ux'); return true; }
    return localStorage.getItem('jta_ux') !== 'off';  // default ON; ?ux=off is the kill-switch
  } catch (e) { return true; }
}

function EditorialChrome({ goTo, screen, cartCount, openCart, openSearch }) {
  const [on] = React.useState(uxEditorialOn);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [pct, setPct] = React.useState(0);
  const [annH, setAnnH] = React.useState(30);

  React.useEffect(() => {
    document.body.classList.toggle('ux-editorial', on);
    if (!on) return undefined;
    const measure = () => { const a = document.querySelector('.announce'); setAnnH(a ? a.offsetHeight : 0); };
    const onScroll = () => {
      const h = document.documentElement;
      const max = (h.scrollHeight - h.clientHeight) || 1;
      setPct(Math.min(100, Math.max(0, (h.scrollTop / max) * 100)));
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', measure);
    measure(); setTimeout(measure, 400); onScroll();
    return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', measure); };
  }, [on]);

  if (!on) return null;

  const go = (s, opts) => { setMenuOpen(false); goTo(s, opts); };
  const LINKS = [
    ['Men', () => go('collection', { gender: 'Men' })],
    ['Women', () => go('collection', { gender: 'Women' })],
    ['Luxury', () => go('collection', { season: 'Luxury' })],
    ['Collections', () => go('collections')],
    ['Bespoke', () => { setMenuOpen(false); if (window.openBespoke) window.openBespoke(); }],
    ['Journal', () => go('journal')],
    ['FAQ', () => go('faq')],
    ['About', () => go('about')],
    ['Contact', () => go('contact')],
    ['Account', () => go('account')],
    ['Affiliate Portal', () => go('affiliate-portal')],
  ];
  const corner = { position: 'fixed', zIndex: 70, fontFamily: 'var(--font-mono)' };
  // On the marble catalog the chrome sits over a bright background, so its
  // token-driven (white) text would vanish. Override the ink tokens for the
  // persistent chrome only — NOT the full-screen menu overlay, which keeps
  // its own dark surface.
  const onMarble = screen === 'collection';
  const marbleInk = onMarble
    ? { '--fg': '#1A1A1A', '--fg-2': 'rgba(26,26,26,.66)', '--fg-3': 'rgba(26,26,26,.45)' }
    : undefined;

  return (
    <>
      <style>{`
        body.ux-editorial .nav{display:none!important;}
      `}</style>

      <div style={marbleInk}>
      <div className="deck-rail" style={{ position: 'fixed', left: 22, top: '18vh', bottom: '12vh', width: 2, zIndex: 65, background: 'color-mix(in srgb,var(--fg) 12%,transparent)' }}>
        <div style={{ position: 'absolute', left: 0, top: 0, width: '100%', height: pct + '%', background: 'var(--gold,#c6a86b)', transition: 'height .1s linear' }} />
        <div style={{ position: 'absolute', left: -3, bottom: -24, fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.14em', color: 'var(--fg-3)', writingMode: 'vertical-rl' }}>{String(Math.round(pct)).padStart(2, '0')}</div>
      </div>

      <button onClick={() => setMenuOpen(true)} aria-label="Open menu"
        style={{ ...corner, left: 48, top: annH + 22, display: 'flex', alignItems: 'center', gap: 9, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--fg)', fontSize: 11, letterSpacing: '.22em' }}>
        <span style={{ display: 'inline-flex', flexDirection: 'column', gap: 4 }}>
          <span style={{ width: 20, height: 1.4, background: 'currentColor' }} />
          <span style={{ width: 20, height: 1.4, background: 'currentColor' }} />
        </span>
        MENU
      </button>

      <div style={{ ...corner, right: 30, top: annH + 18, display: 'flex', alignItems: 'center', gap: 18 }}>
        <button onClick={openSearch} aria-label="Search" style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--fg-2)', fontSize: 16 }}>⌕</button>
        <button onClick={openCart} aria-label="Cart" style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--fg-2)', fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.12em' }}>BAG{cartCount ? ' (' + cartCount + ')' : ''}</button>
        <span onClick={() => go('home')} style={{ cursor: 'pointer', fontFamily: 'var(--font-display,Georgia,serif)', fontSize: 19, letterSpacing: '.05em', color: 'var(--fg)' }}>JT <span style={{ color: 'var(--crimson,#c0322b)', letterSpacing: '.2em' }}>ATELIER</span></span>
      </div>

      <div style={{ ...corner, left: 40, bottom: 54, display: 'flex', alignItems: 'center', gap: 14 }}><LanguageSelector dropUp /><CurrencySelector dropUp /></div>
      </div>

      {menuOpen && (
        <div style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'color-mix(in srgb,var(--bg) 95%,#000)', backdropFilter: 'blur(2px)', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 8vw' }}>
          <button onClick={() => setMenuOpen(false)} aria-label="Close menu" style={{ position: 'absolute', left: 48, top: annH + 22, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--fg)', fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.22em' }}>✕ &nbsp;CLOSE</button>
          <nav>
            {LINKS.map(([label, fn], i) => (
              <div key={label} onClick={fn}
                style={{ cursor: 'pointer', fontFamily: 'var(--font-display,Georgia,serif)', fontStyle: 'italic', fontSize: 'clamp(32px,6vw,62px)', lineHeight: 1.18, color: 'var(--fg)', opacity: 0.9, transition: 'opacity .2s, transform .2s, color .2s' }}
                onMouseEnter={e => { e.currentTarget.style.opacity = '1'; e.currentTarget.style.transform = 'translateX(10px)'; e.currentTarget.style.color = 'var(--crimson,#c0322b)'; }}
                onMouseLeave={e => { e.currentTarget.style.opacity = '0.9'; e.currentTarget.style.transform = 'none'; e.currentTarget.style.color = 'var(--fg)'; }}>
                <span style={{ fontFamily: 'var(--font-mono)', fontStyle: 'normal', fontSize: 11, color: 'var(--fg-3)', marginRight: 18, verticalAlign: 'middle' }}>{String(i + 1).padStart(2, '0')}</span>{label}
              </div>
            ))}
          </nav>
          {/* WhatsApp + cookie badges live here only (removed from floating everywhere) */}
          <div style={{ display: 'flex', gap: 14, alignItems: 'center', marginTop: 'clamp(24px,5vh,48px)' }}>
            <a href={`https://wa.me/${WA_NUMBER}?text=Hi%2C%20I%27m%20interested%20in%20a%20JT%20Atelier%20piece.`}
              target="_blank" rel="noopener noreferrer" aria-label="Chat on WhatsApp" className="menu-badge" style={{ background: '#25D366' }}>
              <svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M16 .5C7.44.5.5 7.44.5 16c0 2.72.69 5.27 1.9 7.5L.5 31.5l8.27-1.87A15.47 15.47 0 0016 31.5C24.56 31.5 31.5 24.56 31.5 16S24.56.5 16 .5zm0 28.3c-2.46 0-4.76-.66-6.74-1.8l-.48-.29-4.91 1.11 1.14-4.77-.32-.5A12.47 12.47 0 013.47 16C3.47 9.09 9.09 3.47 16 3.47S28.53 9.09 28.53 16 22.91 28.8 16 28.8zm6.84-9.33c-.37-.19-2.2-1.09-2.54-1.21-.34-.13-.58-.19-.83.19-.24.37-.95 1.21-1.16 1.46-.21.25-.43.28-.8.09-.37-.19-1.57-.58-2.99-1.84-1.1-.98-1.85-2.2-2.07-2.57-.21-.37-.02-.57.16-.75.17-.17.37-.43.56-.65.19-.21.25-.37.38-.62.12-.25.06-.46-.03-.65-.09-.19-.83-2.01-1.14-2.76-.3-.72-.61-.62-.83-.63h-.71c-.25 0-.65.09-.99.46-.34.37-1.3 1.27-1.3 3.1s1.33 3.6 1.52 3.85c.18.25 2.62 4 6.36 5.61.89.38 1.58.61 2.12.78.89.28 1.7.24 2.34.15.71-.11 2.2-.9 2.51-1.77.31-.87.31-1.62.22-1.77-.09-.16-.34-.25-.71-.44z"/></svg>
            </a>
            <button type="button" aria-label="Cookie preferences" className="menu-badge" style={{ background: '#2f6fed', fontSize: 21 }}
              onClick={() => { setMenuOpen(false); const ic = document.getElementById('stcm-icon'); if (ic) ic.click(); }}>🍪</button>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.18em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>Chat · Cookies</span>
          </div>
        </div>
      )}
    </>
  );
}

// ── Policy pages (Privacy, Shipping, Terms) ───────────────────────────
function PolicyPage({ type, goTo }) {
  const POLICIES = {
    privacy: {
      title: 'Privacy Policy',
      updated: '1 June 2026',
      sections: [
        { h: 'Who we are', p: 'JT Atelier is a made-to-order leather outerwear atelier. Inquiries: inquiries@jtatelier.shop.' },
        { h: 'What we collect', p: 'When you place an order we collect your name, email address, shipping address, and payment details (processed securely by Stripe — we never see your full card number). When you contact us or subscribe to our studio list we collect your email address.' },
        { h: 'How we use it', p: 'Order fulfilment and shipping updates. Customer support replies. Studio list newsletters (opt-in only — unsubscribe any time via the link in any email). Improving our website and products.' },
        { h: 'Who we share it with', p: 'Stripe (payment processing), Supabase (secure cloud data storage), and shipping carriers (name and address only). We never sell or rent your personal data to third parties.' },
        { h: 'Your rights', p: 'Under GDPR and applicable privacy law you may request access to, correction of, or deletion of your personal data at any time. Email inquiries@jtatelier.shop with the subject line "Data request" and we will respond within 30 days.' },
        { h: 'Cookies', p: 'We use functional cookies (cart, preferences) and analytics cookies (Google Analytics). You can manage your cookie choices via the cookie banner shown on your first visit.' },
        { h: 'Contact', p: 'Data controller: JT Atelier · inquiries@jtatelier.shop' },
      ],
    },
    shipping: {
      title: 'Shipping Policy',
      updated: '1 June 2026',
      sections: [
        { h: 'Free worldwide shipping', p: 'Every JT Atelier order ships free to any country, with no minimum order value. We use insured express couriers (DHL, FedEx, or equivalent).' },
        { h: 'Lead time', p: 'Because each piece is made to order, please allow 2–4 weeks from payment confirmation to dispatch. You will receive a tracking number as soon as your parcel ships.' },
        { h: 'Delivery estimate', p: 'After dispatch, most international orders arrive in 5–10 business days. Delivery times may vary depending on your country\'s customs processing.' },
        { h: 'Customs & duties', p: 'Import duties and local taxes (if applicable) are the responsibility of the buyer. Please check your country\'s import regulations before ordering. Contact us if you have specific questions.' },
        { h: 'Lost or delayed parcels', p: 'If your tracking shows no movement for 7 business days after dispatch, please email inquiries@jtatelier.shop and we will open a trace with the carrier immediately.' },
      ],
    },
    terms: {
      title: 'Terms & Conditions',
      updated: '1 June 2026',
      sections: [
        { h: 'Made to order', p: 'Every JT Atelier piece is handcrafted to order. Orders cannot be cancelled once production has begun, which is typically within 24–48 hours of payment confirmation.' },
        { h: 'Returns & refunds', p: 'Because pieces are made to your specifications, all sales are final except in the case of a verified manufacturing defect. A defect must be reported within 2 days of delivery with photographic evidence. We will repair, replace, or refund at our discretion and will cover return shipping costs.' },
        { h: 'Sizing responsibility', p: 'We provide a detailed size guide. If you are unsure of your size, we recommend placing a Bespoke order so we can tailor the piece to your exact measurements. Standard orders placed in the wrong size do not qualify for a return.' },
        { h: 'Pricing & currency', p: 'All prices are shown and charged in USD via Stripe. Currency conversion indicators shown on the site are for reference only.' },
        { h: 'Intellectual property', p: 'All content on this site — photographs, copy, design, and the JT Atelier name — is the property of JT Atelier. Reproduction without written permission is prohibited.' },
        { h: 'Governing law', p: 'These terms are governed by applicable international commercial law. Any dispute will be resolved through good-faith negotiation before formal proceedings.' },
        { h: 'Contact', p: 'Questions about these terms: inquiries@jtatelier.shop' },
      ],
    },
  };

  const policy = POLICIES[type] || POLICIES.privacy;

  return (
    <div data-screen-label={type}>
      <section className="container" style={{ paddingTop: 80, paddingBottom: 100, maxWidth: 760 }}>
        <div className="eyebrow" style={{ marginBottom: 14 }}>◇ &nbsp; Legal</div>
        <h1 className="display" style={{ fontSize: 'clamp(40px, 7vw, 100px)', margin: '0 0 12px', lineHeight: 1 }}>
          <em>{policy.title}.</em>
        </h1>
        <p className="mono" style={{ color: 'var(--fg-3)', marginBottom: 60, fontSize: 11 }}>
          Last updated: {policy.updated}
        </p>
        {policy.sections.map(({ h, p }) => (
          <div key={h} style={{ marginBottom: 32, paddingBottom: 32, borderBottom: '.5px solid var(--line-2)' }}>
            <h2 style={{
              fontSize: 10, fontFamily: 'var(--font-mono)', letterSpacing: '.18em',
              textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 10, fontWeight: 400,
            }}>{h}</h2>
            <p style={{ fontSize: 14, lineHeight: 1.75, color: 'var(--fg-2)', margin: 0 }}>{p}</p>
          </div>
        ))}
        <div style={{ marginTop: 48, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
          <button className="btn ghost sm" onClick={() => goTo('contact')}>
            Questions? Contact us <span className="arrow">→</span>
          </button>
          <button className="btn ghost sm" onClick={() => goTo('home')}>Back home</button>
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { AnnouncementBar, Nav, Footer, EmailCapture, SocialFeed, CurrencySelector, LanguageSelector, EditorialChrome, useCurrency, useMobile, WhatsApp, PolicyPage });
