// La Pharmacia — Mobile e-commerce prototype (Hebrew, RTL)
const { useState, useEffect, useRef } = React;

// ── Feature flags ───────────────────────────────────────────────────
// Flip any of these to `true` to re-enable a feature; the rest of the app
// already has the wiring intact, so nothing else needs to change.
//   - customerAccounts: register/login for shoppers, account tab, "create
//     account during checkout" toggle. Admin login on /admin is separate
//     and unaffected by this flag.
//   - coupons:          promo-code input in cart + admin section
//   - rewards:          loyalty-points display on the account screen
const FEATURES = {
  customerAccounts: false,
  coupons:          false,
  rewards:          false,
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "emerald",
  "displayFont": "Heebo",
  "showGlow": true,
  "denseGrid": false
}/*EDITMODE-END*/;

const THEMES = {
  emerald: {
    bg: 'oklch(0.20 0.025 165)', bgSoft: 'oklch(0.24 0.030 165)', bgCard: 'oklch(0.28 0.035 165)',
    line: 'oklch(0.34 0.030 165)', ink: 'oklch(0.96 0.012 85)', inkDim: 'oklch(0.78 0.020 90)',
    inkMute: 'oklch(0.58 0.025 100)', accent: 'oklch(0.82 0.085 82)', accentDim: 'oklch(0.62 0.075 80)',
    glow: 'rgba(220, 240, 220, 0.35)',
  },
  ink: {
    bg: 'oklch(0.16 0.005 250)', bgSoft: 'oklch(0.20 0.005 250)', bgCard: 'oklch(0.24 0.008 250)',
    line: 'oklch(0.30 0.008 250)', ink: 'oklch(0.96 0.005 85)', inkDim: 'oklch(0.78 0.010 85)',
    inkMute: 'oklch(0.58 0.012 90)', accent: 'oklch(0.85 0.10 80)', accentDim: 'oklch(0.65 0.09 80)',
    glow: 'rgba(255, 235, 200, 0.3)',
  },
  bone: {
    bg: 'oklch(0.95 0.008 85)', bgSoft: 'oklch(0.92 0.010 85)', bgCard: 'oklch(0.98 0.005 85)',
    line: 'oklch(0.86 0.012 85)', ink: 'oklch(0.20 0.020 165)', inkDim: 'oklch(0.40 0.018 165)',
    inkMute: 'oklch(0.55 0.015 165)', accent: 'oklch(0.45 0.060 165)', accentDim: 'oklch(0.55 0.050 165)',
    glow: 'rgba(50, 80, 60, 0.15)',
  },
};

// Unsplash demo imagery
const IMG = {
  bags:     'https://images.unsplash.com/photo-1548036328-c9fa89d128fa?w=800&q=80&auto=format&fit=crop',
  perfumes: 'https://images.unsplash.com/photo-1541643600914-78b084683601?w=800&q=80&auto=format&fit=crop',
  access:   'https://images.unsplash.com/photo-1535632787350-4e68ef0ac584?w=800&q=80&auto=format&fit=crop',
  beauty:   'https://images.unsplash.com/photo-1596462502278-27bfdc403348?w=800&q=80&auto=format&fit=crop',
  hero:     'https://images.unsplash.com/photo-1592945403244-b3fbafd7f539?w=1200&q=85&auto=format&fit=crop',
  bag1:     'https://images.unsplash.com/photo-1584917865442-de89df76afd3?w=800&q=80&auto=format&fit=crop',
  bag2:     'https://images.unsplash.com/photo-1591561954557-26941169b49e?w=800&q=80&auto=format&fit=crop',
  bag3:     'https://images.unsplash.com/photo-1590874103328-eac38a683ce7?w=800&q=80&auto=format&fit=crop',
  bag4:     'https://images.unsplash.com/photo-1566150905458-1bf1fc113f0d?w=800&q=80&auto=format&fit=crop',
  bottle1:  'https://images.unsplash.com/photo-1523293182086-7651a899d37f?w=800&q=80&auto=format&fit=crop',
  bottle2:  'https://images.unsplash.com/photo-1587017539504-67cfbddac569?w=800&q=80&auto=format&fit=crop',
  bottle3:  'https://images.unsplash.com/photo-1594035910387-fea47794261f?w=800&q=80&auto=format&fit=crop',
  bottle4:  'https://images.unsplash.com/photo-1557170334-a9086d21c1d6?w=800&q=80&auto=format&fit=crop',
  ring1:    'https://images.unsplash.com/photo-1535632787350-4e68ef0ac584?w=800&q=80&auto=format&fit=crop',
  scarf1:   'https://images.unsplash.com/photo-1601762603339-fd61e28b698a?w=800&q=80&auto=format&fit=crop',
  watch1:   'https://images.unsplash.com/photo-1524805444758-089113d48a6d?w=800&q=80&auto=format&fit=crop',
  sun1:     'https://images.unsplash.com/photo-1572635196237-14b3f281503f?w=800&q=80&auto=format&fit=crop',
  lipstick: 'https://images.unsplash.com/photo-1586495777744-4413f21062fa?w=800&q=80&auto=format&fit=crop',
  shoes:    'https://images.unsplash.com/photo-1543163521-1bf539c55dd2?w=800&q=80&auto=format&fit=crop',
  jewelry:  'https://images.unsplash.com/photo-1515562141207-7a88fb7ce338?w=800&q=80&auto=format&fit=crop',
  ig1:      'https://images.unsplash.com/photo-1490481651871-ab68de25d43d?w=600&q=80&auto=format&fit=crop',
  ig2:      'https://images.unsplash.com/photo-1469334031218-e382a71b716b?w=600&q=80&auto=format&fit=crop',
  ig3:      'https://images.unsplash.com/photo-1483985988355-763728e1935b?w=600&q=80&auto=format&fit=crop',
};

// These globals are reassigned at boot from /api/* endpoints.
// Components read them at render time; a `dataVersion` state in App forces a re-render
// after the fetch completes. Hardcoded values are an offline fallback.
let SETTINGS = {
  store_name: 'La Pharmacia', store_address: 'רוטשילד 42, תל אביב', store_phone: '',
  store_hours: 'ראשון–חמישי 09:00–22:00 · שישי 09:00–15:00',
  waze_lat: '32.0633', waze_lng: '34.7702',
  social_instagram: 'https://instagram.com', social_facebook: 'https://facebook.com',
  social_whatsapp: 'https://wa.me/972500000000', social_tiktok: '',
  banner_active: false, banner_text: '', banner_link: '',
  banner_bg: '#d4a85a', banner_fg: '#14201a',
};
let IG_POSTS = [];
let HOME_SLIDES = []; // hero slider entries from /api/home-slides — admin managed
let SHIPPING_METHODS = [
  { id: 'express',  label: 'אקספרס',     sub: 'מחר עד 12:00', price: 0,  icon: 'truck', badge: 'חינם' },
  { id: 'standard', label: 'רגיל',        sub: '2–4 ימי עסקים', price: 25, icon: 'truck' },
  { id: 'pickup',   label: 'איסוף עצמי',  sub: 'תל אביב — רוטשילד 42', price: 0, icon: 'home' },
];

let PAYMENT_METHODS = [
  { id: 'cod',    label: 'במזומן בעת קבלה', description: 'תשלום במזומן או בכרטיס לשליח / בחנות בזמן האיסוף', icon: 'cash' },
  { id: 'credit', label: 'כרטיס אשראי',     description: 'תועברי לעמוד תשלום מאובטח של Grow', icon: 'card' },
  { id: 'apple',  label: 'Apple Pay',        description: 'אישור עם Touch ID / Face ID דרך Grow', icon: 'apple' },
  { id: 'paypal', label: 'PayPal',           description: 'התחברות לחשבון ה-PayPal שלך', icon: 'paypal' },
  { id: 'bit',    label: 'Bit',              description: 'תשלום דרך אפליקציית Bit', icon: 'bit' },
];

let CATEGORIES = [
  { id: 'bags',     label: 'תיקים',       sub: '142 פריטים', img: IMG.bags },
  { id: 'perfumes', label: 'בשמים',       sub: '86 פריטים',  img: IMG.perfumes },
  { id: 'access',   label: 'אקססוריז',    sub: '210 פריטים', img: IMG.access },
  { id: 'beauty',   label: 'יופי',         sub: '54 פריטים',  img: IMG.beauty },
  { id: 'shoes',    label: 'נעליים',       sub: '78 פריטים',  img: IMG.shoes },
  { id: 'jewelry',  label: 'תכשיטים',      sub: '64 פריטים',  img: IMG.jewelry },
];

let PRODUCTS = [
  { id: 'p1', name: 'תיק טוט עור רך',         brand: 'Maison Cervo',  price: 285, was: null, cat: 'bags',     img: IMG.bag1, tag: 'חדש' },
  { id: 'p2', name: 'Amber Veil — 50ml',      brand: 'Atelier Noir',  price: 142, was: 168,  cat: 'perfumes', img: IMG.bottle1, tag: '15%-' },
  { id: 'p3', name: 'עגילי פנינה',             brand: 'Lune & Co.',    price: 64,  was: null, cat: 'access',   img: IMG.ring1, tag: null },
  { id: 'p4', name: 'צעיף משי 90',             brand: 'Lume',          price: 120, was: null, cat: 'access',   img: IMG.scarf1, tag: 'חדש' },
  { id: 'p5', name: 'תיק קרוסבודי סהר',        brand: 'Maison Cervo',  price: 340, was: null, cat: 'bags',     img: IMG.bag2, tag: null },
  { id: 'p6', name: 'Rose de Mai — 100ml',    brand: 'Atelier Noir',  price: 198, was: null, cat: 'perfumes', img: IMG.bottle2, tag: 'לוהט' },
  { id: 'p7', name: 'תיק דלי פשתן',            brand: 'Casa Verde',    price: 175, was: 210,  cat: 'bags',     img: IMG.bag3, tag: '20%-' },
  { id: 'p8', name: 'Vetiver Smoke — 50ml',   brand: 'Atelier Noir',  price: 156, was: null, cat: 'perfumes', img: IMG.bottle3, tag: null },
  { id: 'p9', name: 'משקפי שמש קלאסיים',       brand: 'Lume',          price: 89,  was: null, cat: 'access',   img: IMG.sun1, tag: null },
  { id: 'p10', name: 'שעון יד מינימלי',         brand: 'Lune & Co.',    price: 220, was: null, cat: 'access',   img: IMG.watch1, tag: 'חדש' },
];

let STORIES = [
  { id: 's1', title: 'בשמי האביב',     sub: 'מבט מקרוב', img: IMG.bottle2 },
  { id: 's2', title: 'תיקי הקיץ',       sub: 'המלצות',    img: IMG.bag2 },
  { id: 's3', title: 'אקססוריז יומי',  sub: 'סטיילינג',  img: IMG.scarf1 },
  { id: 's4', title: 'יופי בטבעיות',    sub: 'טיפים',     img: IMG.beauty },
  { id: 's5', title: 'מתנות אהובות',   sub: 'נבחרים',    img: IMG.ring1 },
  { id: 's6', title: 'מאחורי הקלעים',  sub: 'הסטודיו',   img: IMG.bottle1 },
];

let BRANDS = [
  { id: 'b1', name: 'Maison Cervo',  count: 42, img: IMG.bag1 },
  { id: 'b2', name: 'Atelier Noir',  count: 38, img: IMG.bottle3 },
  { id: 'b3', name: 'Lune & Co.',    count: 27, img: IMG.ring1 },
  { id: 'b4', name: 'Lume',          count: 31, img: IMG.scarf1 },
  { id: 'b5', name: 'Casa Verde',    count: 19, img: IMG.bag3 },
  { id: 'b6', name: 'Sable',         count: 24, img: IMG.bottle4 },
];

const fmt = (n) => '₪' + n.toFixed(0);

// ── Hero slider — admin-managed via /api/home-slides. Auto-cycles every 6s when 2+ slides.
//    Renders both the mobile card (rounded, 380px tall) and the desktop full-bleed hero.
function HomeSlider({ T, displayFont, showGlow, heroParallax = 0, heroOpacity = 1, layout = 'mobile', onCta }) {
  const slides = HOME_SLIDES.length ? HOME_SLIDES : [];
  const [idx, setIdx] = useState(0);
  useEffect(() => {
    if (slides.length < 2) return;
    const t = setInterval(() => setIdx(i => (i + 1) % slides.length), 6000);
    return () => clearInterval(t);
  }, [slides.length]);
  if (slides.length === 0) return null;
  const cur = slides[Math.min(idx, slides.length - 1)];

  // Resolve a CTA link like 'cat:perfumes' or 'shop' into a navigation action
  function clickCta() {
    if (!cur.cta_link) return;
    if (cur.cta_link.startsWith('cat:')) onCta?.({ type: 'category', id: cur.cta_link.slice(4) });
    else if (cur.cta_link === 'shop')   onCta?.({ type: 'tab', id: 'shop' });
    else if (cur.cta_link.startsWith('http')) window.open(cur.cta_link, '_blank', 'noopener');
  }

  if (layout === 'mobile') {
    return (
      <div style={{
        margin: '0 16px 24px', height: 380, borderRadius: 28, overflow: 'hidden',
        position: 'relative', background: T.bgCard,
        boxShadow: showGlow ? `0 30px 60px -20px ${T.glow}, 0 0 0 1px ${T.line}` : `0 0 0 1px ${T.line}`,
      }}>
        {/* Image fills the slide statically — no parallax. The previous transform caused
            the image to translate above the slide as the page scrolled, leaving the
            bottom half "empty" with just the dark background showing through. */}
        <div key={cur.id} style={{ position: 'absolute', inset: 0, animation: 'fadein 0.6s' }}>
          <Img src={cur.image_url} style={{ width: '100%', height: '100%' }} />
          <div style={{ position: 'absolute', inset: 0,
            background: `linear-gradient(180deg, transparent 0%, transparent 30%, ${T.bg}cc 75%, ${T.bg} 100%)` }} />
        </div>
        <div style={{ position: 'relative', height: '100%', padding: 22, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
          {cur.eyebrow && (
            <div style={{
              alignSelf: 'flex-start',
              padding: '6px 12px', borderRadius: 999,
              background: `color-mix(in oklab, ${T.ink}, transparent 88%)`,
              border: `1px solid ${T.line}`,
              fontSize: 10, letterSpacing: 1, color: T.ink,
            }}>{cur.eyebrow}</div>
          )}
          <div style={{ textAlign: cur.align || 'right' }}>
            {cur.title && (
              <div style={{ fontFamily: displayFont, fontSize: 36, lineHeight: 1.1, color: T.ink, fontWeight: 700 }}>
                {cur.title}
              </div>
            )}
            {cur.subtitle && (
              <div style={{ marginTop: cur.title ? 12 : 0, color: T.inkDim, fontSize: 13, maxWidth: 280 }}>{cur.subtitle}</div>
            )}
            {cur.cta_label && (
              <button onClick={clickCta} style={{
                marginTop: 18, padding: '12px 22px', borderRadius: 999,
                background: T.ink, color: T.bg, border: 'none',
                fontWeight: 700, fontSize: 12, letterSpacing: 0.5,
                display: 'inline-flex', alignItems: 'center', gap: 10, cursor: 'pointer',
                transition: 'transform 0.2s',
              }}
              onPointerDown={e => e.currentTarget.style.transform = 'scale(0.96)'}
              onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
              onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
                {cur.cta_label} <Icon name="left" size={14} strokeWidth={2.2} />
              </button>
            )}
          </div>
        </div>
        {/* Dots — only when there are multiple slides */}
        {slides.length > 1 && (
          <div style={{ position: 'absolute', bottom: 12, insetInline: 0, display: 'flex', justifyContent: 'center', gap: 6, zIndex: 5 }}>
            {slides.map((_, i) => (
              <button key={i} onClick={() => setIdx(i)} aria-label={`slide ${i+1}`} style={{
                width: i === idx ? 18 : 6, height: 6, borderRadius: 3,
                background: i === idx ? T.ink : `color-mix(in oklab, ${T.ink}, transparent 70%)`,
                border: 'none', padding: 0, cursor: 'pointer', transition: 'width 0.3s',
              }} />
            ))}
          </div>
        )}
      </div>
    );
  }

  // Desktop: full-bleed hero with overlay text
  return (
    <section className="lp-hero" style={{ position: 'relative' }}>
      <div key={cur.id} style={{ position: 'absolute', inset: 0, animation: 'fadein 0.6s' }}>
        <img src={cur.image_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(10,19,15,0.45) 0%, rgba(10,19,15,0.2) 40%, rgba(10,19,15,0.85) 100%)' }} />
      </div>
      <div className="lp-hero-inner" style={{ position: 'relative', zIndex: 2, textAlign: cur.align || 'right' }}>
        {cur.eyebrow && <div className="lp-eyebrow">{cur.eyebrow}</div>}
        {cur.title && <h1 className="lp-hero-title" style={{ marginTop: 12 }}>{cur.title}</h1>}
        {cur.subtitle && <p className="lp-hero-sub">{cur.subtitle}</p>}
        {cur.cta_label && (
          <button className="lp-btn lp-btn-primary lp-btn-light" onClick={clickCta} style={{ marginTop: 24 }}>
            {cur.cta_label} ←
          </button>
        )}
      </div>
      {slides.length > 1 && (
        <div style={{ position: 'absolute', bottom: 24, insetInline: 0, display: 'flex', justifyContent: 'center', gap: 8, zIndex: 5 }}>
          {slides.map((_, i) => (
            <button key={i} onClick={() => setIdx(i)} aria-label={`slide ${i+1}`} style={{
              width: i === idx ? 24 : 8, height: 8, borderRadius: 4,
              background: i === idx ? '#d4a85a' : 'rgba(240,236,228,0.4)',
              border: 'none', padding: 0, cursor: 'pointer', transition: 'all 0.3s',
            }} />
          ))}
        </div>
      )}
    </section>
  );
}

// ── Banner — slim promo bar from /api/settings, shown on the home screens ──
function Banner({ T }) {
  const [dismissed, setDismissed] = useState(() => {
    try { return localStorage.getItem('lp_banner_dismissed') === SETTINGS.banner_text; }
    catch { return false; }
  });
  if (!SETTINGS.banner_active || !SETTINGS.banner_text || dismissed) return null;

  const dismiss = (e) => {
    e?.preventDefault();
    e?.stopPropagation();
    try { localStorage.setItem('lp_banner_dismissed', SETTINGS.banner_text); } catch {}
    setDismissed(true);
  };

  const inner = (
    <>
      <span style={{ flex: 1, padding: '0 32px' }}>{SETTINGS.banner_text}</span>
      <button onClick={dismiss} aria-label="סגירה" style={{
        position: 'absolute', insetInlineEnd: 8, top: '50%', transform: 'translateY(-50%)',
        background: 'none', border: 'none', color: 'inherit', cursor: 'pointer',
        opacity: 0.6, padding: 6, fontSize: 18, lineHeight: 1,
      }}>×</button>
    </>
  );

  const baseStyle = {
    position: 'relative',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    minHeight: 38, padding: '10px 16px',
    background: SETTINGS.banner_bg || '#d4a85a',
    color: SETTINGS.banner_fg || '#14201a',
    fontSize: 12.5, fontWeight: 600, letterSpacing: 0.3,
    textAlign: 'center', textDecoration: 'none', direction: 'rtl',
  };

  return SETTINGS.banner_link
    ? <a href={SETTINGS.banner_link} target={SETTINGS.banner_link.startsWith('http') ? '_blank' : undefined} rel="noopener" style={baseStyle}>{inner}</a>
    : <div style={baseStyle}>{inner}</div>;
}

// ── Instagram strip — fed by /api/instagram/posts, managed in admin ──
// Instagram brand gradient — official 4-stop radial that mimics the app icon
const IG_GRADIENT = 'radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%)';

// Camera glyph (matches the real IG outline)
function IGGlyph({ size = 22, color = '#fff', strokeWidth = 2 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="3" width="18" height="18" rx="5.5"/>
      <circle cx="12" cy="12" r="4"/>
      <circle cx="17.5" cy="6.5" r="1" fill={color} stroke="none"/>
    </svg>
  );
}

// Parse "https://instagram.com/lapharmacia" → "lapharmacia"
function igHandleFromUrl(url) {
  if (!url) return null;
  const m = url.match(/instagram\.com\/([^/?#]+)/i);
  return m ? '@' + m[1].replace(/^@/, '') : null;
}

function InstagramStrip({ T, displayFont, layout = 'mobile' }) {
  if (!IG_POSTS || IG_POSTS.length === 0) return null;
  const visible = IG_POSTS.slice(0, layout === 'mobile' ? 6 : 6);
  const handle = igHandleFromUrl(SETTINGS.social_instagram) || '@lapharmacia';

  if (layout === 'mobile') {
    return (
      <div style={{ margin: '20px 0 28px', padding: '0 16px' }}>
        {/* IG-branded header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '6px 4px 16px' }}>
          <div style={{
            width: 44, height: 44, borderRadius: 12,
            background: IG_GRADIENT,
            display: 'grid', placeItems: 'center',
            boxShadow: '0 6px 18px -4px rgba(214,36,159,0.45)',
            flexShrink: 0,
          }}>
            <IGGlyph size={24} color="#fff" strokeWidth={2} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 14, color: T.ink, fontWeight: 700, letterSpacing: 0.2, direction: 'ltr', textAlign: 'right' }}>{handle}</div>
            <div style={{ fontSize: 11, color: T.inkDim, marginTop: 2 }}>הרגעים שלנו · עקבי</div>
          </div>
          {SETTINGS.social_instagram && (
            <a href={SETTINGS.social_instagram} target="_blank" rel="noopener" style={{
              padding: '7px 14px', borderRadius: 999,
              background: T.accent, color: T.bg,
              fontSize: 11, fontWeight: 700, textDecoration: 'none',
              letterSpacing: 0.3, flexShrink: 0,
            }}>עקבי</a>
          )}
        </div>

        {/* 3 × N grid of square posts */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 4 }}>
          {visible.map(p => (
            <a key={p.id} href={p.link || SETTINGS.social_instagram || '#'} target="_blank" rel="noopener" style={{
              aspectRatio: '1', overflow: 'hidden',
              position: 'relative', display: 'block', background: T.bgCard,
            }}>
              <img src={p.image_url} alt={p.caption || ''}
                style={{ width: '100%', height: '100%', objectFit: 'cover', transition: 'transform 0.4s' }}
                onPointerEnter={e => e.currentTarget.style.transform = 'scale(1.06)'}
                onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'} />
              {/* Tiny IG icon top-right of each tile */}
              <div style={{
                position: 'absolute', top: 6, insetInlineEnd: 6,
                width: 18, height: 18, borderRadius: 5,
                background: 'rgba(0,0,0,0.45)',
                display: 'grid', placeItems: 'center',
                backdropFilter: 'blur(4px)',
              }}>
                <IGGlyph size={11} color="#fff" strokeWidth={2} />
              </div>
            </a>
          ))}
        </div>
      </div>
    );
  }

  // Desktop
  return (
    <section className="lp-section">
      <div className="lp-section-head" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
        <div style={{
          width: 64, height: 64, borderRadius: 16,
          background: IG_GRADIENT,
          display: 'grid', placeItems: 'center',
          boxShadow: '0 10px 30px -6px rgba(214,36,159,0.5)',
          marginBottom: 18,
        }}>
          <IGGlyph size={32} color="#fff" strokeWidth={2} />
        </div>
        <div className="lp-eyebrow" style={{ direction: 'ltr' }}>{handle}</div>
        <h2 className="lp-section-title">העולם שלנו ב<em>אינסטגרם</em></h2>
        {SETTINGS.social_instagram && (
          <a href={SETTINGS.social_instagram} target="_blank" rel="noopener" style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            marginTop: 14, padding: '12px 26px', borderRadius: 999,
            background: IG_GRADIENT, color: '#fff',
            fontSize: 13, fontWeight: 700, textDecoration: 'none',
            letterSpacing: 0.3, boxShadow: '0 8px 24px -6px rgba(214,36,159,0.5)',
            transition: 'transform 0.2s',
          }}
          onPointerEnter={e => e.currentTarget.style.transform = 'translateY(-2px)'}
          onPointerLeave={e => e.currentTarget.style.transform = 'translateY(0)'}>
            <IGGlyph size={16} color="#fff" /> עקבי בפיד
          </a>
        )}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 10, marginTop: 40 }}>
        {visible.map(p => (
          <a key={p.id} href={p.link || SETTINGS.social_instagram || '#'} target="_blank" rel="noopener" style={{
            aspectRatio: '1', borderRadius: 8, overflow: 'hidden',
            position: 'relative', display: 'block',
            transition: 'transform 0.3s, box-shadow 0.3s', cursor: 'pointer',
          }}
          onPointerEnter={e => { e.currentTarget.style.transform = 'translateY(-4px)'; e.currentTarget.style.boxShadow = '0 12px 30px rgba(0,0,0,0.5)'; }}
          onPointerLeave={e => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'none'; }}>
            <img src={p.image_url} alt={p.caption || ''} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
            <div style={{
              position: 'absolute', top: 8, insetInlineEnd: 8,
              width: 22, height: 22, borderRadius: 6,
              background: 'rgba(0,0,0,0.55)',
              display: 'grid', placeItems: 'center',
              backdropFilter: 'blur(6px)',
            }}>
              <IGGlyph size={13} color="#fff" strokeWidth={2} />
            </div>
          </a>
        ))}
      </div>
    </section>
  );
}

// ── Image with subtle gradient overlay ──
function Img({ src, style, overlay }) {
  return (
    <div style={{ position: 'relative', overflow: 'hidden', ...style }}>
      <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
      {overlay && <div style={{ position: 'absolute', inset: 0, background: overlay, pointerEvents: 'none' }} />}
    </div>
  );
}

// ── Icons ──
const Icon = ({ name, size = 22, color = 'currentColor', strokeWidth = 1.6 }) => {
  const p = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'search':   return <svg {...p}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>;
    case 'bag':      return <svg {...p}><path d="M5 8h14l-1 12H6L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>;
    case 'heart':    return <svg {...p}><path d="M12 20s-7-4.5-9-9.5C1.5 6.5 5 4 8 5.5c1.5.7 2.5 2 4 4 1.5-2 2.5-3.3 4-4 3-1.5 6.5 1 5 5C19 15.5 12 20 12 20z"/></svg>;
    case 'home':     return <svg {...p}><path d="M3 11 12 4l9 7"/><path d="M5 10v10h14V10"/></svg>;
    case 'grid':     return <svg {...p}><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>;
    case 'user':     return <svg {...p}><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/></svg>;
    case 'chevron':  return <svg {...p}><path d="m9 6 6 6-6 6"/></svg>;
    case 'chev-r':   return <svg {...p} style={{transform:'scaleX(-1)'}}><path d="m9 6 6 6-6 6"/></svg>;
    case 'left':     return <svg {...p}><path d="m15 6-6 6 6 6"/></svg>;
    case 'right':    return <svg {...p}><path d="m9 6 6 6-6 6"/></svg>;
    case 'plus':     return <svg {...p}><path d="M12 5v14M5 12h14"/></svg>;
    case 'minus':    return <svg {...p}><path d="M5 12h14"/></svg>;
    case 'close':    return <svg {...p}><path d="M6 6l12 12M18 6 6 18"/></svg>;
    case 'star':     return <svg {...p}><path d="M12 3l2.6 5.5 6 .9-4.3 4.2 1 6L12 16.8 6.7 19.6l1-6L3.4 9.4l6-.9L12 3z"/></svg>;
    case 'filter':   return <svg {...p}><path d="M4 6h16M7 12h10M10 18h4"/></svg>;
    case 'sparkle':  return <svg {...p}><path d="M12 3v6M12 15v6M3 12h6M15 12h6"/></svg>;
    case 'truck':    return <svg {...p}><rect x="2" y="7" width="13" height="10" rx="1"/><path d="M15 10h4l3 3v4h-7"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/></svg>;
    case 'shield':   return <svg {...p}><path d="M12 3 4 6v6c0 5 4 8 8 9 4-1 8-4 8-9V6l-8-3z"/></svg>;
    case 'leaf':     return <svg {...p}><path d="M5 19c0-8 6-14 14-14 0 8-6 14-14 14z"/><path d="M5 19c4-4 8-8 14-14"/></svg>;
    case 'check':    return <svg {...p}><path d="M5 12l5 5L20 7"/></svg>;
    case 'waze':     return <svg {...p}><path d="M12 4.5c4.4 0 8 2.7 8 6 0 1.3-.5 2.5-1.4 3.6.2.5.7 1.5 1 2.4-.6-.2-1.7-.6-2.5-.7-1.4 1-3.2 1.5-5.1 1.5-.4 0-.8 0-1.2-.1-.4 1.2-1.6 2-2.9 2a3 3 0 0 1-2.8-2.1A6.5 6.5 0 0 1 4 10.5c0-3.3 3.6-6 8-6z"/><circle cx="9.5" cy="11" r="0.9" fill="currentColor" stroke="none"/><circle cx="14.5" cy="11" r="0.9" fill="currentColor" stroke="none"/></svg>;
    case 'insta':    return <svg {...p}><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.8" fill="currentColor" stroke="none"/></svg>;
    case 'fb':       return <svg {...p}><path d="M15 3h-2a4 4 0 0 0-4 4v3H6v4h3v7h4v-7h3l1-4h-4V7a1 1 0 0 1 1-1h2z"/></svg>;
    case 'wapp':     return <svg {...p}><path d="M21 12a9 9 0 0 1-13.5 7.8L3 21l1.3-4.5A9 9 0 1 1 21 12z"/><path d="M8.5 9c.3 1.5 1 2.7 2.1 3.7s2.2 1.7 3.7 2c.6.1 1.2-.2 1.4-.7l.3-.8c.2-.5-.1-1-.6-1.2l-1.4-.5c-.4-.1-.9 0-1.1.4l-.3.4a5 5 0 0 1-2.3-2.3l.4-.3c.4-.3.5-.7.4-1.1l-.5-1.4c-.2-.5-.7-.7-1.2-.6l-.8.3c-.5.2-.8.8-.7 1.4z"/></svg>;
    case 'pin':      return <svg {...p}><path d="M12 22s7-7 7-12a7 7 0 0 0-14 0c0 5 7 12 7 12z"/><circle cx="12" cy="10" r="2.5"/></svg>;
    case 'phone':    return <svg {...p}><path d="M5 4h3l2 5-2.5 1.5a11 11 0 0 0 6 6L15 14l5 2v3a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>;
    default:         return null;
  }
};

// ── Tab bar — fixed to device frame, not scroll container ──
function TabBar({ active, onNav, T, cartCount }) {
  const tabs = [
    { id: 'home',     icon: 'home',  label: 'בית' },
    { id: 'shop',     icon: 'grid',  label: 'חנות' },
    { id: 'wishlist', icon: 'heart', label: 'מועדפים' },
    { id: 'cart',     icon: 'bag',   label: 'סל' },
    { id: 'track',    icon: 'truck', label: 'מעקב' },
    FEATURES.customerAccounts && { id: 'account', icon: 'user', label: 'חשבון' },
  ].filter(Boolean);
  return (
    <div dir="rtl" className="lp-mobile-only" style={{
      position: 'absolute', left: 12, right: 12, bottom: 16,
      background: `color-mix(in oklab, ${T.bgCard}, transparent 18%)`,
      backdropFilter: 'blur(20px) saturate(140%)',
      WebkitBackdropFilter: 'blur(20px) saturate(140%)',
      border: `1px solid ${T.line}`,
      borderRadius: 28,
      padding: '10px 8px',
      display: 'flex', justifyContent: 'space-around',
      boxShadow: '0 12px 30px rgba(0,0,0,0.35)',
      zIndex: 50,
    }}>
      {tabs.map(t => {
        const on = active === t.id;
        return (
          <button key={t.id} onClick={() => onNav(t.id)} style={{
            background: 'none', border: 'none', cursor: 'pointer',
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
            color: on ? T.ink : T.inkMute, padding: '4px 10px',
            transition: 'color 0.25s ease', position: 'relative',
          }}>
            <div style={{ position: 'relative' }}>
              <Icon name={t.icon} size={22} strokeWidth={on ? 1.9 : 1.5} />
              {t.id === 'cart' && cartCount > 0 && (
                <div style={{
                  position: 'absolute', top: -4, insetInlineEnd: -8,
                  minWidth: 16, height: 16, borderRadius: 8, padding: '0 4px',
                  background: T.accent, color: T.bg, fontSize: 10, fontWeight: 700,
                  display: 'grid', placeItems: 'center',
                }}>{cartCount}</div>
              )}
            </div>
            <div style={{ fontSize: 10, letterSpacing: 0.4, fontWeight: on ? 600 : 500 }}>{t.label}</div>
            {on && <div style={{ position: 'absolute', bottom: -4, width: 4, height: 4, borderRadius: 2, background: T.accent }} />}
          </button>
        );
      })}
    </div>
  );
}

function IconBtn({ T, icon, onClick }) {
  return (
    <button onClick={onClick} style={{
      width: 40, height: 40, borderRadius: 20,
      background: `color-mix(in oklab, ${T.bgCard}, transparent 30%)`,
      border: `1px solid ${T.line}`, color: T.ink, cursor: 'pointer',
      display: 'grid', placeItems: 'center', transition: 'transform 0.2s',
    }}
    onPointerDown={e => e.currentTarget.style.transform = 'scale(0.92)'}
    onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
    onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
      <Icon name={icon} size={18} />
    </button>
  );
}

function SectionHead({ T, displayFont, title, link, onLinkClick }) {
  const linkContent = link ? `${link} ←` : null;
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', padding: '14px 20px 12px' }}>
      <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 600 }}>{title}</div>
      {linkContent && (onLinkClick
        ? (
          <button onClick={onLinkClick} style={{
            background: 'transparent', border: 'none', padding: 0,
            fontSize: 11, letterSpacing: 0.5, color: T.inkMute, fontWeight: 600,
            cursor: 'pointer', fontFamily: 'inherit',
          }}>{linkContent}</button>
        )
        : <div style={{ fontSize: 11, letterSpacing: 0.5, color: T.inkMute, fontWeight: 600 }}>{linkContent}</div>
      )}
    </div>
  );
}

// ── Home ──
function HomeScreen({ T, displayFont, showGlow, onOpenProduct, onOpenCategory, onOpenBrand, onOpenAllBrands, onOpenSearch, onOpenTrackOrder, onOpenLegal, scrollRef }) {
  const [scrollY, setScrollY] = useState(0);
  useEffect(() => {
    const el = scrollRef.current; if (!el) return;
    const h = () => setScrollY(el.scrollTop);
    el.addEventListener('scroll', h, { passive: true });
    return () => el.removeEventListener('scroll', h);
  }, [scrollRef]);

  // Parallax + glow fade were the source of the "slider goes empty" bug — disabled.
  // Kept the scrollY listener around in case other sections want it later.
  const heroOpacity = 1;
  const heroParallax = 0;

  return (
    <div style={{ paddingBottom: 120 }}>
      <Banner T={T} />
      <div style={{
        position: 'sticky', top: 0, zIndex: 20,
        padding: '8px 20px 8px',
        background: scrollY > 40 ? `color-mix(in oklab, ${T.bg}, transparent 10%)` : 'transparent',
        backdropFilter: scrollY > 40 ? 'blur(16px)' : 'none',
        WebkitBackdropFilter: scrollY > 40 ? 'blur(16px)' : 'none',
        transition: 'background 0.3s ease',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        gap: 12,
      }}>
        <img src="assets/logo.png?v=2" alt="La Pharmacia" style={{
          height: 72, width: 'auto', maxWidth: 'calc(100% - 200px)',
          objectFit: 'contain', display: 'block',
          filter: 'brightness(0) invert(1)',
        }} />
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <button
            onClick={() => window.open(`https://waze.com/ul?ll=${SETTINGS.waze_lat},${SETTINGS.waze_lng}&navigate=yes`, '_blank', 'noopener')}
            style={{
              display: 'flex', alignItems: 'center', gap: 6,
              height: 40, padding: '0 12px', borderRadius: 20,
              background: `color-mix(in oklab, ${T.accent}, transparent 80%)`,
              border: `1px solid color-mix(in oklab, ${T.accent}, transparent 50%)`,
              color: T.accent, cursor: 'pointer', fontFamily: 'inherit',
              transition: 'transform 0.2s, background 0.2s',
            }}
            onPointerDown={e => e.currentTarget.style.transform = 'scale(0.94)'}
            onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
            onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
            <Icon name="pin" size={15} strokeWidth={1.8} />
            <span style={{ fontSize: 11.5, fontWeight: 600, letterSpacing: 0.3 }}>ניווט</span>
          </button>
          <IconBtn T={T} icon="search" onClick={onOpenSearch} />
        </div>
      </div>

      {/* Hero slider — admin-managed */}
      <HomeSlider T={T} displayFont={displayFont} showGlow={showGlow}
        heroParallax={heroParallax} heroOpacity={heroOpacity}
        layout="mobile"
        onCta={(action) => {
          if (action.type === 'category') onOpenCategory(action.id);
          else if (action.type === 'tab') onOpenCategory('__all'); // tab='shop' resolves to ShopScreen via __all
        }} />

      {/* Categories — featured + show all */}
      <div style={{
        display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
        padding: '14px 20px 12px',
      }}>
        <div>
          <div style={{ fontSize: 10, color: T.accent, fontWeight: 700, letterSpacing: 0.5 }}>קטגוריות</div>
          <div style={{ fontFamily: displayFont, fontSize: 24, color: T.ink, fontWeight: 700, marginTop: 4 }}>קניה לפי תחום</div>
        </div>
        <button onClick={() => onOpenCategory('__all')} style={{
          padding: '8px 14px', borderRadius: 999,
          background: 'transparent', border: `1px solid ${T.line}`,
          color: T.ink, fontSize: 11, fontWeight: 600, cursor: 'pointer',
          fontFamily: 'inherit', display: 'inline-flex', alignItems: 'center', gap: 6,
        }}>
          הצג הכל <Icon name="left" size={12} strokeWidth={2} />
        </button>
      </div>
      {/* Featured cat — big card */}
      <button onClick={() => onOpenCategory(CATEGORIES[0].id)} style={{
        margin: '0 16px 12px', height: 220, width: 'calc(100% - 32px)',
        borderRadius: 26, overflow: 'hidden', position: 'relative',
        border: `1px solid ${T.line}`, background: 'transparent',
        padding: 0, cursor: 'pointer', textAlign: 'right',
        boxShadow: showGlow ? `0 20px 50px -20px ${T.glow}` : 'none',
      }}>
        <Img src={CATEGORIES[0].img} style={{ position: 'absolute', inset: 0 }} />
        <div style={{ position: 'absolute', inset: 0,
          background: `linear-gradient(270deg, ${T.bg}f0 0%, ${T.bg}80 40%, transparent 75%)` }} />
        <div style={{ position: 'absolute', insetInlineEnd: 22, top: '50%', transform: 'translateY(-50%)' }}>
          <div style={{ fontSize: 10, color: T.accent, fontWeight: 700, letterSpacing: 1 }}>★ נבחר</div>
          <div style={{ fontFamily: displayFont, fontSize: 36, color: T.ink, marginTop: 6, lineHeight: 1, fontWeight: 700 }}>{CATEGORIES[0].label}</div>
          <div style={{ fontSize: 12, color: T.inkDim, marginTop: 6 }}>{CATEGORIES[0].sub}</div>
          <div style={{
            marginTop: 14, display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '8px 14px', borderRadius: 999,
            background: T.ink, color: T.bg, fontSize: 11, fontWeight: 700,
          }}>
            לקטגוריה <Icon name="left" size={12} strokeWidth={2.4} />
          </div>
        </div>
      </button>
      {/* Other cats — grid 3 */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10, margin: '0 16px 12px' }}>
        {CATEGORIES.slice(1).map((c, i) => (
          <button key={c.id} onClick={() => onOpenCategory(c.id)} style={{
            position: 'relative', height: 130, borderRadius: 18, overflow: 'hidden',
            border: `1px solid ${T.line}`, background: 'transparent', padding: 0,
            cursor: 'pointer', textAlign: 'right',
          }}>
            <Img src={c.img} style={{ position: 'absolute', inset: 0 }} />
            <div style={{ position: 'absolute', inset: 0,
              background: `linear-gradient(180deg, transparent 30%, ${T.bg}e0 100%)` }} />
            <div style={{ position: 'absolute', insetInlineStart: 8, insetInlineEnd: 8, bottom: 8 }}>
              <div style={{ fontFamily: displayFont, fontSize: 14, color: T.ink, fontWeight: 700, lineHeight: 1 }}>{c.label}</div>
              <div style={{ fontSize: 9, color: T.inkDim, marginTop: 3 }}>{c.sub}</div>
            </div>
          </button>
        ))}
        {/* Show all tile */}
        <button onClick={() => onOpenCategory('__all')} style={{
          position: 'relative', height: 130, borderRadius: 18, overflow: 'hidden',
          border: `1px dashed ${T.line}`, background: T.bgSoft, padding: 0,
          cursor: 'pointer', display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center', gap: 6, color: T.ink,
        }}>
          <div style={{
            width: 36, height: 36, borderRadius: 18,
            background: T.accent, color: T.bg,
            display: 'grid', placeItems: 'center',
          }}>
            <Icon name="grid" size={18} strokeWidth={2} />
          </div>
          <div style={{ fontSize: 11, fontWeight: 700, fontFamily: displayFont }}>הצג הכל</div>
          <div style={{ fontSize: 9, color: T.inkMute }}>{CATEGORIES.length}+ קטגוריות</div>
        </button>
      </div>

      {/* (stories moved to top) */}
      <SectionHead T={T} displayFont={displayFont} title="חדש בחנות" link="עוד" />
      <div className="hide-scroll" style={{
        display: 'flex', gap: 12, overflowX: 'auto',
        padding: '4px 16px 8px', scrollSnapType: 'x mandatory',
      }}>
        {PRODUCTS.slice(0, 6).map(p => (
          <ProductCardWide key={p.id} T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} />
        ))}
      </div>

      {/* Brands — only those admin flagged as featured. Trailing "show all" tile
          lives inside the grid so it sits next to the brand cards and reads as
          a peer affordance (not just a corner link). */}
      {(() => {
        const featuredBrands = BRANDS.filter(b => b.featured);
        if (featuredBrands.length === 0) return null;
        const hasMore = BRANDS.length > featuredBrands.length;
        return (
          <>
            <SectionHead T={T} displayFont={displayFont} title="מותגים מובילים" link="הכל" onLinkClick={onOpenAllBrands} />
            <div style={{
              display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10,
              padding: '4px 16px 8px',
            }}>
              {featuredBrands.map(b => <BrandCard key={b.id} T={T} b={b} displayFont={displayFont} onOpen={() => onOpenBrand(b.id)} />)}
              <BrandShowAllCard T={T} displayFont={displayFont} onOpen={onOpenAllBrands} extraCount={hasMore ? BRANDS.length - featuredBrands.length : null} />
            </div>
          </>
        );
      })()}

      {/* Instagram strip — admin-managed via /api/instagram/posts, branded with the IG logo */}
      <InstagramStrip T={T} displayFont={displayFont} layout="mobile" />

      {/* Best sellers — only those admin flagged as featured. Later: auto-derived from real sales. */}
      {(() => {
        const bestSellers = PRODUCTS.filter(p => p.featured);
        if (bestSellers.length === 0) return null;
        return (
          <>
            <SectionHead T={T} displayFont={displayFont} title="הכי נמכרים" link="הכל" />
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, padding: '4px 16px 24px' }}>
              {bestSellers.slice(0, 8).map(p => (
                <ProductCard key={p.id} T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} />
              ))}
            </div>
          </>
        );
      })()}

      <div style={{
        margin: '8px 16px 0', padding: '18px 16px',
        borderRadius: 20, border: `1px solid ${T.line}`,
        display: 'flex', justifyContent: 'space-around', textAlign: 'center',
      }}>
        {[
          { icon: 'truck', l: 'משלוח חינם מ-300₪' },
          { icon: 'shield', l: 'אותנטי 100%' },
          { icon: 'leaf', l: 'החזרה תוך 30 יום' },
        ].map(x => (
          <div key={x.l} style={{ display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'center', color: T.ink }}>
            <Icon name={x.icon} size={18} />
            <div style={{ fontSize: 10, color: T.inkDim }}>{x.l}</div>
          </div>
        ))}
      </div>

      {/* Brand footer + socials */}
      <div style={{ margin: '32px 16px 0', padding: '28px 20px 24px', borderTop: `1px solid ${T.line}`, textAlign: 'center' }}>
        <div style={{ fontFamily: 'Frank Ruhl Libre, serif', fontSize: 26, color: T.ink, letterSpacing: 0.4, marginBottom: 6 }}>
          La <span style={{ color: T.accent, fontStyle: 'italic' }}>Pharmacia</span>
        </div>
        <div style={{ fontSize: 12, color: T.inkMute, letterSpacing: 1, textTransform: 'uppercase', marginBottom: 18 }}>
          {SETTINGS.store_address}
        </div>
        <div style={{ display: 'flex', justifyContent: 'center', gap: 12, marginBottom: 18 }}>
          {[
            { icon: 'phone', label: 'Phone',     href: SETTINGS.store_phone ? `tel:${String(SETTINGS.store_phone).replace(/[^\d+]/g, '')}` : '', external: false },
            { icon: 'insta', label: 'Instagram', href: SETTINGS.social_instagram, external: true },
            { icon: 'fb',    label: 'Facebook',  href: SETTINGS.social_facebook,  external: true },
            { icon: 'wapp',  label: 'WhatsApp',  href: SETTINGS.social_whatsapp,  external: true },
            { icon: 'pin',   label: 'Waze',      href: `https://waze.com/ul?ll=${SETTINGS.waze_lat},${SETTINGS.waze_lng}&navigate=yes`, external: true },
          ].filter(s => s.href && s.href !== '').map(s => (
            <a key={s.label} href={s.href} {...(s.external ? { target: '_blank', rel: 'noopener' } : {})} aria-label={s.label}
              style={{
                width: 44, height: 44, borderRadius: 22,
                border: `1px solid ${T.line}`, color: T.inkDim,
                display: 'grid', placeItems: 'center',
                transition: 'color 0.2s, border-color 0.2s, background 0.2s',
                textDecoration: 'none',
              }}
              onPointerEnter={e => { e.currentTarget.style.color = T.accent; e.currentTarget.style.borderColor = T.accent; }}
              onPointerLeave={e => { e.currentTarget.style.color = T.inkDim; e.currentTarget.style.borderColor = T.line; }}>
              <Icon name={s.icon} size={18} strokeWidth={1.6} />
            </a>
          ))}
        </div>
        <div style={{ fontSize: 10.5, color: T.inkMute, letterSpacing: 0.5, lineHeight: 1.7 }}>
          © 2026 La Pharmacia · כל הזכויות שמורות<br/>
          <span style={{ color: T.inkMute, opacity: 0.7 }}>VISA · MASTERCARD · BIT · APPLE PAY</span>
        </div>
        {onOpenTrackOrder && (
          <button onClick={onOpenTrackOrder} style={{
            marginTop: 14, background: 'none', border: 'none',
            color: T.accent, fontSize: 11.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
            letterSpacing: 0.4,
          }}>מעקב הזמנה ←</button>
        )}
        {onOpenLegal && (
          <div style={{ marginTop: 14, display: 'flex', gap: 14, justifyContent: 'center', flexWrap: 'wrap' }}>
            <a onClick={() => onOpenLegal('privacy')} style={{ fontSize: 10.5, color: T.inkMute, cursor: 'pointer' }}>פרטיות</a>
            <a onClick={() => onOpenLegal('terms')}   style={{ fontSize: 10.5, color: T.inkMute, cursor: 'pointer' }}>תקנון</a>
            <a onClick={() => onOpenLegal('returns')} style={{ fontSize: 10.5, color: T.inkMute, cursor: 'pointer' }}>החזרות</a>
          </div>
        )}
      </div>
    </div>
  );
}

function CategoryCard({ T, c, i, onOpen, displayFont, showGlow }) {
  const [hover, setHover] = useState(false);
  return (
    <button onClick={onOpen}
      onPointerEnter={() => setHover(true)} onPointerLeave={() => setHover(false)}
      style={{
        position: 'relative', height: i % 3 === 0 ? 200 : 170,
        borderRadius: 22, overflow: 'hidden',
        border: `1px solid ${T.line}`, cursor: 'pointer',
        background: 'transparent', padding: 0, textAlign: 'right',
        transition: 'transform 0.4s cubic-bezier(0.2,0.8,0.2,1), box-shadow 0.4s',
        transform: hover ? 'translateY(-2px)' : 'translateY(0)',
        boxShadow: hover && showGlow ? `0 18px 40px -10px ${T.glow}` : 'none',
      }}>
      <Img src={c.img} style={{
        position: 'absolute', inset: 0,
        transform: hover ? 'scale(1.08)' : 'scale(1.02)',
        transition: 'transform 0.6s cubic-bezier(0.2,0.8,0.2,1)',
      }} />
      <div style={{ position: 'absolute', inset: 0,
        background: `linear-gradient(to top, ${T.bg} 0%, ${T.bg}80 30%, transparent 65%)` }} />
      <div style={{ position: 'absolute', insetInlineStart: 14, insetInlineEnd: 14, bottom: 12,
        display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, lineHeight: 1, fontWeight: 700 }}>{c.label}</div>
          <div style={{ fontSize: 10.5, color: T.inkDim, marginTop: 4 }}>{c.sub}</div>
        </div>
        <div style={{
          width: 30, height: 30, borderRadius: 15,
          background: `color-mix(in oklab, ${T.ink}, transparent 80%)`,
          backdropFilter: 'blur(8px)',
          display: 'grid', placeItems: 'center', color: T.ink,
          transform: hover ? 'translateX(-2px)' : 'translateX(0)',
          transition: 'transform 0.4s',
        }}>
          <Icon name="left" size={14} strokeWidth={2} />
        </div>
      </div>
    </button>
  );
}

// ── Story circle (Instagram-style round avatar) ──
function StoryCircle({ T, s, displayFont }) {
  const [pressed, setPressed] = useState(false);
  return (
    <button
      onPointerDown={() => setPressed(true)} onPointerUp={() => setPressed(false)} onPointerLeave={() => setPressed(false)}
      style={{
        flex: '0 0 76px', scrollSnapAlign: 'start',
        background: 'none', border: 'none', padding: 0, cursor: 'pointer',
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
        transform: pressed ? 'scale(0.94)' : 'scale(1)',
        transition: 'transform 0.2s cubic-bezier(0.2,0.8,0.2,1)',
      }}>
      <div style={{
        width: 70, height: 70, borderRadius: 35,
        padding: 2.5,
        background: `conic-gradient(from 220deg, ${T.accent}, ${T.ink}, ${T.accent})`,
        boxShadow: `0 0 12px ${T.glow}`,
      }}>
        <div style={{
          width: '100%', height: '100%', borderRadius: '50%',
          overflow: 'hidden', border: `2px solid ${T.bg}`,
        }}>
          <Img src={s.img} style={{ width: '100%', height: '100%' }} />
        </div>
      </div>
      <div style={{ fontSize: 9.5, color: T.ink, fontFamily: displayFont, fontWeight: 600, textAlign: 'center', lineHeight: 1.1, maxWidth: 76, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{s.title}</div>
    </button>
  );
}

// ── Story big card (kept for future use) ──
function StoryCard({ T, s, displayFont, showGlow }) {
  const [pressed, setPressed] = useState(false);
  return (
    <button
      onPointerDown={() => setPressed(true)} onPointerUp={() => setPressed(false)} onPointerLeave={() => setPressed(false)}
      style={{
        flex: '0 0 110px', scrollSnapAlign: 'start',
        position: 'relative', height: 160, borderRadius: 20, overflow: 'hidden',
        background: 'transparent', border: 'none', padding: 0, cursor: 'pointer',
        textAlign: 'right',
        transform: pressed ? 'scale(0.96)' : 'scale(1)',
        transition: 'transform 0.25s cubic-bezier(0.2,0.8,0.2,1)',
        boxShadow: showGlow ? `0 0 0 2px ${T.accent}, 0 12px 28px -12px ${T.glow}` : `0 0 0 2px ${T.accent}`,
      }}>
      <Img src={s.img} style={{ position: 'absolute', inset: 0 }} />
      <div style={{ position: 'absolute', inset: 0,
        background: `linear-gradient(to top, ${T.bg}f0 0%, ${T.bg}40 35%, transparent 60%)` }} />
      <div style={{ position: 'absolute', top: 10, insetInlineEnd: 10,
        width: 8, height: 8, borderRadius: 4, background: T.accent,
        boxShadow: `0 0 8px ${T.accent}`, animation: 'pulse 1.6s ease-in-out infinite',
      }} />
      <div style={{ position: 'absolute', insetInlineStart: 10, insetInlineEnd: 10, bottom: 10 }}>
        <div style={{ fontSize: 9, color: T.accent, fontWeight: 700, letterSpacing: 0.5 }}>{s.sub}</div>
        <div style={{ fontFamily: displayFont, fontSize: 13, color: T.ink, marginTop: 2, lineHeight: 1.2, fontWeight: 700 }}>{s.title}</div>
      </div>
    </button>
  );
}

// ── Brand chip ──
function BrandCard({ T, b, displayFont, onOpen }) {
  const [pressed, setPressed] = useState(false);
  return (
    <button onClick={onOpen}
      onPointerDown={() => setPressed(true)} onPointerUp={() => setPressed(false)} onPointerLeave={() => setPressed(false)}
      style={{
        position: 'relative', height: 110, borderRadius: 18, overflow: 'hidden',
        background: T.bgCard, border: `1px solid ${T.line}`, padding: 0, cursor: 'pointer',
        textAlign: 'center',
        transform: pressed ? 'scale(0.96)' : 'scale(1)',
        transition: 'transform 0.25s cubic-bezier(0.2,0.8,0.2,1)',
      }}>
      <Img src={b.img} style={{ position: 'absolute', inset: 0, opacity: 0.35 }} />
      <div style={{ position: 'absolute', inset: 0,
        background: `linear-gradient(180deg, ${T.bgCard}80 0%, ${T.bgCard} 70%)` }} />
      <div style={{ position: 'relative', height: '100%', display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center', padding: 8 }}>
        <div style={{ fontFamily: displayFont, fontSize: 14, color: T.ink, fontWeight: 700, letterSpacing: 0.3, lineHeight: 1.1 }}>{b.name}</div>
        <div style={{ marginTop: 6, fontSize: 10, color: T.inkMute }}>{b.count} מוצרים</div>
      </div>
    </button>
  );
}

// "Show all brands" tile — sized to match BrandCard so it slots into the same grid.
// Renders as the last cell so the affordance is unmistakable, not a corner link.
function BrandShowAllCard({ T, displayFont, onOpen, extraCount }) {
  const [pressed, setPressed] = useState(false);
  return (
    <button onClick={onOpen}
      onPointerDown={() => setPressed(true)} onPointerUp={() => setPressed(false)} onPointerLeave={() => setPressed(false)}
      style={{
        position: 'relative', height: 110, borderRadius: 18, overflow: 'hidden',
        background: T.bgSoft, border: `1px dashed ${T.line}`, padding: 0, cursor: 'pointer',
        textAlign: 'center',
        transform: pressed ? 'scale(0.96)' : 'scale(1)',
        transition: 'transform 0.25s cubic-bezier(0.2,0.8,0.2,1), background 0.2s',
      }}>
      <div style={{ position: 'relative', height: '100%', display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center', padding: 8, gap: 4 }}>
        <div style={{
          width: 32, height: 32, borderRadius: 16,
          background: T.bgCard, border: `1px solid ${T.line}`,
          display: 'grid', placeItems: 'center', color: T.ink,
        }}>
          <Icon name="left" size={16} />
        </div>
        <div style={{ fontFamily: displayFont, fontSize: 12, color: T.ink, fontWeight: 700, letterSpacing: 0.3, lineHeight: 1.1, marginTop: 4 }}>כל המותגים</div>
        {extraCount != null && (
          <div style={{ fontSize: 10, color: T.inkMute }}>{extraCount}+ נוספים</div>
        )}
      </div>
    </button>
  );
}

// ── All-brands page — every brand in a grid, opens the per-brand page on tap ──
function BrandsScreen({ T, displayFont, onBack, onOpenBrand }) {
  // Sort featured ones first so the experience stays consistent with the home strip.
  const all = [...BRANDS].sort((a, b) => (b.featured ? 1 : 0) - (a.featured ? 1 : 0));
  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ position: 'relative', height: 200, overflow: 'hidden' }}>
        <div style={{ position: 'absolute', inset: 0,
          background: `linear-gradient(135deg, ${T.bgCard} 0%, ${T.bg} 100%)` }} />
        <div style={{ position: 'absolute', top: 54, insetInlineStart: 16, insetInlineEnd: 16, display: 'flex', justifyContent: 'space-between' }}>
          <IconBtn T={T} icon="right" onClick={onBack} />
          <IconBtn T={T} icon="search" />
        </div>
        <div style={{ position: 'absolute', insetInlineStart: 20, insetInlineEnd: 20, bottom: 20 }}>
          <div style={{ fontSize: 10, color: T.accent, letterSpacing: 1.5, fontWeight: 600, textTransform: 'uppercase' }}>בעולם שלנו</div>
          <div style={{ fontFamily: displayFont, fontSize: 38, color: T.ink, lineHeight: 1.1, marginTop: 6, fontWeight: 700 }}>כל המותגים</div>
          <div style={{ marginTop: 6, color: T.inkDim, fontSize: 12 }}>{all.length} מותגים</div>
        </div>
      </div>

      {all.length === 0 ? (
        <div style={{ padding: '60px 24px', textAlign: 'center', color: T.inkDim }}>
          <div style={{ fontSize: 13 }}>עוד לא נוספו מותגים.</div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, padding: '16px 16px 0' }}>
          {all.map(b => <BrandCard key={b.id} T={T} b={b} displayFont={displayFont} onOpen={() => onOpenBrand(b.id)} />)}
        </div>
      )}
    </div>
  );
}

// ── Brand page — all products from a single brand ──
function BrandScreen({ T, displayFont, brandId, onBack, onOpenProduct }) {
  const brand = BRANDS.find(b => b.id === brandId);
  const items = PRODUCTS.filter(p => p.brandId === brandId || p.brand_id === brandId);
  if (!brand) return (
    <div style={{ padding: 60, textAlign: 'center', color: T.inkDim }}>
      <IconBtn T={T} icon="right" onClick={onBack} />
      <div style={{ marginTop: 24 }}>מותג לא נמצא</div>
    </div>
  );

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ position: 'relative', height: 260, overflow: 'hidden' }}>
        {brand.img && <Img src={brand.img} style={{ position: 'absolute', inset: 0 }} />}
        <div style={{ position: 'absolute', inset: 0,
          background: `linear-gradient(to bottom, ${T.bg}80 0%, transparent 30%, ${T.bg})` }} />
        <div style={{ position: 'absolute', top: 54, insetInlineStart: 16, insetInlineEnd: 16, display: 'flex', justifyContent: 'space-between' }}>
          <IconBtn T={T} icon="right" onClick={onBack} />
          <IconBtn T={T} icon="search" />
        </div>
        <div style={{ position: 'absolute', insetInlineStart: 20, insetInlineEnd: 20, bottom: 20 }}>
          <div style={{ fontSize: 10, color: T.accent, letterSpacing: 1.5, fontWeight: 600, textTransform: 'uppercase' }}>מותג</div>
          <div style={{ fontFamily: displayFont, fontSize: 38, color: T.ink, lineHeight: 1.1, marginTop: 6, fontWeight: 700 }}>{brand.name}</div>
          <div style={{ marginTop: 6, color: T.inkDim, fontSize: 12 }}>{items.length} מוצרים</div>
        </div>
      </div>

      {items.length === 0 ? (
        <div style={{ padding: '60px 24px', textAlign: 'center', color: T.inkDim }}>
          <Icon name="bag" size={36} color={T.inkMute} />
          <div style={{ marginTop: 14, fontSize: 13 }}>עוד לא נוספו מוצרים למותג הזה.</div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, padding: '16px 16px 0' }}>
          {items.map(p => <ProductCard key={p.id} T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} />)}
        </div>
      )}
    </div>
  );
}
function ProductCardWide({ T, p, onOpen, displayFont }) {
  return (
    <button onClick={onOpen} style={{
      flex: '0 0 200px', scrollSnapAlign: 'start',
      background: T.bgCard, border: `1px solid ${T.line}`,
      borderRadius: 22, overflow: 'hidden',
      padding: 0, cursor: 'pointer', textAlign: 'right',
      transition: 'transform 0.3s',
    }}
    onPointerDown={e => e.currentTarget.style.transform = 'scale(0.97)'}
    onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
    onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
      <div style={{ height: 220, position: 'relative' }}>
        <Img src={p.img} style={{ width: '100%', height: '100%' }} />
        {p.tag && (
          <div style={{
            position: 'absolute', top: 10, insetInlineStart: 10,
            padding: '4px 10px', borderRadius: 999,
            background: p.tag.includes('%') ? T.accent : `color-mix(in oklab, ${T.ink}, transparent 85%)`,
            color: p.tag.includes('%') ? T.bg : T.ink,
            fontSize: 9.5, fontWeight: 700, letterSpacing: 0.5,
            border: p.tag.includes('%') ? 'none' : `1px solid ${T.line}`,
            backdropFilter: 'blur(8px)',
          }}>{p.tag}</div>
        )}
        <div style={{
          position: 'absolute', top: 10, insetInlineEnd: 10,
          width: 30, height: 30, borderRadius: 15,
          background: `color-mix(in oklab, ${T.bg}, transparent 30%)`,
          backdropFilter: 'blur(10px)',
          display: 'grid', placeItems: 'center', color: T.ink,
          border: `1px solid ${T.line}`,
        }}>
          <Icon name="heart" size={14} />
        </div>
      </div>
      <div style={{ padding: '12px 14px 14px' }}>
        <div style={{ fontSize: 9.5, color: T.inkMute, letterSpacing: 0.5 }}>{p.brand}</div>
        <div style={{ fontFamily: displayFont, fontSize: 15, color: T.ink, marginTop: 3, lineHeight: 1.3, fontWeight: 600 }}>{p.name}</div>
        <div style={{ marginTop: 8, color: T.ink, fontWeight: 700, fontSize: 14, display: 'flex', gap: 8, alignItems: 'baseline' }}>
          {fmt(p.price)}
          {p.was && <span style={{ color: T.inkMute, fontSize: 11, textDecoration: 'line-through', fontWeight: 400 }}>{fmt(p.was)}</span>}
        </div>
      </div>
    </button>
  );
}

function ProductCard({ T, p, onOpen, displayFont, dense }) {
  const [pressed, setPressed] = useState(false);
  const oos = (p.stock ?? 999) <= 0;
  return (
    <button onClick={onOpen}
      onPointerDown={() => setPressed(true)} onPointerUp={() => setPressed(false)} onPointerLeave={() => setPressed(false)}
      style={{
        background: T.bgCard, border: `1px solid ${T.line}`,
        borderRadius: 20, overflow: 'hidden',
        padding: 0, cursor: 'pointer', textAlign: 'right',
        transform: pressed ? 'scale(0.97)' : 'scale(1)',
        transition: 'transform 0.25s cubic-bezier(0.2,0.8,0.2,1)',
        position: 'relative',
        opacity: oos ? 0.55 : 1,
      }}>
      <div style={{ height: dense ? 140 : 175, position: 'relative' }}>
        <Img src={p.img} style={{ width: '100%', height: '100%' }} />
        {p.tag && !oos && (
          <div style={{
            position: 'absolute', top: 8, insetInlineStart: 8,
            padding: '3px 9px', borderRadius: 999,
            background: p.tag.includes('%') ? T.accent : `color-mix(in oklab, ${T.bg}, transparent 30%)`,
            color: p.tag.includes('%') ? T.bg : T.ink,
            fontSize: 9, fontWeight: 700, letterSpacing: 0.5,
            backdropFilter: 'blur(8px)',
          }}>{p.tag}</div>
        )}
        {oos && (
          <div style={{
            position: 'absolute', top: 8, insetInlineStart: 8,
            padding: '4px 10px', borderRadius: 999,
            background: T.bg, color: T.ink, opacity: 0.95,
            fontSize: 10, fontWeight: 700, letterSpacing: 0.8,
          }}>אזל</div>
        )}
      </div>
      <div style={{ padding: '10px 12px 12px' }}>
        <div style={{ fontSize: 9, color: T.inkMute, letterSpacing: 0.4 }}>{p.brand}</div>
        <div style={{ fontFamily: displayFont, fontSize: 13.5, color: T.ink, marginTop: 2, lineHeight: 1.2,
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontWeight: 600,
        }}>{p.name}</div>
        <div style={{ marginTop: 6, color: T.ink, fontWeight: 700, fontSize: 13, display: 'flex', gap: 6, alignItems: 'baseline' }}>
          {fmt(p.price)}
          {p.was && <span style={{ color: T.inkMute, fontSize: 10.5, textDecoration: 'line-through', fontWeight: 400 }}>{fmt(p.was)}</span>}
        </div>
      </div>
    </button>
  );
}

// ── Category ──
function CategoryScreen({ T, displayFont, denseGrid, catId, onBack, onOpenProduct }) {
  const cat = CATEGORIES.find(c => c.id === catId) || CATEGORIES[0];
  const items = PRODUCTS.filter(p => p.cat === catId).concat(PRODUCTS.filter(p => p.cat !== catId));
  const [filter, setFilter] = useState('all');
  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ position: 'relative', height: 280, overflow: 'hidden' }}>
        <Img src={cat.img} style={{ position: 'absolute', inset: 0 }} />
        <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(to bottom, transparent 30%, ${T.bg})` }} />
        <div style={{ position: 'absolute', top: 54, insetInlineStart: 16, insetInlineEnd: 16, display: 'flex', justifyContent: 'space-between' }}>
          <IconBtn T={T} icon="right" onClick={onBack} />
          <IconBtn T={T} icon="search" />
        </div>
        <div style={{ position: 'absolute', insetInlineStart: 20, insetInlineEnd: 20, bottom: 20 }}>
          <div style={{ fontSize: 10, color: T.accent, letterSpacing: 1, fontWeight: 600 }}>קטגוריה</div>
          <div style={{ fontFamily: displayFont, fontSize: 44, color: T.ink, lineHeight: 1, marginTop: 8, fontWeight: 700 }}>{cat.label}</div>
          <div style={{ marginTop: 6, color: T.inkDim, fontSize: 12 }}>{cat.sub} · נבחר עבורך</div>
        </div>
      </div>

      <div className="hide-scroll" style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '14px 16px' }}>
        <button style={{
          padding: '8px 14px', borderRadius: 999, border: `1px solid ${T.line}`, background: T.bgCard,
          color: T.ink, fontSize: 11, fontWeight: 600,
          display: 'inline-flex', alignItems: 'center', gap: 6, flexShrink: 0, cursor: 'pointer',
        }}>
          <Icon name="filter" size={14} /> סינון
        </button>
        {['הכל', 'חדש', 'מתחת ל-500₪', 'במבצע', 'Maison Cervo', 'Atelier Noir'].map(f => {
          const on = (f === 'הכל' && filter === 'all') || filter === f;
          return (
            <button key={f} onClick={() => setFilter(f === 'הכל' ? 'all' : f)} style={{
              padding: '8px 14px', borderRadius: 999,
              border: `1px solid ${on ? T.ink : T.line}`,
              background: on ? T.ink : 'transparent',
              color: on ? T.bg : T.inkDim,
              fontSize: 11, fontWeight: 500,
              flexShrink: 0, cursor: 'pointer', transition: 'all 0.2s',
            }}>{f}</button>
          );
        })}
      </div>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '6px 20px 12px', color: T.inkMute, fontSize: 11 }}>
        <span>{items.length} מוצרים</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: T.ink }}>
          מיון: מומלץ <Icon name="chevron" size={12} />
        </span>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: denseGrid ? 8 : 14, padding: '0 16px' }}>
        {items.map(p => <ProductCard key={p.id} T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} dense={denseGrid} />)}
      </div>
    </div>
  );
}

// ── Product ──
function ProductScreen({ T, displayFont, showGlow, product, onBack, onAdd, inWishlist, onToggleWish }) {
  // Fetch the full product on mount to get variants — list responses don't include them
  const [variants, setVariants] = useState([]);
  const [selectedVariant, setSelectedVariant] = useState(null);
  const [added, setAdded] = useState(false);

  useEffect(() => {
    let cancelled = false;
    window.API.get('/products/' + product.id).then(r => {
      if (cancelled) return;
      const vs = r.product?.variants || [];
      setVariants(vs);
      // Default to the cheapest variant so the card price and the opened page match.
      // Falls back to the first (admin-sorted) variant if prices are tied.
      if (vs.length > 0) {
        const cheapest = [...vs].sort((a, b) => a.price - b.price)[0];
        setSelectedVariant(cheapest);
      }
    }).catch(() => {});
    return () => { cancelled = true; };
  }, [product.id]);

  // Selected variant overrides product-level fields when present
  const effectivePrice = selectedVariant?.price ?? product.price;
  const effectiveWas   = selectedVariant?.was   ?? product.was;
  const effectiveImg   = selectedVariant?.img   || product.img;
  const effectiveStock = selectedVariant ? selectedVariant.stock : (product.stock ?? 999);
  const oos = effectiveStock <= 0;
  const variantLabel = selectedVariant?.label || null;

  const handleAdd = () => {
    if (oos) return;
    // When a variant is picked, the cart line must use THAT variant's price/img/was —
    // not the product-level (cheapest-variant) fallback. Logged-in carts get this
    // correction from the server's JOIN, but guest carts persist whatever we pass in.
    const cartProduct = selectedVariant
      ? {
          ...product,
          price: selectedVariant.price,
          was:   selectedVariant.was ?? product.was,
          img:   selectedVariant.img || product.img,
        }
      : product;
    onAdd(cartProduct, variantLabel, selectedVariant?.id);
    setAdded(true);
    setTimeout(() => setAdded(false), 1400);
  };
  return (
    <div style={{ paddingBottom: 0, position: 'relative', minHeight: '100%' }}>
      <div style={{ position: 'relative', height: 460, background: T.bgSoft, overflow: 'hidden' }}>
        {showGlow && (
          <div style={{ position: 'absolute', inset: 0,
            background: `radial-gradient(ellipse at 50% 60%, ${T.glow}, transparent 60%)`,
            opacity: 0.5, pointerEvents: 'none' }} />
        )}
        <Img src={effectiveImg} style={{ position: 'absolute', inset: 0 }} />
        <div style={{ position: 'absolute', inset: 0,
          background: `linear-gradient(to bottom, ${T.bg}40 0%, transparent 18%, transparent 78%, ${T.bg} 100%)`,
          pointerEvents: 'none' }} />
        <div style={{ position: 'absolute', top: 54, insetInlineStart: 16, insetInlineEnd: 16, display: 'flex', justifyContent: 'space-between' }}>
          <IconBtn T={T} icon="right" onClick={onBack} />
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={onToggleWish} aria-label={inWishlist ? 'הסר מהמועדפים' : 'שמירה למועדפים'} style={{
              width: 40, height: 40, borderRadius: 20,
              background: inWishlist
                ? `color-mix(in oklab, ${T.accent}, transparent 70%)`
                : `color-mix(in oklab, ${T.bgCard}, transparent 30%)`,
              border: `1px solid ${inWishlist ? T.accent : T.line}`,
              color: inWishlist ? T.accent : T.ink,
              cursor: 'pointer', display: 'grid', placeItems: 'center',
              transition: 'all 0.2s',
            }}>
              <Icon name="heart" size={18} strokeWidth={inWishlist ? 2.2 : 1.6} />
            </button>
            <IconBtn T={T} icon="search" />
          </div>
        </div>
        <div style={{ position: 'absolute', bottom: 16, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 6 }}>
          {[0,1,2,3].map(i => (
            <div key={i} style={{
              width: i === 0 ? 18 : 6, height: 6, borderRadius: 3,
              background: i === 0 ? T.ink : `color-mix(in oklab, ${T.ink}, transparent 70%)`,
              transition: 'width 0.3s',
            }} />
          ))}
        </div>
      </div>

      <div style={{ padding: '20px 22px 16px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div style={{ fontSize: 10.5, color: T.accent, letterSpacing: 0.5, fontWeight: 600 }}>{product.brand}</div>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: T.inkDim, fontSize: 11 }}>
            <Icon name="star" size={12} color={T.accent} /> 4.8 · 124 ביקורות
          </div>
        </div>
        <div style={{ fontFamily: displayFont, fontSize: 28, color: T.ink, lineHeight: 1.15, marginTop: 8, fontWeight: 700 }}>
          {product.name}
        </div>
        <div style={{ marginTop: 14, display: 'flex', gap: 10, alignItems: 'baseline' }}>
          <div style={{ fontFamily: displayFont, fontSize: 26, color: T.ink, fontWeight: 700 }}>{fmt(effectivePrice)}</div>
          {effectiveWas && <div style={{ color: T.inkMute, fontSize: 14, textDecoration: 'line-through' }}>{fmt(effectiveWas)}</div>}
        </div>

        <div style={{ marginTop: 18, color: T.inkDim, fontSize: 13.5, lineHeight: 1.7 }}>
          מדיטציה של ענבר חם, וניל קטיפתי וארז אטלס.
          תווי פתיחה של ברגמוט נמסים לבסיס רך —
          מעוצב לרגעים שנמשכים.
        </div>

        {/* Variant picker — only shown when the admin defined variants for this product */}
        {variants.length > 0 && (
          <div style={{ marginTop: 22 }}>
            <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5, marginBottom: 10, fontWeight: 600 }}>
              אפשרות
            </div>
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              {variants.map(v => {
                const on = selectedVariant?.id === v.id;
                const vOos = v.stock <= 0;
                return (
                  <button key={v.id} onClick={() => !vOos && setSelectedVariant(v)} disabled={vOos} style={{
                    flex: '1 1 auto', minWidth: 90, padding: '12px 14px', borderRadius: 14,
                    border: `1px solid ${on ? T.ink : T.line}`,
                    background: on ? T.ink : 'transparent',
                    color: on ? T.bg : (vOos ? T.inkMute : T.ink),
                    fontWeight: on ? 700 : 500, fontSize: 12,
                    cursor: vOos ? 'not-allowed' : 'pointer', transition: 'all 0.25s',
                    opacity: vOos ? 0.5 : 1, textAlign: 'center',
                  }}>
                    <div>{v.label}</div>
                    {v.price !== effectivePrice && !on && (
                      <div style={{ fontSize: 10, marginTop: 3, opacity: 0.7 }}>{fmt(v.price)}</div>
                    )}
                    {vOos && <div style={{ fontSize: 9, marginTop: 3 }}>אזל</div>}
                  </button>
                );
              })}
            </div>
          </div>
        )}

        <div style={{
          marginTop: 22, padding: 16, borderRadius: 18,
          background: T.bgCard, border: `1px solid ${T.line}`,
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14,
        }}>
          {[
            { l: 'תווי פתיחה', v: 'ברגמוט · פלפל ורוד' },
            { l: 'תווי לב', v: 'ורד · איריס' },
            { l: 'תווי בסיס', v: 'ענבר · ארז · וניל' },
            { l: 'עוצמה', v: 'רכה, נמשכת 6+ שעות' },
          ].map(x => (
            <div key={x.l}>
              <div style={{ fontSize: 9.5, color: T.accent, letterSpacing: 0.5, fontWeight: 600 }}>{x.l}</div>
              <div style={{ fontSize: 12.5, color: T.ink, marginTop: 3 }}>{x.v}</div>
            </div>
          ))}
        </div>

        <div style={{
          marginTop: 14, padding: '14px 16px', borderRadius: 16,
          border: `1px solid ${T.line}`, display: 'flex', gap: 12, alignItems: 'center', color: T.ink,
        }}>
          <Icon name="truck" size={18} color={T.accent} />
          <div style={{ fontSize: 12 }}>
            <div style={{ fontWeight: 700 }}>משלוח אקספרס חינם</div>
            <div style={{ color: T.inkMute, marginTop: 2, fontSize: 11 }}>מגיע ביום ג', 9 במאי</div>
          </div>
        </div>
      </div>

      <div style={{
        position: 'sticky', bottom: 0, insetInlineStart: 0, insetInlineEnd: 0,
        padding: '14px 16px 22px',
        background: `linear-gradient(to top, ${T.bg} 70%, ${T.bg}f0 88%, transparent)`,
        zIndex: 30, marginTop: 24,
      }}>
        <button onClick={handleAdd} disabled={oos} style={{
          width: '100%', padding: '18px 24px',
          borderRadius: 999,
          background: oos ? T.bgCard : added ? T.accent : T.ink,
          color: oos ? T.inkMute : T.bg,
          border: oos ? `1px solid ${T.line}` : 'none',
          fontSize: 13, letterSpacing: 0.5, fontWeight: 700,
          cursor: oos ? 'not-allowed' : 'pointer',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          transition: 'background 0.3s, transform 0.2s',
        }}
        onPointerDown={e => !oos && (e.currentTarget.style.transform = 'scale(0.98)')}
        onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
        onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
          <span>{oos ? 'אזל מהמלאי' : added ? 'נוסף ✓' : 'הוסף לסל'}</span>
          <span>{fmt(effectivePrice)}</span>
        </button>
      </div>
    </div>
  );
}

// ── Cart ──
function CartScreen({ T, displayFont, items, actions, onBack, onCheckout }) {
  const subtotal = items.reduce((s, x) => s + x.product.price * x.qty, 0);
  const [promoCode, setPromoCode] = useState('');
  const [promo, setPromo] = useState(null);          // { code, discount, description }
  const [promoError, setPromoError] = useState('');
  const [promoBusy, setPromoBusy] = useState(false);

  const discount = promo?.discount || 0;
  const subtotalAfterDiscount = Math.max(0, subtotal - discount);
  const shipping = subtotalAfterDiscount > 300 ? 0 : 25;
  const total = subtotalAfterDiscount + shipping;
  const updateQty = (item, d) => actions.setQty(item, item.qty + d);

  const PROMO_ERRORS = {
    invalid_code: 'קוד לא תקין',
    inactive: 'הקוד אינו פעיל',
    expired: 'הקוד פג תוקף',
    exhausted: 'הקוד נוצל מקסימום פעמים',
    min_not_met: 'הזמנה מתחת למינימום',
  };

  async function applyPromo() {
    if (!promoCode.trim()) return;
    setPromoError(''); setPromoBusy(true);
    try {
      const r = await window.API.post('/promo/apply', { code: promoCode.trim(), subtotal });
      setPromo(r);
      setPromoError('');
    } catch (err) {
      setPromo(null);
      setPromoError(PROMO_ERRORS[err.message] || 'אירעה שגיאה');
    } finally { setPromoBusy(false); }
  }
  function clearPromo() { setPromo(null); setPromoCode(''); setPromoError(''); }
  return (
    <div style={{ paddingBottom: 0, position: 'relative', minHeight: '100%' }}>
      <div style={{ padding: '54px 20px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>הסל שלך</div>
        <div style={{ width: 40 }} />
      </div>

      {items.length === 0 ? (
        <div style={{ padding: '60px 24px', textAlign: 'center', color: T.inkDim }}>
          <Icon name="bag" size={42} color={T.inkMute} />
          <div style={{ marginTop: 14, fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>הסל שלך ריק</div>
          <div style={{ marginTop: 8, fontSize: 13 }}>הוסיפו כמה פריטים אהובים כדי להתחיל.</div>
        </div>
      ) : (
        <div style={{ padding: '8px 16px' }}>
          {items.map((it, idx) => (
            <div key={it.serverId || `${it.product.id}-${it.size}-${idx}`} style={{ display: 'flex', gap: 12, padding: '12px 0', borderBottom: `1px solid ${T.line}` }}>
              <div style={{ width: 92, height: 110, borderRadius: 14, overflow: 'hidden', background: T.bgCard, flexShrink: 0 }}>
                <Img src={it.product.img} style={{ width: '100%', height: '100%' }} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
                  <div style={{ minWidth: 0, flex: 1 }}>
                    <div style={{ fontSize: 9.5, color: T.inkMute }}>{it.product.brand}</div>
                    <div style={{ fontFamily: displayFont, fontSize: 15, color: T.ink, marginTop: 3, lineHeight: 1.25, fontWeight: 600 }}>{it.product.name}</div>
                    {it.size && <div style={{ fontSize: 11, color: T.inkDim, marginTop: 4 }}>מידה: {it.size}</div>}
                  </div>
                  <button onClick={() => actions.remove(it)} style={{
                    background: 'none', border: 'none', color: T.inkMute, cursor: 'pointer', padding: 4, marginTop: -4,
                  }}>
                    <Icon name="close" size={16} />
                  </button>
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 14 }}>
                  <div style={{ display: 'inline-flex', alignItems: 'center', border: `1px solid ${T.line}`, borderRadius: 999, padding: 2 }}>
                    <button onClick={() => updateQty(it, -1)} style={{ width: 28, height: 28, borderRadius: 14, background: 'none', border: 'none', color: T.ink, cursor: 'pointer', display: 'grid', placeItems: 'center' }}>
                      <Icon name="minus" size={14} />
                    </button>
                    <div style={{ minWidth: 22, textAlign: 'center', fontSize: 13, color: T.ink, fontWeight: 700 }}>{it.qty}</div>
                    <button onClick={() => updateQty(it, 1)} style={{ width: 28, height: 28, borderRadius: 14, background: 'none', border: 'none', color: T.ink, cursor: 'pointer', display: 'grid', placeItems: 'center' }}>
                      <Icon name="plus" size={14} />
                    </button>
                  </div>
                  <div style={{ fontFamily: displayFont, fontSize: 17, color: T.ink, fontWeight: 700 }}>{fmt(it.product.price * it.qty)}</div>
                </div>
              </div>
            </div>
          ))}

          {FEATURES.coupons && (
            <div style={{ marginTop: 20 }}>
              {promo ? (
                <div style={{
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                  padding: '12px 14px', borderRadius: 14,
                  background: `color-mix(in oklab, ${T.accent}, transparent 85%)`,
                  border: `1px solid color-mix(in oklab, ${T.accent}, transparent 60%)`,
                  color: T.accent,
                }}>
                  <div>
                    <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: 0.5 }}>{promo.code}</div>
                    <div style={{ fontSize: 11, color: T.inkDim, marginTop: 2 }}>
                      {promo.description || (promo.kind === 'percent' ? `${promo.amount}% הנחה` : `${fmt(promo.amount)} הנחה`)}
                    </div>
                  </div>
                  <button onClick={clearPromo} style={{
                    background: 'none', border: 'none', color: T.inkMute, cursor: 'pointer', fontSize: 11,
                  }}>הסר ×</button>
                </div>
              ) : (
                <>
                  <div style={{ display: 'flex', gap: 8 }}>
                    <input placeholder="קוד הנחה" value={promoCode}
                      onChange={e => setPromoCode(e.target.value.toUpperCase())}
                      onKeyDown={e => e.key === 'Enter' && applyPromo()}
                      style={{
                        flex: 1, padding: '13px 16px', borderRadius: 14,
                        background: T.bgCard, border: `1px solid ${promoError ? '#c0606080' : T.line}`,
                        color: T.ink, fontSize: 12, outline: 'none', fontFamily: 'inherit',
                        textAlign: 'right', direction: 'rtl',
                      }} />
                    <button onClick={applyPromo} disabled={promoBusy || !promoCode.trim()} style={{
                      padding: '0 18px', borderRadius: 14,
                      background: 'transparent', border: `1px solid ${T.line}`,
                      color: T.ink, fontSize: 11, fontWeight: 700, cursor: promoBusy ? 'wait' : 'pointer',
                      opacity: !promoCode.trim() ? 0.5 : 1,
                    }}>{promoBusy ? '...' : 'החל'}</button>
                  </div>
                  {promoError && <div style={{ fontSize: 11, color: '#ffb8b8', marginTop: 6 }}>{promoError}</div>}
                </>
              )}
            </div>
          )}

          <div style={{ marginTop: 20, padding: '16px 0', borderTop: `1px solid ${T.line}` }}>
            <Row T={T} l="סכום ביניים" v={fmt(subtotal)} />
            {FEATURES.coupons && discount > 0 && <Row T={T} l={`הנחה (${promo.code})`} v={`-${fmt(discount)}`} />}
            <Row T={T} l="משלוח" v={shipping ? fmt(shipping) : 'חינם'} />
            <Row T={T} l="מע״מ" v="כלול" />
          </div>
        </div>
      )}

      {items.length > 0 && (
        <div style={{
          position: 'sticky', bottom: 0, insetInlineStart: 0, insetInlineEnd: 0,
          padding: '14px 16px 22px',
          background: `linear-gradient(to top, ${T.bg} 70%, ${T.bg}f0 88%, transparent)`, zIndex: 30,
          marginTop: 24,
        }}>
          <button onClick={onCheckout} style={{
            width: '100%', padding: '18px 24px',
            borderRadius: 999, background: T.ink, color: T.bg, border: 'none',
            fontSize: 13, fontWeight: 700, cursor: 'pointer',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <span>לתשלום</span>
            <span>{fmt(total)}</span>
          </button>
        </div>
      )}
    </div>
  );
}

function Row({ T, l, v }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 0', color: T.ink, fontSize: 13 }}>
      <span style={{ color: T.inkDim }}>{l}</span>
      <span>{v}</span>
    </div>
  );
}

// ── Checkout ──
function CheckoutScreen({ T, displayFont, items, user, onBack, onPlace }) {
  const [step, setStep] = useState(0); // 0=address, 1=delivery, 2=payment, 3=review
  const [addr, setAddr] = useState({ name: user?.name || '', email: '', street: '', city: '', zip: '', phone: user?.phone || '' });
  const [savedAddresses, setSavedAddresses] = useState([]);
  const [pickedAddrId, setPickedAddrId] = useState(null);
  const [saveAddress, setSaveAddress] = useState(false); // logged-in: save this new address

  // Load saved addresses + pre-fill from default
  useEffect(() => {
    if (!user) return;
    window.API.get('/addresses').then(r => {
      setSavedAddresses(r.addresses);
      const def = r.addresses.find(a => a.isDefault) || r.addresses[0];
      if (def) {
        setAddr(p => ({ ...p, street: def.street, city: def.city, zip: def.zip || '', phone: def.phone || p.phone }));
        setPickedAddrId(def.id);
      }
    }).catch(() => {});
  }, [user]);

  function pickSaved(a) {
    setPickedAddrId(a.id);
    setAddr(p => ({ ...p, street: a.street, city: a.city, zip: a.zip || '', phone: a.phone || p.phone }));
  }
  function clearPick() {
    setPickedAddrId(null);
    setAddr(p => ({ ...p, street: '', city: '', zip: '' }));
  }

  const [delivery, setDelivery] = useState(() => SHIPPING_METHODS[0]?.id || 'express');
  const [pay, setPay] = useState(() => (PAYMENT_METHODS.find(m => m.id === 'cod') ? 'cod' : PAYMENT_METHODS[0]?.id) || 'cod');
  const [wantAccount, setWantAccount] = useState(false);
  const [password, setPassword] = useState('');
  const [attempted, setAttempted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState('');
  // Email-acknowledgement modal: shown after user clicks "אשר הזמנה" on step 4.
  // The order won't actually submit until the user ticks the checkbox + confirms.
  const [showEmailGate, setShowEmailGate] = useState(false);
  const [emailAck, setEmailAck] = useState(false);

  const isGuest = !user;
  const subtotal = items.reduce((s, x) => s + x.product.price * x.qty, 0);
  const deliveryCost = SHIPPING_METHODS.find(m => m.id === delivery)?.price ?? 0;
  const total = subtotal + deliveryCost;
  const stepLabels = ['כתובת', 'משלוח', 'תשלום', 'אישור'];

  // Per-step validation. Errors are keyed by field name.
  const errors = (() => {
    const e = {};
    if (step === 0) {
      if (!addr.name?.trim())             e.name   = 'נא להזין שם מלא';
      if (!addr.street?.trim())           e.street = 'נא להזין כתובת';
      if (!addr.city?.trim())             e.city   = 'נא להזין עיר';
      if (!addr.phone || addr.phone.replace(/\D/g,'').length < 8) e.phone  = 'מספר טלפון לא תקין';
      if (isGuest) {
        if (!addr.email || !/^\S+@\S+\.\S+$/.test(addr.email)) e.email = 'נא להזין אימייל תקין';
        if (wantAccount && (!password || password.length < 6))  e.password = 'סיסמה לפחות 6 תווים';
      }
    }
    if (step === 1 && !SHIPPING_METHODS.find(m => m.id === delivery)) e.delivery = 'יש לבחור אופן משלוח';
    if (step === 2 && !PAYMENT_METHODS.find(m => m.id === pay))       e.pay      = 'יש לבחור אופן תשלום';
    return e;
  })();
  const stepValid = Object.keys(errors).length === 0;

  const next = () => {
    if (!stepValid) { setAttempted(true); return; }
    setAttempted(false);
    setStep(s => Math.min(3, s + 1));
  };
  const prev = () => step === 0 ? onBack() : setStep(s => s - 1);

  async function place() {
    setSubmitting(true); setSubmitError('');
    try {
      await onPlace({
        addr, delivery, pay, total, subtotal, deliveryCost,
        wantAccount: isGuest && wantAccount,
        password: isGuest && wantAccount ? password : null,
        saveAddress: !isGuest && saveAddress && !pickedAddrId,
      });
    } catch (err) {
      setSubmitError(err?.message || 'שגיאה');
    } finally { setSubmitting(false); }
  }

  return (
    <div style={{ paddingBottom: 0, position: 'relative', minHeight: '100%' }}>
      {/* Header with progress */}
      <div style={{ padding: '54px 20px 14px' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 22 }}>
          <IconBtn T={T} icon="right" onClick={prev} />
          <div style={{ fontFamily: displayFont, fontSize: 20, color: T.ink, fontWeight: 700 }}>תשלום</div>
          <div style={{ width: 40, fontSize: 11, color: T.inkMute, textAlign: 'left' }}>{step + 1}/4</div>
        </div>
        {/* Stepper */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          {stepLabels.map((label, i) => (
            <React.Fragment key={i}>
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, flex: '0 0 auto' }}>
                <div style={{
                  width: 26, height: 26, borderRadius: 13,
                  background: i <= step ? T.ink : 'transparent',
                  border: `1px solid ${i <= step ? T.ink : T.line}`,
                  color: i <= step ? T.bg : T.inkMute,
                  display: 'grid', placeItems: 'center',
                  fontSize: 11, fontWeight: 700,
                  transition: 'all 0.3s',
                }}>
                  {i < step ? <Icon name="check" size={13} strokeWidth={2.5} /> : i + 1}
                </div>
                <div style={{ fontSize: 9.5, color: i === step ? T.ink : T.inkMute, fontWeight: i === step ? 700 : 500, whiteSpace: 'nowrap' }}>{label}</div>
              </div>
              {i < 3 && (
                <div style={{ flex: 1, height: 1, background: i < step ? T.ink : T.line, marginBottom: 18, transition: 'background 0.3s' }} />
              )}
            </React.Fragment>
          ))}
        </div>
      </div>

      <div style={{ padding: '12px 16px 24px' }}>
        {step === 0 && (
          <CheckoutAddress T={T} displayFont={displayFont}
            addr={addr} setAddr={setAddr}
            isGuest={isGuest}
            wantAccount={wantAccount} setWantAccount={setWantAccount}
            password={password} setPassword={setPassword}
            errors={attempted ? errors : {}}
            savedAddresses={savedAddresses} pickedAddrId={pickedAddrId}
            onPickSaved={pickSaved} onClearPick={clearPick}
            saveAddress={saveAddress} setSaveAddress={setSaveAddress} />
        )}
        {step === 1 && <CheckoutDelivery T={T} displayFont={displayFont} value={delivery} onChange={setDelivery} />}
        {step === 2 && <CheckoutPayment T={T} displayFont={displayFont} pay={pay} setPay={setPay} />}
        {step === 3 && <CheckoutReview T={T} displayFont={displayFont} items={items} addr={addr} delivery={delivery} pay={pay} subtotal={subtotal} deliveryCost={deliveryCost} total={total} />}
        {submitError && <div style={{ marginTop: 14, padding: 12, borderRadius: 12, background: 'rgba(220,80,80,0.12)', border: '1px solid rgba(220,80,80,0.35)', color: '#ffb8b8', fontSize: 13 }}>{submitError}</div>}
      </div>

      {/* Sticky footer */}
      <div style={{
        position: 'sticky', bottom: 0, insetInlineStart: 0, insetInlineEnd: 0,
        padding: '12px 16px 22px',
        background: `linear-gradient(to top, ${T.bg} 70%, ${T.bg}f0 88%, transparent)`,
        zIndex: 30, marginTop: 24,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 6px 10px', fontSize: 12, color: T.inkDim }}>
          <span>סך הכל</span>
          <span style={{ color: T.ink, fontWeight: 700, fontFamily: displayFont, fontSize: 16 }}>{fmt(total)}</span>
        </div>
        <button onClick={step === 3 ? () => { setEmailAck(false); setShowEmailGate(true); } : next} disabled={submitting} style={{
          width: '100%', padding: '18px 24px', borderRadius: 999,
          background: T.ink, color: T.bg, border: 'none',
          fontSize: 13, fontWeight: 700, cursor: submitting ? 'wait' : 'pointer',
          display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 8,
          transition: 'transform 0.2s',
          opacity: submitting ? 0.7 : 1,
        }}
        onPointerDown={e => !submitting && (e.currentTarget.style.transform = 'scale(0.98)')}
        onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
        onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
          {submitting ? '...' : step === 3 ? (<><Icon name="check" size={14} strokeWidth={2.5} /> אשר הזמנה</>) : 'המשך'}
        </button>
      </div>

      {showEmailGate && (
        <EmailConsentModal T={T} displayFont={displayFont}
          email={addr.email || (user?.email || '')}
          ack={emailAck} setAck={setEmailAck}
          submitting={submitting}
          onCancel={() => setShowEmailGate(false)}
          onConfirm={async () => {
            setShowEmailGate(false);
            await place();
          }} />
      )}
    </div>
  );
}

// ── Pre-submit consent modal: tells the user a confirmation email is on the way and
// reminds them to check the spam folder. Order doesn't submit until the checkbox is ticked.
function EmailConsentModal({ T, displayFont, email, ack, setAck, submitting, onCancel, onConfirm }) {
  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 400,
      background: 'rgba(10,19,15,0.65)',
      backdropFilter: 'blur(6px)',
      WebkitBackdropFilter: 'blur(6px)',
      display: 'grid', placeItems: 'center', padding: 16,
      animation: 'fadein 0.2s ease',
    }}
    onClick={(e) => { if (e.target === e.currentTarget) onCancel(); }}>
      <div style={{
        background: T.bg, color: T.ink,
        border: `1px solid ${T.line}`,
        borderRadius: 22, padding: '28px 24px 22px',
        width: '100%', maxWidth: 420,
        direction: 'rtl', textAlign: 'right',
        boxShadow: '0 30px 80px rgba(0,0,0,0.6)',
        animation: 'slideIn 0.25s cubic-bezier(0.2,0.8,0.2,1)',
      }} onClick={(e) => e.stopPropagation()}>
        {/* Envelope icon */}
        <div style={{
          width: 56, height: 56, borderRadius: 28,
          background: `color-mix(in oklab, ${T.accent}, transparent 75%)`,
          color: T.accent,
          display: 'grid', placeItems: 'center', marginBottom: 16,
        }}>
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
            <rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/>
          </svg>
        </div>

        <div style={{ fontFamily: displayFont, fontSize: 22, fontWeight: 700, lineHeight: 1.2 }}>
          רגע לפני סיום
        </div>
        <div style={{ marginTop: 10, fontSize: 13.5, color: T.inkDim, lineHeight: 1.7 }}>
          מיד לאחר אישור ההזמנה נשלח אישור למייל
          {email && (<> <span style={{ color: T.ink, fontWeight: 600, direction: 'ltr', display: 'inline-block' }}>{email}</span></>)}
          .
          <br/>
          <span style={{ color: T.accent, fontWeight: 600 }}>חשוב:</span> ייתכן שהמייל ייכנס לתיקיית <b>הספאם / קידומי מכירות</b> — מומלץ להציץ גם שם.
        </div>

        {/* Save the order number — used for tracking */}
        <div style={{
          marginTop: 16, padding: '12px 14px', borderRadius: 12,
          background: `color-mix(in oklab, ${T.accent}, transparent 90%)`,
          border: `1px dashed color-mix(in oklab, ${T.accent}, transparent 55%)`,
          fontSize: 12.5, color: T.ink, lineHeight: 1.65,
        }}>
          <b style={{ color: T.accent }}>שמרי את מספר ההזמנה</b> שיופיע מיד אחרי האישור (בפורמט <span style={{ direction: 'ltr', display: 'inline-block', fontFamily: 'monospace' }}>LP-XXXX-XXXX</span>).
          ניתן לעקוב אחר ההזמנה בכל זמן דרך הכפתור <b>מעקב</b> בתפריט התחתון.
        </div>

        <label style={{
          display: 'flex', alignItems: 'flex-start', gap: 12,
          marginTop: 18, padding: '14px 14px',
          background: T.bgCard, border: `1px solid ${ack ? T.accent : T.line}`,
          borderRadius: 14, cursor: 'pointer',
          transition: 'border-color 0.2s',
        }}>
          <input type="checkbox" checked={ack} onChange={e => setAck(e.target.checked)}
            style={{ width: 20, height: 20, accentColor: T.accent, cursor: 'pointer', marginTop: 1, flexShrink: 0 }} />
          <span style={{ fontSize: 13, color: T.ink, lineHeight: 1.5 }}>
            קראתי והבנתי. אבדוק גם בתיקיית הספאם, ואשמור את מספר ההזמנה למעקב.
          </span>
        </label>

        <div style={{ display: 'flex', gap: 10, marginTop: 20 }}>
          <button onClick={onCancel} disabled={submitting} style={{
            flex: '0 0 auto', padding: '13px 22px', borderRadius: 999,
            background: 'transparent', color: T.ink, border: `1px solid ${T.line}`,
            fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
            cursor: submitting ? 'not-allowed' : 'pointer',
          }}>חזרה</button>
          <button onClick={onConfirm} disabled={!ack || submitting} style={{
            flex: 1, padding: '13px 22px', borderRadius: 999,
            background: ack ? T.accent : T.bgCard,
            color: ack ? T.bg : T.inkMute,
            border: 'none', fontSize: 13, fontWeight: 700,
            fontFamily: 'inherit',
            cursor: !ack || submitting ? 'not-allowed' : 'pointer',
            opacity: !ack || submitting ? 0.6 : 1,
            transition: 'background 0.2s, transform 0.15s',
          }}>{submitting ? '...' : 'אשרי וסיימי הזמנה'}</button>
        </div>
      </div>
    </div>
  );
}

function CheckoutField({ T, label, value, onChange, placeholder, type = 'text', required, error }) {
  const isRtl = type !== 'email' && type !== 'password' && type !== 'tel';
  return (
    <label style={{ display: 'block', marginBottom: 12 }}>
      <div style={{ fontSize: 10.5, color: T.inkMute, fontWeight: 600, marginBottom: 6, letterSpacing: 0.3 }}>
        {label}{required && <span style={{ color: T.accent, marginInlineStart: 4 }}>*</span>}
      </div>
      <input type={type} value={value || ''} onChange={e => onChange(e.target.value)} placeholder={placeholder}
        required={required}
        style={{
          width: '100%', padding: '14px 16px', borderRadius: 14,
          background: T.bgCard,
          border: `1px solid ${error ? '#c0606080' : T.line}`,
          color: T.ink, fontSize: 13, outline: 'none', fontFamily: 'inherit',
          textAlign: isRtl ? 'right' : 'left', direction: isRtl ? 'rtl' : 'ltr',
          boxSizing: 'border-box',
        }} />
      {error && (
        <div style={{ fontSize: 11, color: '#ffb8b8', marginTop: 5, paddingInlineStart: 4 }}>{error}</div>
      )}
    </label>
  );
}

function CheckoutAddress({
  T, displayFont, addr, setAddr,
  isGuest, wantAccount, setWantAccount, password, setPassword, errors = {},
  savedAddresses = [], pickedAddrId, onPickSaved, onClearPick,
  saveAddress, setSaveAddress,
}) {
  const set = (k) => (v) => setAddr({ ...addr, [k]: v });
  return (
    <div>
      <div style={{ fontFamily: displayFont, fontSize: 18, color: T.ink, fontWeight: 700, marginBottom: 14 }}>פרטי משלוח</div>

      {savedAddresses.length > 0 && (
        <div style={{ marginBottom: 18 }}>
          <div style={{ fontSize: 11, color: T.inkMute, fontWeight: 600, marginBottom: 8, letterSpacing: 0.5 }}>כתובות שמורות</div>
          <div style={{ display: 'flex', gap: 8, overflowX: 'auto', paddingBottom: 4 }} className="hide-scroll">
            {savedAddresses.map(a => {
              const on = pickedAddrId === a.id;
              return (
                <button key={a.id} onClick={() => onPickSaved(a)} style={{
                  flex: '0 0 auto', minWidth: 200, padding: '12px 14px', borderRadius: 14,
                  background: on ? T.bgCard : 'transparent',
                  border: `1.5px solid ${on ? T.accent : T.line}`,
                  color: T.ink, cursor: 'pointer', fontFamily: 'inherit',
                  textAlign: 'right', direction: 'rtl',
                }}>
                  <div style={{ fontSize: 12, fontWeight: 700, color: on ? T.accent : T.ink }}>
                    {a.label || 'כתובת'}{a.isDefault && ' · ברירת מחדל'}
                  </div>
                  <div style={{ fontSize: 11, color: T.inkDim, marginTop: 4, lineHeight: 1.4 }}>
                    {a.street}, {a.city}
                  </div>
                </button>
              );
            })}
            <button onClick={onClearPick} style={{
              flex: '0 0 auto', minWidth: 110, padding: '12px 14px', borderRadius: 14,
              background: 'transparent', border: `1.5px dashed ${T.line}`,
              color: T.inkDim, cursor: 'pointer', fontFamily: 'inherit',
              fontSize: 11.5, fontWeight: 600,
            }}>+ חדשה</button>
          </div>
        </div>
      )}

      <CheckoutField T={T} label="שם מלא" value={addr.name} onChange={set('name')} placeholder="שם פרטי ומשפחה" required error={errors.name} />
      {isGuest && (
        <CheckoutField T={T} label="אימייל" value={addr.email} onChange={set('email')} placeholder="email@example.com" type="email" required error={errors.email} />
      )}
      <CheckoutField T={T} label="רחוב ומספר" value={addr.street} onChange={set('street')} placeholder="לדוגמה: רוטשילד 42" required error={errors.street} />
      <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 10 }}>
        <CheckoutField T={T} label="עיר" value={addr.city} onChange={set('city')} required error={errors.city} />
        <CheckoutField T={T} label="מיקוד" value={addr.zip} onChange={set('zip')} placeholder="לא חובה" />
      </div>
      <CheckoutField T={T} label="טלפון" value={addr.phone} onChange={set('phone')} placeholder="050-0000000" type="tel" required error={errors.phone} />

      {isGuest && FEATURES.customerAccounts && (
        <div style={{
          marginTop: 18, padding: 14, borderRadius: 14,
          background: T.bgCard, border: `1px solid ${T.line}`,
        }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer' }}>
            <input type="checkbox" checked={wantAccount} onChange={e => setWantAccount(e.target.checked)}
              style={{ width: 18, height: 18, accentColor: T.accent, cursor: 'pointer' }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13.5, color: T.ink, fontWeight: 600 }}>שמרי את הפרטים שלי</div>
              <div style={{ fontSize: 11.5, color: T.inkMute, marginTop: 2, lineHeight: 1.5 }}>
                ייווצר חשבון עם המייל שלך כדי שתוכלי לעקוב אחרי ההזמנה ולקנות מהר יותר בעתיד.
              </div>
            </div>
          </label>
          {wantAccount && (
            <div style={{ marginTop: 12 }}>
              <CheckoutField T={T} label="סיסמה (לפחות 6 תווים)" value={password} onChange={setPassword} type="password" required error={errors.password} />
            </div>
          )}
        </div>
      )}

      {!isGuest && !pickedAddrId && (
        <label style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 4px', cursor: 'pointer' }}>
          <input type="checkbox" checked={saveAddress} onChange={e => setSaveAddress(e.target.checked)}
            style={{ width: 18, height: 18, accentColor: T.accent }} />
          <span style={{ fontSize: 13, color: T.ink }}>שמרי את הכתובת לפעם הבאה</span>
        </label>
      )}
    </div>
  );
}

function CheckoutDelivery({ T, displayFont, value, onChange }) {
  // Admin-editable shipping methods, fetched at boot from /api/shipping
  const opts = SHIPPING_METHODS;
  // If the previously selected option no longer exists (admin removed it), pick the first available
  useEffect(() => {
    if (opts.length && !opts.find(o => o.id === value)) onChange(opts[0].id);
  }, [opts, value]);
  return (
    <div>
      <div style={{ fontFamily: displayFont, fontSize: 18, color: T.ink, fontWeight: 700, marginBottom: 14 }}>בחרו אופן משלוח</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {opts.map(o => {
          const active = value === o.id;
          return (
            <button key={o.id} onClick={() => onChange(o.id)} style={{
              padding: 16, borderRadius: 18, textAlign: 'right',
              background: active ? T.bgCard : 'transparent',
              border: `1.5px solid ${active ? T.accent : T.line}`,
              cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 12,
              fontFamily: 'inherit', transition: 'all 0.2s',
            }}>
              <div style={{
                width: 44, height: 44, borderRadius: 14, flexShrink: 0,
                background: active ? T.accent : T.bgCard,
                color: active ? T.bg : T.ink,
                display: 'grid', placeItems: 'center',
              }}>
                <Icon name={o.icon} size={20} />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 14, color: T.ink, fontWeight: 700 }}>{o.label}</span>
                  {o.badge && <span style={{
                    fontSize: 9, padding: '3px 8px', borderRadius: 999,
                    background: T.accent, color: T.bg, fontWeight: 700,
                  }}>{o.badge}</span>}
                </div>
                <div style={{ fontSize: 11.5, color: T.inkDim, marginTop: 3 }}>{o.sub}</div>
              </div>
              <div style={{ fontSize: 13, color: T.ink, fontWeight: 700, fontFamily: displayFont }}>
                {o.price === 0 ? '—' : fmt(o.price)}
              </div>
              <div style={{
                width: 20, height: 20, borderRadius: 10, flexShrink: 0,
                border: `1.5px solid ${active ? T.accent : T.line}`,
                background: active ? T.accent : 'transparent',
                display: 'grid', placeItems: 'center',
              }}>
                {active && <div style={{ width: 8, height: 8, borderRadius: 4, background: T.bg }} />}
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function CheckoutPayment({ T, displayFont, pay, setPay }) {
  const methods = PAYMENT_METHODS;

  // If admin disabled the previously-selected method, snap to the first one
  useEffect(() => {
    if (methods.length && !methods.find(m => m.id === pay)) setPay(methods[0].id);
  }, [methods, pay]);

  const active = methods.find(m => m.id === pay);
  if (!methods.length) return (
    <div style={{ padding: 24, color: T.inkDim, textAlign: 'center' }}>
      אין כרגע אפשרויות תשלום זמינות. נסי שוב מאוחר יותר.
    </div>
  );

  // Auto-grid: max 3 per row, more rows as methods grow
  const cols = Math.min(methods.length, 3);

  return (
    <div>
      <div style={{ fontFamily: displayFont, fontSize: 18, color: T.ink, fontWeight: 700, marginBottom: 14 }}>אופן תשלום</div>
      <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 8, marginBottom: 18 }}>
        {methods.map(m => {
          const on = pay === m.id;
          return (
            <button key={m.id} onClick={() => setPay(m.id)} style={{
              padding: '14px 8px', borderRadius: 14, fontFamily: 'inherit',
              background: on ? T.bgCard : 'transparent',
              border: `1.5px solid ${on ? T.accent : T.line}`,
              color: T.ink, cursor: 'pointer',
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
              transition: 'all 0.2s', minHeight: 78,
            }}>
              <PayIcon name={m.icon} color={T.ink} />
              <span style={{ fontSize: 10.5, fontWeight: 600, textAlign: 'center', lineHeight: 1.2 }}>{m.label}</span>
            </button>
          );
        })}
      </div>

      <div style={{
        padding: 24, borderRadius: 18,
        background: T.bgCard, border: `1px solid ${T.line}`,
        textAlign: 'center', color: T.ink,
      }}>
        <PayIcon name={active.icon} color={T.ink} size={40} />
        <div style={{ marginTop: 12, fontSize: 14, fontWeight: 700 }}>{active.label}</div>
        {active.description && (
          <div style={{ marginTop: 8, fontSize: 12, color: T.inkDim, lineHeight: 1.6 }}>{active.description}</div>
        )}
        {pay === 'cod' && (
          <div style={{ marginTop: 14, padding: '8px 14px', borderRadius: 999,
            background: `color-mix(in oklab, ${T.accent}, transparent 80%)`,
            color: T.accent, display: 'inline-block', fontSize: 11, fontWeight: 700,
          }}>ללא עמלה נוספת</div>
        )}
      </div>
    </div>
  );
}

function PayIcon({ name, color = '#fff', size = 22 }) {
  if (name === 'apple') return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
      <path d="M17.5 12.7c0-2.3 1.9-3.4 2-3.4-1.1-1.6-2.8-1.8-3.4-1.9-1.4-.1-2.8.9-3.6.9-.7 0-1.9-.8-3.1-.8-1.6 0-3.1.9-3.9 2.4-1.7 2.9-.4 7.2 1.2 9.5.8 1.1 1.7 2.4 2.9 2.4 1.2 0 1.6-.8 3-.8s1.8.8 3 .8c1.2 0 2-1.1 2.8-2.3.9-1.3 1.2-2.6 1.3-2.6-.1-.1-2.5-1-2.5-3.8zM15.5 5.7c.6-.8 1-1.9.9-3-.9 0-2 .6-2.7 1.4-.6.7-1.1 1.8-1 2.9 1 .1 2.1-.5 2.8-1.3z"/>
    </svg>
  );
  if (name === 'paypal') return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
      <path d="M7.4 21l.5-3h-3l2-13c.1-.5.5-.8 1-.8h6.5c2.7 0 4.5 1.5 4.2 4-.3 2.8-2.4 4.4-5.1 4.4h-2.5c-.5 0-.9.3-1 .8L9.5 18l-.4 3H7.4zm3.4-15.4l-.7 4.5h2.6c1.6 0 2.7-.9 2.9-2.4.2-1.5-.7-2.1-2-2.1h-2.8z"/>
    </svg>
  );
  if (name === 'cash') return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="6" width="20" height="12" rx="2"/>
      <circle cx="12" cy="12" r="2.4"/>
      <path d="M5 9.5v0M19 14.5v0"/>
    </svg>
  );
  if (name === 'bit') return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
      <path d="M5 4h6.5a4.2 4.2 0 0 1 3.3 6.7A4.5 4.5 0 0 1 12 19.5H5V4zm3.2 3v3.7h3.2c1 0 1.7-.8 1.7-1.8S12.4 7 11.5 7H8.2zm0 6.5v3.5h3.5c1.1 0 2-.8 2-1.8s-.9-1.7-2-1.7H8.2z"/>
    </svg>
  );
  // card
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="6" width="20" height="14" rx="2"/>
      <path d="M2 11h20"/>
    </svg>
  );
}

function CheckoutReview({ T, displayFont, items, addr, delivery, pay, subtotal, deliveryCost, total }) {
  const ship = SHIPPING_METHODS.find(m => m.id === delivery);
  const deliveryLabel = ship ? `${ship.label}${ship.sub ? ' · ' + ship.sub : ''}` : delivery;
  const payLabel = {
    card: 'כרטיס אשראי (דרך Grow)',
    cod: 'במזומן בעת קבלה',
    apple: 'Apple Pay',
    paypal: 'PayPal',
    bit: 'Bit',
  }[pay] || pay;
  return (
    <div>
      <div style={{ fontFamily: displayFont, fontSize: 18, color: T.ink, fontWeight: 700, marginBottom: 14 }}>בדקו את ההזמנה</div>
      {/* Items */}
      <div style={{ background: T.bgCard, border: `1px solid ${T.line}`, borderRadius: 18, padding: 14, marginBottom: 14 }}>
        <div style={{ fontSize: 10.5, color: T.inkMute, fontWeight: 700, marginBottom: 10, letterSpacing: 0.5 }}>{items.length} פריטים</div>
        {items.map((it, i) => (
          <div key={i} style={{
            display: 'flex', gap: 10, alignItems: 'center',
            paddingTop: i === 0 ? 0 : 10, paddingBottom: 10,
            borderBottom: i < items.length - 1 ? `1px solid ${T.line}` : 'none',
          }}>
            <div style={{ width: 50, height: 60, borderRadius: 10, overflow: 'hidden', background: T.bg, flexShrink: 0 }}>
              <Img src={it.product.img} style={{ width: '100%', height: '100%' }} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 9.5, color: T.inkMute }}>{it.product.brand}</div>
              <div style={{ fontSize: 12.5, color: T.ink, fontWeight: 600, marginTop: 2 }}>{it.product.name}</div>
              <div style={{ fontSize: 10.5, color: T.inkDim, marginTop: 3 }}>מידה: {it.size} · כמות: {it.qty}</div>
            </div>
            <div style={{ fontSize: 13, color: T.ink, fontWeight: 700, fontFamily: displayFont }}>{fmt(it.product.price * it.qty)}</div>
          </div>
        ))}
      </div>
      {/* Summary cards */}
      <ReviewLine T={T} icon="home" label="כתובת" value={`${addr.street}, ${addr.city}`} />
      <ReviewLine T={T} icon="truck" label="משלוח" value={deliveryLabel} />
      <ReviewLine T={T} icon="card" label="תשלום" value={payLabel} />
      {/* Totals */}
      <div style={{ marginTop: 16, padding: '14px 16px', background: T.bgCard, border: `1px solid ${T.line}`, borderRadius: 16 }}>
        <Row T={T} l="סכום ביניים" v={fmt(subtotal)} />
        <Row T={T} l="משלוח" v={deliveryCost ? fmt(deliveryCost) : 'חינם'} />
        <Row T={T} l="מע״מ" v="כלול" />
        <div style={{ height: 1, background: T.line, margin: '10px 0' }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: 13, color: T.ink, fontWeight: 700 }}>סך הכל</span>
          <span style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>{fmt(total)}</span>
        </div>
      </div>
    </div>
  );
}

function ReviewLine({ T, icon, label, value }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 12,
      padding: '12px 14px', borderRadius: 14, marginBottom: 8,
      background: T.bgCard, border: `1px solid ${T.line}`,
    }}>
      <div style={{
        width: 34, height: 34, borderRadius: 11, flexShrink: 0,
        background: T.bg, display: 'grid', placeItems: 'center', color: T.accent,
      }}>
        {icon === 'card' ? <PayIcon name="card" color={T.accent} size={16} /> : <Icon name={icon} size={16} />}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 10, color: T.inkMute, fontWeight: 600 }}>{label}</div>
        <div style={{ fontSize: 12.5, color: T.ink, fontWeight: 600, marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{value}</div>
      </div>
    </div>
  );
}

// ── Order success ──
function OrderSuccessScreen({ T, displayFont, onDone }) {
  return (
    <div style={{ minHeight: '100%', display: 'flex', flexDirection: 'column', padding: '54px 24px 30px', textAlign: 'center', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{
        width: 96, height: 96, borderRadius: 48,
        background: `radial-gradient(circle, ${T.accent}, ${T.accent}cc)`,
        display: 'grid', placeItems: 'center', color: T.bg,
        boxShadow: `0 20px 60px -10px ${T.glow}`,
        marginBottom: 28,
      }}>
        <Icon name="check" size={42} strokeWidth={2.4} />
      </div>
      <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, fontWeight: 700, lineHeight: 1.1 }}>תודה על הקנייה!</div>
      <div style={{ marginTop: 14, fontSize: 13.5, color: T.inkDim, lineHeight: 1.55, maxWidth: 300 }}>
        ההזמנה שלך התקבלה ואנחנו כבר מתחילים להכין את החבילה.
      </div>

      <div style={{
        marginTop: 22, padding: '14px 22px', borderRadius: 14,
        background: T.bgCard, border: `1px solid ${T.line}`, color: T.ink,
      }}>
        <div style={{ fontSize: 10.5, color: T.inkMute, fontWeight: 600 }}>מספר הזמנה</div>
        <div style={{ fontFamily: 'monospace', fontSize: 16, marginTop: 4, letterSpacing: 1 }}>#AA-{Math.floor(Math.random() * 90000 + 10000)}</div>
      </div>
      <button onClick={onDone} style={{
        marginTop: 36, padding: '16px 40px', borderRadius: 999,
        background: T.ink, color: T.bg, border: 'none',
        fontSize: 13, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit',
      }}>חזרה לחנות</button>
    </div>
  );
}

// ── Search ──
function SearchOverlay({ T, displayFont, onClose, onOpenProduct, onOpenCategory }) {
  const [q, setQ] = useState('');
  const inputRef = useRef(null);
  useEffect(() => { setTimeout(() => inputRef.current?.focus(), 100); }, []);
  const results = q ? PRODUCTS.filter(p =>
    p.name.toLowerCase().includes(q.toLowerCase()) ||
    p.brand.toLowerCase().includes(q.toLowerCase())
  ) : [];
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 100, background: T.bg, animation: 'fadein 0.3s ease' }}>
      <div style={{ padding: '54px 16px 12px', display: 'flex', gap: 10, alignItems: 'center' }}>
        <div style={{
          flex: 1, background: T.bgCard, borderRadius: 14,
          border: `1px solid ${T.line}`,
          display: 'flex', alignItems: 'center', padding: '0 14px',
        }}>
          <Icon name="search" size={16} color={T.inkDim} />
          <input ref={inputRef} value={q} onChange={e => setQ(e.target.value)}
            placeholder="חיפוש תיקים, בשמים, מותגים…" style={{
              flex: 1, background: 'none', border: 'none', outline: 'none',
              color: T.ink, padding: '14px 12px', fontSize: 13,
              fontFamily: 'inherit', textAlign: 'right', direction: 'rtl',
            }} />
        </div>
        <button onClick={onClose} style={{
          background: 'none', border: 'none', color: T.ink, cursor: 'pointer',
          fontSize: 13, padding: '0 4px', fontFamily: 'inherit',
        }}>ביטול</button>
      </div>

      {!q && (
        <div style={{ padding: '12px 20px' }}>
          <div style={{ fontSize: 10, color: T.inkMute, letterSpacing: 0.5, marginBottom: 12, fontWeight: 600 }}>פופולרי</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {['Amber Veil', 'קרוסבודי', 'צעיף משי', 'Rose de Mai', 'פנינה', 'תיק דלי', 'Atelier Noir'].map(t => (
              <div key={t} style={{
                padding: '8px 14px', borderRadius: 999,
                background: T.bgCard, border: `1px solid ${T.line}`,
                color: T.ink, fontSize: 12,
              }}>{t}</div>
            ))}
          </div>

          <div style={{ fontSize: 10, color: T.inkMute, letterSpacing: 0.5, margin: '24px 0 12px', fontWeight: 600 }}>עיון</div>
          {CATEGORIES.map(c => (
            <button key={c.id} onClick={() => onOpenCategory(c.id)} style={{
              width: '100%', textAlign: 'right',
              display: 'flex', alignItems: 'center', gap: 14,
              padding: '12px 0',
              background: 'none', border: 'none', borderBottom: `1px solid ${T.line}`, cursor: 'pointer',
            }}>
              <div style={{ width: 48, height: 48, borderRadius: 12, overflow: 'hidden' }}>
                <Img src={c.img} style={{ width: '100%', height: '100%' }} />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: displayFont, fontSize: 16, color: T.ink, fontWeight: 600 }}>{c.label}</div>
                <div style={{ fontSize: 11, color: T.inkMute, marginTop: 2 }}>{c.sub}</div>
              </div>
              <Icon name="left" size={14} color={T.inkMute} />
            </button>
          ))}
        </div>
      )}

      {q && (
        <div style={{ padding: '8px 16px' }}>
          {results.length === 0 ? (
            <div style={{ padding: 40, textAlign: 'center', color: T.inkDim, fontSize: 13 }}>
              לא נמצאו תוצאות עבור "{q}"
            </div>
          ) : (
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, paddingTop: 8 }}>
              {results.map(p => <ProductCard key={p.id} T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} />)}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── Wishlist ──
function WishlistScreen({ T, displayFont, items, onOpenProduct, onRemove }) {
  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 12px', display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5, fontWeight: 600 }}>שמורים</div>
          <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, marginTop: 2, fontWeight: 700 }}>מועדפים</div>
        </div>
        <div style={{ fontSize: 12, color: T.inkDim }}>{items.length} פריטים</div>
      </div>
      {items.length === 0 ? (
        <div style={{ padding: '60px 24px', textAlign: 'center', color: T.inkDim }}>
          <Icon name="heart" size={42} color={T.inkMute} />
          <div style={{ marginTop: 14, fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>אין כאן עדיין כלום</div>
          <div style={{ marginTop: 8, fontSize: 13, lineHeight: 1.6 }}>הקישי על הלב בכל מוצר<br/>כדי לשמור אותו לכאן.</div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, padding: '12px 16px' }}>
          {items.map(p => (
            <div key={p.id} style={{ position: 'relative' }}>
              <ProductCard T={T} p={p} onOpen={() => onOpenProduct(p)} displayFont={displayFont} />
              <button onClick={() => onRemove(p)} style={{
                position: 'absolute', top: 8, insetInlineEnd: 8,
                width: 32, height: 32, borderRadius: 16,
                background: `color-mix(in oklab, ${T.bgCard}, transparent 20%)`,
                backdropFilter: 'blur(10px)',
                border: `1px solid ${T.line}`,
                color: T.accent, cursor: 'pointer',
                display: 'grid', placeItems: 'center',
              }} aria-label="הסר מהמועדפים">
                <Icon name="heart" size={16} strokeWidth={2} />
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Account ──
// ── Legal pages (privacy / terms / returns) ──
// Copy is a placeholder template. Have a lawyer review before going live.
// Replace the [...] tokens with the actual entity name + contact info from settings,
// or hard-code once you've finalized the wording.
function LegalPageScreen({ T, displayFont, page, onBack }) {
  const PAGES = {
    privacy: {
      title: 'מדיניות פרטיות',
      eyebrow: 'PRIVACY',
      body: [
        ['איזה מידע אנחנו אוספים',
         'בעת ביצוע הזמנה אנחנו אוספים: שם מלא, אימייל, כתובת למשלוח, מספר טלפון, ופירוט פריטי ההזמנה. בעת תשלום באשראי הנתונים עוברים ישירות לסולק (CardCom) — אנחנו לא רואים את פרטי הכרטיס.'],
        ['במה משתמשים במידע',
         'לעיבוד הזמנות, לאספקה, ליצירת קשר במידת הצורך, ולשליחת אישורי הזמנה ועדכוני סטטוס לאימייל שמסרת.'],
        ['שמירת המידע',
         'המידע נשמר על שרת מאובטח. הזמנות נשמרות ל-7 שנים לצרכי דיווח מס. ניתן לבקש מחיקת פרטים אישיים שלא משויכים להזמנות פעילות.'],
        ['העברה לצדדים שלישיים',
         'אנחנו לא מוכרים, משכירים או חולקים את המידע שלך עם צד שלישי, למעט: ספק הסליקה (CardCom), חברת המשלוחים, ושירות הדואר האלקטרוני (Resend). כולם פועלים לפי הסכמי שמירת פרטיות.'],
        ['הזכויות שלך',
         'יש לך זכות לדעת איזה מידע נשמר עליך, לתקן מידע שגוי, ולבקש מחיקה. פנייה בנושא: privacy@lapharmacia.co.il'],
      ],
      reviewed: false,
    },
    terms: {
      title: 'תקנון האתר',
      eyebrow: 'TERMS',
      body: [
        ['הרכישה',
         'אתר La Pharmacia מציע פריטי לייפסטייל ויופי, כולל תיקים, בשמים ואקססוריז. ההזמנה נכנסת לתוקף עם אישור התשלום ושליחת אישור הזמנה למייל.'],
        ['מחירים',
         'כל המחירים באתר כוללים מע"מ ובשקלים חדשים. אנחנו שומרים את הזכות לעדכן מחירים — המחיר התקף הוא זה שמופיע באישור ההזמנה.'],
        ['משלוחים',
         'משלוח אקספרס: מחר עד 12:00. משלוח רגיל: 2-4 ימי עסקים. איסוף עצמי: רוטשילד 42, תל אביב.'],
        ['ביטולים והחזרות',
         'ראי "החזרות והחזרים".'],
        ['אחריות',
         'כל הפריטים אותנטיים ומגיעים עם אריזה מקורית. בעיה איכותית — נטפל בה מיד.'],
        ['פתרון מחלוקות',
         'הדין החל הוא הדין הישראלי. סמכות שיפוט בלעדית לבתי המשפט בתל אביב.'],
      ],
      reviewed: false,
    },
    returns: {
      title: 'החזרות והחזרים',
      eyebrow: 'RETURNS',
      body: [
        ['חלון ההחזר',
         '14 יום מקבלת המשלוח. הפריט חייב להיות באריזתו המקורית, ללא שימוש.'],
        ['פריטים שלא ניתן להחזיר',
         'בשמים שנפתחו או שאריזת המגן הוסרה, פריטי היגיינה, ופריטים בהזמנה אישית.'],
        ['איך מחזירים',
         'יצרי קשר ב-returns@lapharmacia.co.il עם מספר ההזמנה. נשלח אלייך תווית החזר.'],
        ['החזר כספי',
         'מתבצע באותו אמצעי תשלום ששימש לרכישה, תוך 7 ימי עסקים מקבלת הפריט.'],
        ['פגם או טעות',
         'אם קיבלת פריט פגום או שגוי — אנחנו מטפלים בהחזרה על חשבוננו ושולחים פריט חלופי או החזר מלא לבחירתך.'],
      ],
      reviewed: false,
    },
  };
  const p = PAGES[page] || PAGES.privacy;

  return (
    <div style={{ paddingBottom: 80 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 2, fontWeight: 600 }}>{p.eyebrow}</div>
          <div style={{ fontFamily: displayFont, fontSize: 24, color: T.ink, fontWeight: 700, marginTop: 2 }}>{p.title}</div>
        </div>
      </div>
      {!p.reviewed && (
        <div style={{
          margin: '4px 20px 18px', padding: '10px 14px', borderRadius: 10,
          background: 'rgba(212,168,90,0.08)', border: '1px dashed rgba(212,168,90,0.35)',
          fontSize: 11, color: T.inkDim, lineHeight: 1.55, textAlign: 'right', direction: 'rtl',
        }}>
          ⚠ נוסח טיוטה. יש להחליף בנוסח עם עו"ד לפני פרסום בפועל.
        </div>
      )}
      <div style={{ padding: '0 24px' }}>
        {p.body.map(([head, text], i) => (
          <div key={i} style={{ marginBottom: 22 }}>
            <div style={{ fontFamily: displayFont, fontSize: 16, color: T.ink, fontWeight: 600, marginBottom: 6 }}>{head}</div>
            <div style={{ fontSize: 13, color: T.inkDim, lineHeight: 1.8 }}>{text}</div>
          </div>
        ))}
        <div style={{ marginTop: 32, paddingTop: 16, borderTop: `1px solid ${T.line}`, fontSize: 11, color: T.inkMute }}>
          עודכן: {new Date().toLocaleDateString('he-IL')} · La Pharmacia · רוטשילד 42, תל אביב
        </div>
      </div>
    </div>
  );
}

// ── Public order tracking (footer link, works without login) ──
function TrackOrderScreen({ T, displayFont, onBack }) {
  const [orderNumber, setOrderNumber] = useState('');
  const [email, setEmail] = useState('');
  const [order, setOrder] = useState(null);
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);

  const STATUS_LABELS = { pending: 'ממתין', paid: 'שולם', shipped: 'נשלח', delivered: 'נמסר', cancelled: 'בוטל', refunded: 'הוחזר' };
  const SHIP_LABELS = { express: 'אקספרס', standard: 'רגיל', regular: 'רגיל', pickup: 'איסוף עצמי' };

  async function track(e) {
    e.preventDefault();
    setBusy(true); setError(''); setOrder(null);
    try {
      const r = await window.API.post('/orders/track', { orderNumber: orderNumber.trim(), email: email.trim() });
      setOrder(r.order);
    } catch (err) {
      setError(err.message === 'not_found' ? 'הזמנה לא נמצאה. ודאי שמספר ההזמנה והאימייל נכונים.' : 'אירעה שגיאה');
    } finally { setBusy(false); }
  }

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        {onBack && <IconBtn T={T} icon="right" onClick={onBack} />}
        <div>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5, fontWeight: 600 }}>שירות לקוחות</div>
          <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700, marginTop: 2 }}>מעקב הזמנה</div>
        </div>
      </div>

      <form onSubmit={track} style={{ padding: '8px 16px' }}>
        <div style={{ fontSize: 13, color: T.inkDim, lineHeight: 1.7, marginBottom: 18 }}>
          הזיני את מספר ההזמנה שקיבלת באישור (LP-…) והאימייל ששימש להזמנה.
        </div>
        <CheckoutField T={T} label="מספר הזמנה" value={orderNumber} onChange={setOrderNumber} placeholder="LP-XXXX-XXXX" required />
        <CheckoutField T={T} label="אימייל" value={email} onChange={setEmail} type="email" required />
        {error && <div style={{ padding: 12, borderRadius: 12, background: 'rgba(220,80,80,0.12)', color: '#ffb8b8', fontSize: 13, marginBottom: 12 }}>{error}</div>}
        <button type="submit" disabled={busy} style={{
          width: '100%', padding: '14px', borderRadius: 999, marginTop: 6,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
          cursor: busy ? 'wait' : 'pointer', opacity: busy ? 0.7 : 1,
        }}>{busy ? '...' : 'איתור הזמנה'}</button>
      </form>

      {order && (
        <div style={{ padding: '24px 16px 0' }}>
          <div style={{ padding: 16, borderRadius: 16, background: T.bgCard, border: `1px solid ${T.line}` }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 }}>
              <div style={{ fontFamily: displayFont, fontSize: 17, fontWeight: 700 }}>{order.orderNumber}</div>
              <div style={{ fontSize: 11, color: T.inkMute }}>{new Date(order.createdAt).toLocaleString('he-IL')}</div>
            </div>
            {order.email && (
              <div style={{ fontSize: 11, color: T.inkDim, marginBottom: 10, direction: 'ltr', textAlign: 'right' }}>
                {order.email}
              </div>
            )}
            <div style={{ display: 'inline-flex', gap: 6, alignItems: 'center', padding: '5px 12px', borderRadius: 999,
              background: `color-mix(in oklab, ${T.accent}, transparent 80%)`, color: T.accent,
              fontSize: 12, fontWeight: 700,
            }}>
              <Icon name="check" size={12} strokeWidth={2.5} />
              {STATUS_LABELS[order.status] || order.status}
            </div>
            <div style={{ marginTop: 14, paddingTop: 14, borderTop: `1px solid ${T.line}` }}>
              {order.items.map((it, i) => (
                <div key={i} style={{ display: 'flex', gap: 10, padding: '8px 0', borderBottom: i < order.items.length - 1 ? `1px solid ${T.line}` : 'none' }}>
                  <div style={{ width: 50, height: 60, borderRadius: 10, overflow: 'hidden', background: T.bg, flexShrink: 0 }}>
                    {it.img && <Img src={it.img} style={{ width: '100%', height: '100%' }} />}
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 11, color: T.inkMute }}>{it.brand}</div>
                    <div style={{ fontSize: 13, fontWeight: 600, color: T.ink, marginTop: 2 }}>{it.name}</div>
                    <div style={{ fontSize: 11, color: T.inkDim, marginTop: 2 }}>×{it.qty}</div>
                  </div>
                  <div style={{ fontWeight: 700, color: T.ink, fontSize: 13 }}>{fmt(it.price * it.qty)}</div>
                </div>
              ))}
            </div>
            <div style={{ marginTop: 12, paddingTop: 12, borderTop: `1px solid ${T.line}`, fontSize: 13, color: T.inkDim }}>
              <Row T={T} l="משלוח" v={SHIP_LABELS[order.shippingMethod] || order.shippingMethod} />
              <Row T={T} l="סך הכל" v={<span style={{ color: T.ink, fontWeight: 700 }}>{fmt(order.total)}</span>} />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Forgot password (request reset link) ──
function ForgotPasswordScreen({ T, displayFont, onBack }) {
  const [email, setEmail] = useState('');
  const [busy, setBusy] = useState(false);
  const [done, setDone] = useState(false);

  async function submit(e) {
    e.preventDefault();
    setBusy(true);
    try { await window.API.post('/auth/forgot', { email: email.trim() }); }
    catch { /* always show same success message — don't leak account existence */ }
    finally { setBusy(false); setDone(true); }
  }

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>איפוס סיסמה</div>
      </div>
      {done ? (
        <div style={{ padding: '40px 24px', textAlign: 'center' }}>
          <Icon name="check" size={42} color={T.accent} strokeWidth={2} />
          <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700, marginTop: 14 }}>בדקי את המייל</div>
          <div style={{ fontSize: 13, color: T.inkDim, marginTop: 10, lineHeight: 1.7 }}>
            אם הכתובת רשומה אצלנו — שלחנו אליה קישור לאיפוס סיסמה. הקישור בתוקף לשעה.
          </div>
          <button onClick={onBack} style={{
            marginTop: 28, padding: '13px 28px', borderRadius: 999,
            background: 'transparent', border: `1px solid ${T.line}`, color: T.ink,
            fontSize: 13, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer',
          }}>חזרה</button>
        </div>
      ) : (
        <form onSubmit={submit} style={{ padding: '8px 16px' }}>
          <div style={{ fontSize: 13, color: T.inkDim, lineHeight: 1.7, marginBottom: 18 }}>
            הזיני את האימייל של החשבון. נשלח אלייך קישור לאיפוס.
          </div>
          <CheckoutField T={T} label="אימייל" value={email} onChange={setEmail} type="email" required />
          <button type="submit" disabled={busy} style={{
            width: '100%', padding: '14px', borderRadius: 999, marginTop: 6,
            background: T.accent, color: T.bg, border: 'none',
            fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
            cursor: busy ? 'wait' : 'pointer', opacity: busy ? 0.7 : 1,
          }}>{busy ? '...' : 'שליחת קישור'}</button>
        </form>
      )}
    </div>
  );
}

// ── Reset password (lands here from email link with ?reset=TOKEN) ──
function ResetPasswordScreen({ T, displayFont, token, onDone }) {
  const [password, setPassword] = useState('');
  const [confirm, setConfirm] = useState('');
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);

  async function submit(e) {
    e.preventDefault();
    setError('');
    if (password.length < 6) { setError('סיסמה לפחות 6 תווים'); return; }
    if (password !== confirm) { setError('הסיסמאות לא תואמות'); return; }
    setBusy(true);
    try {
      await window.API.post('/auth/reset', { token, password });
      onDone();
    } catch (err) {
      setError(err.message === 'expired_token' ? 'הקישור פג תוקף. בקשי איפוס חדש.'
             : err.message === 'invalid_token' ? 'קישור לא תקין או שכבר נוצל.'
             : 'אירעה שגיאה');
    } finally { setBusy(false); }
  }

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px' }}>
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>סיסמה חדשה</div>
        <div style={{ fontSize: 13, color: T.inkDim, marginTop: 6 }}>בחרי סיסמה חדשה לחשבון שלך.</div>
      </div>
      <form onSubmit={submit} style={{ padding: '8px 16px' }}>
        <CheckoutField T={T} label="סיסמה חדשה" value={password} onChange={setPassword} type="password" required />
        <CheckoutField T={T} label="אימות סיסמה" value={confirm} onChange={setConfirm} type="password" required />
        {error && <div style={{ padding: 12, borderRadius: 12, background: 'rgba(220,80,80,0.12)', color: '#ffb8b8', fontSize: 13, marginBottom: 12 }}>{error}</div>}
        <button type="submit" disabled={busy} style={{
          width: '100%', padding: '14px', borderRadius: 999, marginTop: 6,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
          cursor: busy ? 'wait' : 'pointer', opacity: busy ? 0.7 : 1,
        }}>{busy ? '...' : 'שמירת הסיסמה החדשה'}</button>
      </form>
    </div>
  );
}

// ── Auth screen — shown in the account tab when there's no logged-in user ──
function AuthScreen({ T, displayFont, onAuthed, onForgot }) {
  const [mode, setMode] = useState('login'); // 'login' | 'register'
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const ERR_MSG = {
    invalid_credentials: 'אימייל או סיסמה שגויים',
    invalid_email:       'כתובת מייל לא תקינה',
    weak_password:       'הסיסמה צריכה לפחות 6 תווים',
    name_required:       'נא להזין שם',
    email_taken:         'אימייל זה כבר רשום במערכת',
  };

  async function submit(e) {
    e.preventDefault();
    setError(''); setLoading(true);
    try {
      const path = mode === 'login' ? '/auth/login' : '/auth/register';
      const body = mode === 'login' ? { email, password } : { email, password, name };
      const { token, user } = await window.API.post(path, body);
      window.API.setToken(token);
      onAuthed(user);
    } catch (err) {
      setError(ERR_MSG[err.message] || 'משהו השתבש, נסי שוב');
    } finally {
      setLoading(false);
    }
  }

  const inputStyle = {
    width: '100%', padding: '14px 16px', borderRadius: 14,
    background: T.bgCard, border: `1px solid ${T.line}`,
    color: T.ink, fontSize: 14, fontFamily: 'inherit',
    direction: 'rtl', outline: 'none', boxSizing: 'border-box',
    transition: 'border-color 0.2s, background 0.2s',
  };

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 24px 16px' }}>
        <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 1.5, fontWeight: 600, textTransform: 'uppercase' }}>
          {mode === 'login' ? 'ברוכה השבה' : 'הצטרפות'}
        </div>
        <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, marginTop: 6, fontWeight: 600, lineHeight: 1.15 }}>
          {mode === 'login' ? 'התחברי לחשבון שלך' : 'פתחי חשבון חדש'}
        </div>
        <div style={{ fontSize: 13, color: T.inkDim, marginTop: 8, lineHeight: 1.6 }}>
          {mode === 'login'
            ? 'גישה לסל, להזמנות ולתוכנית הנקודות.'
            : 'נשמור לך את הסל, נעדכן על הזמנות ונצרף אותך למועדון.'}
        </div>
      </div>

      <form onSubmit={submit} style={{ padding: '8px 16px', display: 'flex', flexDirection: 'column', gap: 12 }}>
        {mode === 'register' && (
          <input type="text" placeholder="שם מלא" value={name} required minLength={1}
            onChange={e => setName(e.target.value)} style={inputStyle} />
        )}
        <input type="email" placeholder="אימייל" value={email} required autoComplete="email"
          onChange={e => setEmail(e.target.value)} style={inputStyle} />
        <input type="password" placeholder="סיסמה" value={password} required minLength={6}
          autoComplete={mode === 'login' ? 'current-password' : 'new-password'}
          onChange={e => setPassword(e.target.value)} style={inputStyle} />

        {error && (
          <div style={{
            padding: '12px 14px', borderRadius: 12,
            background: 'rgba(220, 80, 80, 0.12)', border: '1px solid rgba(220, 80, 80, 0.35)',
            color: '#ffb8b8', fontSize: 13,
          }}>{error}</div>
        )}

        <button type="submit" disabled={loading} style={{
          padding: '15px 18px', borderRadius: 999,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
          letterSpacing: 0.4, cursor: loading ? 'wait' : 'pointer',
          marginTop: 6, opacity: loading ? 0.7 : 1,
          transition: 'transform 0.15s, opacity 0.2s',
          boxShadow: `0 8px 24px color-mix(in oklab, ${T.accent}, transparent 70%)`,
        }}>
          {loading ? '...' : mode === 'login' ? 'התחברי' : 'יצירת חשבון'}
        </button>

        <button type="button" onClick={() => { setMode(mode === 'login' ? 'register' : 'login'); setError(''); }}
          style={{
            background: 'none', border: 'none', cursor: 'pointer',
            color: T.inkDim, fontSize: 13, fontFamily: 'inherit',
            padding: '12px', marginTop: 4,
          }}>
          {mode === 'login' ? 'אין לך חשבון? הצטרפי' : 'כבר יש לך חשבון? התחברי'}
        </button>
        {mode === 'login' && onForgot && (
          <button type="button" onClick={onForgot} style={{
            background: 'none', border: 'none', cursor: 'pointer',
            color: T.accent, fontSize: 12, fontFamily: 'inherit',
            padding: '4px', marginTop: -8,
          }}>שכחתי סיסמה</button>
        )}
      </form>

      <div style={{ padding: '20px 24px 0', textAlign: 'center', fontSize: 11, color: T.inkMute, letterSpacing: 0.4, lineHeight: 1.7 }}>
        בהצטרפות את מאשרת את <span style={{ color: T.accent }}>תנאי השימוש</span> ו<span style={{ color: T.accent }}>מדיניות הפרטיות</span>
      </div>
    </div>
  );
}

function AccountScreen({ T, displayFont, user, onOpenOrders, onOpenProfile, onOpenAddresses, onLogout }) {
  const items = [
    { l: 'הזמנות שלי',  s: 'צפיה בהיסטוריית הזמנות', action: onOpenOrders },
    { l: 'פרטים אישיים', s: user?.phone || 'הוספת מספר טלפון', action: onOpenProfile },
    { l: 'כתובות',      s: 'ניהול כתובות שמורות', action: onOpenAddresses },
    { l: 'התראות',      s: 'אימייל + פוש' },
    { l: 'עזרה ותמיכה', s: '' },
    { l: 'התנתקות',     s: '', action: onLogout, danger: true },
  ];
  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 24px' }}>
        <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5, fontWeight: 600 }}>
          חברה מאז {new Date(user?.created_at || Date.now()).getFullYear()}
        </div>
        <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, marginTop: 4, fontWeight: 700 }}>
          {user?.name || 'אורחת'}
        </div>
        <div style={{ fontSize: 12, color: T.inkDim, marginTop: 2 }}>{user?.email || ''}</div>

        <div style={{
          marginTop: 22, padding: 18, borderRadius: 18,
          background: `linear-gradient(135deg, ${T.bgCard}, ${T.bgSoft})`,
          border: `1px solid ${T.line}`,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        }}>
          <div>
            <div style={{ fontSize: 10, letterSpacing: 0.5, color: T.accent, fontWeight: 600 }}>חברת אטלייה</div>
            <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, marginTop: 4, fontWeight: 700 }}>1,240 נק׳</div>
            <div style={{ fontSize: 11, color: T.inkDim, marginTop: 2 }}>260 לדרגה הבאה</div>
          </div>
          <Icon name="sparkle" size={28} color={T.accent} />
        </div>
      </div>

      <div style={{ padding: '0 16px' }}>
        {items.map((x, i) => (
          <button key={x.l} onClick={x.action} disabled={!x.action} style={{
            width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            padding: '16px 4px', borderBottom: i === items.length - 1 ? 'none' : `1px solid ${T.line}`,
            background: 'none', border: 'none', textAlign: 'right',
            cursor: x.action ? 'pointer' : 'default',
            color: x.danger ? T.accent : T.ink,
            fontFamily: 'inherit', opacity: x.action ? 1 : 0.55,
          }}>
            <div>
              <div style={{ fontSize: 14 }}>{x.l}</div>
              {x.s && <div style={{ fontSize: 11, color: T.inkMute, marginTop: 2 }}>{x.s}</div>}
            </div>
            <Icon name="left" size={14} color={T.inkMute} />
          </button>
        ))}
      </div>
    </div>
  );
}

// ── Shop ──
function ShopScreen({ T, displayFont, showGlow, onOpenCategory, onOpenSearch, onBack }) {
  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
        {onBack ? (
          <IconBtn T={T} icon="right" onClick={onBack} />
        ) : null}
        <div style={{ flex: 1, textAlign: onBack ? 'center' : 'right' }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5, fontWeight: 600 }}>חנות</div>
          <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, marginTop: 2, fontWeight: 700 }}>כל הקטגוריות</div>
        </div>
        <IconBtn T={T} icon="search" onClick={onOpenSearch} />
      </div>

      <div style={{ padding: '8px 16px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        {CATEGORIES.map((c, i) => (
          <button key={c.id} onClick={() => onOpenCategory(c.id)} style={{
            position: 'relative', height: 180, borderRadius: 24, overflow: 'hidden',
            border: `1px solid ${T.line}`, background: 'transparent', padding: 0,
            cursor: 'pointer', textAlign: 'right',
          }}>
            <Img src={c.img} style={{ position: 'absolute', inset: 0 }} />
            <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(270deg, ${T.bg} 0%, transparent 70%)` }} />
            <div style={{ position: 'absolute', insetInlineEnd: 22, top: '50%', transform: 'translateY(-50%)' }}>
              <div style={{ fontSize: 10, color: T.accent, fontWeight: 700 }}>0{i + 1}</div>
              <div style={{ fontFamily: displayFont, fontSize: 30, color: T.ink, marginTop: 6, lineHeight: 1, fontWeight: 700 }}>{c.label}</div>
              <div style={{ fontSize: 11.5, color: T.inkDim, marginTop: 6 }}>{c.sub}</div>
            </div>
            <div style={{
              position: 'absolute', insetInlineStart: 18, top: '50%', transform: 'translateY(-50%)',
              width: 36, height: 36, borderRadius: 18,
              background: `color-mix(in oklab, ${T.ink}, transparent 80%)`,
              backdropFilter: 'blur(10px)',
              display: 'grid', placeItems: 'center', color: T.ink,
            }}>
              <Icon name="left" size={16} strokeWidth={2} />
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

// ── Splash ──
function Splash({ T, displayFont, onEnter }) {
  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 200,
      background: T.bg,
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      padding: '0 32px', animation: 'fadein 0.5s ease',
    }}>
      <div style={{ position: 'absolute', inset: 0,
        background: `radial-gradient(ellipse at 50% 30%, ${T.glow}, transparent 60%)`,
        opacity: 0.3, pointerEvents: 'none' }} />
      <img src="assets/logo.jpg" alt="La Pharmacia" style={{
        width: 220, height: 220, borderRadius: 24, objectFit: 'cover',
        boxShadow: `0 30px 60px -10px ${T.glow}`,
      }} />
      <div style={{ marginTop: 30, fontFamily: displayFont, fontSize: 26, color: T.ink, lineHeight: 1.3, textAlign: 'center', fontWeight: 700 }}>
        בריאות ויופי,<br/><em style={{ color: T.accent, fontStyle: 'normal' }}>במיטבם.</em>
      </div>
      <div style={{ marginTop: 12, fontSize: 12.5, color: T.inkDim, textAlign: 'center', maxWidth: 280, lineHeight: 1.6 }}>
        תיקים, בשמים ואקססוריז שנבחרו עבור היומיומי והנדיר.
      </div>
      <button onClick={onEnter} style={{
        marginTop: 36, padding: '16px 40px', borderRadius: 999,
        background: T.ink, color: T.bg, border: 'none',
        fontSize: 13, letterSpacing: 0.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit',
      }}>כניסה לחנות</button>
    </div>
  );
}

// ── Toast ──
function Toast({ T, message, show }) {
  return (
    <div style={{
      position: 'absolute', left: '50%', top: 60,
      transform: `translate(-50%, ${show ? '0' : '-30px'})`,
      opacity: show ? 1 : 0,
      transition: 'all 0.4s cubic-bezier(0.2,0.8,0.2,1)',
      pointerEvents: 'none', zIndex: 300,
      padding: '12px 22px', borderRadius: 999,
      background: T.ink, color: T.bg,
      fontSize: 12, fontWeight: 700,
      boxShadow: '0 12px 30px rgba(0,0,0,0.4)',
    }}>{message}</div>
  );
}

// ── Tiny inline brand-icon SVGs used in desktop chrome ──
const Insta = () => (
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6">
    <rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/>
    <circle cx="17.5" cy="6.5" r="0.9" fill="currentColor" stroke="none"/>
  </svg>
);
const Fb = () => (
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6">
    <path d="M15 3h-2a4 4 0 0 0-4 4v3H6v4h3v7h4v-7h3l1-4h-4V7a1 1 0 0 1 1-1h2z"/>
  </svg>
);
const Wa = () => (
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6">
    <path d="M21 12a9 9 0 0 1-13.5 7.8L3 21l1.3-4.5A9 9 0 1 1 21 12z"/>
    <path d="M8.5 9c.3 1.5 1 2.7 2.1 3.7s2.2 1.7 3.7 2c.6.1 1.2-.2 1.4-.7l.3-.8c.2-.5-.1-1-.6-1.2l-1.4-.5c-.4-.1-.9 0-1.1.4l-.3.4a5 5 0 0 1-2.3-2.3l.4-.3c.4-.3.5-.7.4-1.1l-.5-1.4c-.2-.5-.7-.7-1.2-.6l-.8.3c-.5.2-.8.8-.7 1.4z"/>
  </svg>
);
const PhoneSvg = () => (
  <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
    <path d="M5 4h3l2 5-2.5 1.5a11 11 0 0 0 6 6L15 14l5 2v3a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z"/>
  </svg>
);

// ── Desktop top nav (hidden under 768px via CSS) ──
function DesktopTopNav({ active, cartCount, transparent, onTab, onOpenCategory, onSearch }) {
  return (
    <nav className={`lp-topnav lp-desktop-only${transparent ? ' lp-topnav--transparent' : ''}`}>
      <div className="lp-topnav-brand" onClick={() => onTab('home')} style={{ display: 'flex', alignItems: 'center' }}>
        <img src="assets/logo.png?v=2" alt="La Pharmacia" style={{
          height: 96, width: 'auto', maxWidth: 360, objectFit: 'contain',
          filter: 'brightness(0) invert(1)',
        }} />
      </div>
      <div className="lp-topnav-icons">
        <button className="lp-iconbtn" onClick={onSearch} aria-label="חיפוש"><Icon name="search" size={20} /></button>
        <button className="lp-iconbtn" onClick={() => onTab('wishlist')} aria-label="מועדפים"><Icon name="heart" size={20} /></button>
        {FEATURES.customerAccounts && (
          <button className="lp-iconbtn" onClick={() => onTab('account')} aria-label="חשבון"><Icon name="user" size={20} /></button>
        )}
        <button className="lp-iconbtn" onClick={() => onTab('cart')} aria-label="סל">
          <Icon name="bag" size={20} />
          {cartCount > 0 && <span className="lp-cart-badge">{cartCount}</span>}
        </button>
      </div>
    </nav>
  );
}

// ── useMediaQuery — observes a CSS media query and re-renders on change ──
function useMediaQuery(query) {
  const [matches, setMatches] = useState(() =>
    typeof window !== 'undefined' && window.matchMedia(query).matches
  );
  useEffect(() => {
    const mq = window.matchMedia(query);
    const onChange = () => setMatches(mq.matches);
    mq.addEventListener('change', onChange);
    return () => mq.removeEventListener('change', onChange);
  }, [query]);
  return matches;
}

// ── Desktop home page — full-bleed editorial layout (renders only on >=768px home) ──
function DesktopHome({ onOpenCategory, onOpenBrand, onOpenAllBrands, onOpenProduct, onOpenSearch }) {
  return (
    <div className="lp-desktop-home">
      <Banner />
      {/* HERO — admin-managed slider */}
      {HOME_SLIDES.length > 0 ? (
        <HomeSlider layout="desktop" T={null}
          onCta={(action) => {
            if (action.type === 'category') onOpenCategory(action.id);
            else if (action.type === 'tab') onOpenCategory('__all');
          }} />
      ) : (
        // Empty-state fallback so a fresh DB doesn't show a blank page
        <section className="lp-hero">
          <div className="lp-hero-media">
            <img src={IMG.hero || 'https://images.unsplash.com/photo-1592945403244-b3fbafd7f539?w=1600&q=85'} alt="" />
            <div className="lp-hero-veil" />
          </div>
          <div className="lp-hero-content">
            <div className="lp-hero-eyebrow">ATELIER · TEL AVIV</div>
            <h1 className="lp-hero-title">אוצרת בידיים,<br/><em>נשאית בלב</em></h1>
            <p className="lp-hero-sub">בית של אובייקטים יפים — תיקים, בשמים ואקססוריז שנבחרו אחד אחד.</p>
            <div className="lp-hero-ctas">
              <button className="lp-btn lp-btn-primary" onClick={() => onOpenCategory('__all')}>גלי את הקולקציה</button>
            </div>
          </div>
        </section>
      )}

      {/* TRUST STRIP */}
      <section className="lp-trust">
        <div className="lp-trust-inner">
          <div className="lp-trust-item"><Icon name="truck" size={22} /><div><b>משלוח חינם</b><span>בהזמנה מעל ₪400</span></div></div>
          <div className="lp-trust-item"><Icon name="shield" size={22} /><div><b>החזר תוך 30 יום</b><span>ללא שאלות</span></div></div>
          <div className="lp-trust-item"><Icon name="leaf" size={22} /><div><b>בית מרקחת מורשה</b><span>בפיקוח משרד הבריאות</span></div></div>
          <div className="lp-trust-item"><Icon name="sparkle" size={22} /><div><b>איסוף בחנות</b><span>רוטשילד 42, תל אביב</span></div></div>
        </div>
      </section>

      {/* CATEGORIES */}
      <section className="lp-section">
        <div className="lp-section-head">
          <div className="lp-eyebrow">קולקציות</div>
          <h2 className="lp-section-title">הקטגוריות <em>שלנו</em></h2>
          <p className="lp-section-sub">שש משפחות, אינסוף שילובים. כל פריט נבחר ביד מתוך מאות.</p>
        </div>
        <div className="lp-cat-grid">
          {CATEGORIES.map(c => (
            <button key={c.id} className="lp-cat-card" onClick={() => onOpenCategory(c.id)}>
              <div className="lp-cat-img"><img src={c.img} alt="" /></div>
              <div className="lp-cat-meta">
                <div className="lp-cat-label">{c.label}</div>
                <div className="lp-cat-sub">{c.sub} · גלי ←</div>
              </div>
            </button>
          ))}
        </div>
      </section>

      {/* EDITORIAL BANNER — full-bleed alt section */}
      <section className="lp-editorial">
        <div className="lp-editorial-inner">
          <div className="lp-editorial-copy">
            <div className="lp-eyebrow">סיפור</div>
            <h2 className="lp-section-title" style={{ textAlign: 'right' }}>היופי שב<em>שקט</em></h2>
            <p>אנחנו מאמינות שיופי אמיתי לא צועק. הוא נישא לאט, מתגלה ברגעים. הקטלוג שלנו הוא אסיף של פריטים שעוברים את מבחן הזמן — תיקי עור שמתעדנים עם השימוש, ניחוחות שמשתנים על העור, אובייקטים שאפשר להעביר בירושה.</p>
            <button className="lp-btn lp-btn-ghost lp-btn-light" onClick={() => onOpenCategory('__all')}>קראי את הסיפור המלא</button>
          </div>
          <div className="lp-editorial-image">
            <img src={IMG.bottle1} alt="" />
          </div>
        </div>
      </section>

      {/* FEATURED PRODUCTS — admin-flagged best sellers (will be auto-derived later) */}
      <section className="lp-section">
        <div className="lp-section-head">
          <div className="lp-eyebrow">הכי נמכרים</div>
          <h2 className="lp-section-title">המוצרים ה<em>חמים</em></h2>
          <p className="lp-section-sub">המבוקשים ביותר השבוע</p>
        </div>
        <div className="lp-prod-grid">
          {(PRODUCTS.filter(p => p.featured).slice(0, 8).length > 0
              ? PRODUCTS.filter(p => p.featured).slice(0, 8)
              : PRODUCTS.slice(0, 8)).map(p => (
            <button key={p.id} className="lp-prod-card" onClick={() => onOpenProduct(p)}>
              <div className="lp-prod-img">
                <img src={p.img} alt="" />
                {p.tag && <span className="lp-prod-tag">{p.tag}</span>}
              </div>
              <div className="lp-prod-meta">
                <div className="lp-prod-brand">{p.brand}</div>
                <div className="lp-prod-name">{p.name}</div>
                <div className="lp-prod-price">
                  {p.was && <span className="was">{fmt(p.was)}</span>}
                  <span className="now">{fmt(p.price)}</span>
                </div>
              </div>
            </button>
          ))}
        </div>
        <div style={{ textAlign: 'center', marginTop: 48 }}>
          <button className="lp-btn lp-btn-ghost lp-btn-light" onClick={() => onOpenCategory('__all')}>צפי בכל המוצרים ←</button>
        </div>
      </section>

      {/* INSTAGRAM STRIP (admin-managed) */}
      <InstagramStrip layout="desktop" />

      {/* BRANDS — alt section */}
      <section className="lp-section-alt">
        <div className="lp-section-alt-inner">
          <div className="lp-section-head">
            <div className="lp-eyebrow">בעולם שלנו</div>
            <h2 className="lp-section-title">מותגים <em>מובילים</em></h2>
            <p className="lp-section-sub">מסטודיואים קטנים בפריז ועד בתי בושם בפלורנס</p>
          </div>
          <div className="lp-brands-grid">
            {(BRANDS.filter(b => b.featured).length > 0 ? BRANDS.filter(b => b.featured) : BRANDS).map(b => (
              <div key={b.id} className="lp-brand-card" onClick={() => onOpenBrand?.(b.id)} style={{ cursor: 'pointer' }}>
                <div className="lp-brand-img"><img src={b.img} alt="" /></div>
                <div className="lp-brand-name">{b.name}</div>
                <div className="lp-brand-count">{b.count} פריטים</div>
              </div>
            ))}
          </div>
          {onOpenAllBrands && (
            <div style={{ textAlign: 'center', marginTop: 48 }}>
              <button className="lp-btn lp-btn-ghost lp-btn-light" onClick={onOpenAllBrands}>צפי בכל המותגים ←</button>
            </div>
          )}
        </div>
      </section>

      {/* NEWSLETTER */}
      <section className="lp-newsletter">
        <div className="lp-eyebrow">מועדון La Pharmacia</div>
        <h2 className="lp-newsletter-title">הצטרפי <em>לסיפור</em></h2>
        <p>השקות חדשות, אירועי מותג, ומבצעים בלעדיים — ישירות לתיבה שלך, פעם בשבוע.</p>
        <NewsletterForm T={{ bg: '#0a130f', bgCard: 'rgba(255,255,255,0.04)', ink: '#f0ece4', line: 'rgba(255,255,255,0.1)', accent: '#d4a85a' }} />
      </section>
    </div>
  );
}

// ── Desktop footer ──
function DesktopFooter({ onTab, onOpenCategory, onOpenTrackOrder, onOpenLegal }) {
  return (
    <div className="lp-footer-wrap lp-desktop-only">
      <div className="lp-footer">
        <div className="lp-footer-brand">
          <div className="wordmark">La <span className="accent">Pharmacia</span></div>
          <p>בית של אובייקטים יפים — תיקים, בשמים ואקססוריז שנבחרו ביד אחת אחת.<br/>{SETTINGS.store_address}.</p>
          <div className="socials">
            {SETTINGS.store_phone      && <a href={`tel:${String(SETTINGS.store_phone).replace(/[^\d+]/g, '')}`} aria-label="Phone"><PhoneSvg /></a>}
            {SETTINGS.social_instagram && <a href={SETTINGS.social_instagram} target="_blank" rel="noopener" aria-label="Instagram"><Insta /></a>}
            {SETTINGS.social_facebook  && <a href={SETTINGS.social_facebook}  target="_blank" rel="noopener" aria-label="Facebook"><Fb /></a>}
            {SETTINGS.social_whatsapp  && <a href={SETTINGS.social_whatsapp}  target="_blank" rel="noopener" aria-label="WhatsApp"><Wa /></a>}
          </div>
        </div>
        <div>
          <h4>קניות</h4>
          <ul>
            {CATEGORIES.map(c => (
              <li key={c.id}><a onClick={() => onOpenCategory(c.id)}>{c.label}</a></li>
            ))}
          </ul>
        </div>
        <div>
          <h4>שירות</h4>
          <ul>
            <li><a onClick={onOpenTrackOrder} style={{ cursor: 'pointer' }}>מעקב הזמנה</a></li>
            <li><a>יצירת קשר</a></li>
            <li><a onClick={() => onOpenLegal?.('returns')} style={{ cursor: 'pointer' }}>משלוחים והחזרות</a></li>
            <li><a>שאלות נפוצות</a></li>
            <li><a onClick={() => onOpenLegal?.('privacy')} style={{ cursor: 'pointer' }}>מדיניות פרטיות</a></li>
            <li><a onClick={() => onOpenLegal?.('terms')} style={{ cursor: 'pointer' }}>תקנון</a></li>
          </ul>
        </div>
        <div>
          <h4>החנות</h4>
          <ul>
            <li><a onClick={() => onTab('account')}>החשבון שלי</a></li>
            <li><a onClick={() => onTab('wishlist')}>מועדפים</a></li>
            <li><a onClick={() => onTab('cart')}>סל הקניות</a></li>
            <li><a>הצטרפות לניוזלטר</a></li>
          </ul>
        </div>
      </div>
      <div className="lp-footer-bottom">
        <div>© 2026 La Pharmacia · כל הזכויות שמורות</div>
        <div className="payments">VISA · MASTERCARD · BIT · APPLE PAY</div>
      </div>
    </div>
  );
}

// ── Saved addresses (account → כתובות) ──
function AddressesScreen({ T, displayFont, onBack }) {
  const [rows, setRows] = useState(null);
  const [editing, setEditing] = useState(null);   // null | {} for new | { ...row } for edit
  const [error, setError] = useState('');

  const load = () => window.API.get('/addresses').then(r => setRows(r.addresses)).catch(() => setError('load_failed'));
  useEffect(() => { load(); }, []);

  async function save(form) {
    setError('');
    try {
      if (form.id) await window.API.patch(`/addresses/${form.id}`, form);
      else         await window.API.post('/addresses', form);
      setEditing(null); load();
    } catch (err) { setError(err.data?.error || 'save_failed'); }
  }
  async function remove(id) {
    await window.API.del(`/addresses/${id}`); load();
  }
  async function setDefault(a) {
    await window.API.patch(`/addresses/${a.id}`, { isDefault: true }); load();
  }

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>הכתובות שלי</div>
      </div>

      <div style={{ padding: '8px 16px' }}>
        {!rows && <div style={{ padding: 40, color: T.inkDim, textAlign: 'center' }}>טוען...</div>}
        {rows?.length === 0 && (
          <div style={{ padding: '40px 24px', textAlign: 'center', color: T.inkDim, fontSize: 13 }}>
            עדיין אין כתובות שמורות.<br/>הוסיפי כתובת ראשונה כדי לחסוך זמן בהזמנות הבאות.
          </div>
        )}
        {rows?.map(a => (
          <div key={a.id} style={{
            padding: 14, marginBottom: 10, borderRadius: 14,
            background: T.bgCard,
            border: `1px solid ${a.isDefault ? T.accent : T.line}`,
          }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <div style={{ fontFamily: displayFont, fontSize: 15, fontWeight: 700, color: T.ink }}>
                {a.label || 'כתובת'}
                {a.isDefault && <span style={{ marginInlineStart: 8, fontSize: 10, color: T.accent, fontWeight: 700, letterSpacing: 0.5 }}>· ברירת מחדל</span>}
              </div>
            </div>
            <div style={{ fontSize: 13, color: T.inkDim, lineHeight: 1.6 }}>
              {a.street}<br/>{a.city}{a.zip ? ` · ${a.zip}` : ''}<br/>{a.phone}
            </div>
            <div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap' }}>
              {!a.isDefault && (
                <button onClick={() => setDefault(a)} style={{
                  background: 'none', border: `1px solid ${T.line}`, borderRadius: 999,
                  padding: '6px 12px', fontSize: 11, color: T.ink, cursor: 'pointer', fontFamily: 'inherit',
                }}>הגדרי כברירת מחדל</button>
              )}
              <button onClick={() => setEditing(a)} style={{
                background: 'none', border: `1px solid ${T.line}`, borderRadius: 999,
                padding: '6px 12px', fontSize: 11, color: T.ink, cursor: 'pointer', fontFamily: 'inherit',
              }}>עריכה</button>
              <button onClick={() => remove(a.id)} style={{
                background: 'none', border: 'none', padding: '6px 12px', fontSize: 11,
                color: T.accent, cursor: 'pointer', fontFamily: 'inherit',
              }}>מחיקה</button>
            </div>
          </div>
        ))}

        <button onClick={() => setEditing({})} style={{
          width: '100%', padding: '14px', marginTop: 8, borderRadius: 14,
          background: 'none', border: `1.5px dashed ${T.line}`, color: T.ink,
          fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
        }}>+ כתובת חדשה</button>
      </div>

      {editing !== null && (
        <AddressForm T={T} displayFont={displayFont} initial={editing} onSave={save} onCancel={() => setEditing(null)} error={error} />
      )}
    </div>
  );
}

function AddressForm({ T, displayFont, initial, onSave, onCancel, error }) {
  const [f, setF] = useState({
    id: initial.id, label: initial.label || '',
    street: initial.street || '', city: initial.city || '',
    zip: initial.zip || '', phone: initial.phone || '',
    isDefault: initial.isDefault || false,
  });
  const set = (k) => (v) => setF(p => ({ ...p, [k]: v }));
  const valid = f.street?.trim() && f.city?.trim();

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 200,
      background: `color-mix(in oklab, ${T.bg}, transparent 8%)`,
      backdropFilter: 'blur(20px)', overflowY: 'auto',
    }}>
      <div style={{ padding: '54px 20px 32px', maxWidth: 460, margin: '0 auto' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 22 }}>
          <IconBtn T={T} icon="right" onClick={onCancel} />
          <div style={{ fontFamily: displayFont, fontSize: 20, color: T.ink, fontWeight: 700 }}>
            {initial.id ? 'עריכת כתובת' : 'כתובת חדשה'}
          </div>
        </div>
        <CheckoutField T={T} label="שם הכתובת (בית, עבודה...)" value={f.label} onChange={set('label')} placeholder="בית" />
        <CheckoutField T={T} label="רחוב ומספר" value={f.street} onChange={set('street')} required />
        <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 10 }}>
          <CheckoutField T={T} label="עיר" value={f.city} onChange={set('city')} required />
          <CheckoutField T={T} label="מיקוד" value={f.zip} onChange={set('zip')} />
        </div>
        <CheckoutField T={T} label="טלפון" value={f.phone} onChange={set('phone')} type="tel" />

        <label style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 0', cursor: 'pointer' }}>
          <input type="checkbox" checked={f.isDefault} onChange={e => set('isDefault')(e.target.checked)}
            style={{ width: 18, height: 18, accentColor: T.accent }} />
          <span style={{ fontSize: 13, color: T.ink }}>הגדרי כברירת מחדל</span>
        </label>

        {error && <div style={{ padding: 12, borderRadius: 12, background: 'rgba(220,80,80,0.12)', color: '#ffb8b8', fontSize: 13, marginBottom: 12 }}>שמירה נכשלה</div>}

        <button onClick={() => valid && onSave(f)} disabled={!valid} style={{
          width: '100%', padding: '15px', borderRadius: 999,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
          cursor: valid ? 'pointer' : 'not-allowed', opacity: valid ? 1 : 0.5,
          marginTop: 8,
        }}>{initial.id ? 'שמירת שינויים' : 'הוספת כתובת'}</button>
      </div>
    </div>
  );
}

// ── Orders list ──
function OrdersScreen({ T, displayFont, onBack, onOpenOrder }) {
  const [orders, setOrders] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;
    window.API.get('/orders')
      .then(r => { if (!cancelled) setOrders(r.orders); })
      .catch(e => { if (!cancelled) setError(e.message || 'load_failed'); });
    return () => { cancelled = true; };
  }, []);

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>ההזמנות שלי</div>
      </div>

      <div style={{ padding: '8px 16px' }}>
        {error && (
          <div style={{ padding: 18, color: T.accent, fontSize: 13, textAlign: 'center' }}>שגיאה בטעינה</div>
        )}
        {!orders && !error && (
          <div style={{ padding: 40, color: T.inkDim, fontSize: 13, textAlign: 'center' }}>טוען...</div>
        )}
        {orders && orders.length === 0 && (
          <div style={{ padding: '60px 24px', textAlign: 'center', color: T.inkDim }}>
            <Icon name="bag" size={42} color={T.inkMute} />
            <div style={{ marginTop: 14, fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>עדיין אין הזמנות</div>
            <div style={{ marginTop: 8, fontSize: 13 }}>ההזמנה הראשונה שלך תופיע כאן.</div>
          </div>
        )}
        {orders && orders.map(o => (
          <button key={o.id} onClick={() => onOpenOrder(o.id)} style={{
            width: '100%', display: 'block', textAlign: 'right', direction: 'rtl',
            background: T.bgCard, border: `1px solid ${T.line}`, borderRadius: 16,
            padding: 16, marginBottom: 10, cursor: 'pointer', color: T.ink, fontFamily: 'inherit',
            transition: 'transform 0.15s, border-color 0.2s',
          }}
          onPointerDown={e => e.currentTarget.style.transform = 'scale(0.99)'}
          onPointerUp={e => e.currentTarget.style.transform = 'scale(1)'}
          onPointerLeave={e => e.currentTarget.style.transform = 'scale(1)'}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
              <div style={{ fontFamily: displayFont, fontSize: 16, fontWeight: 700 }}>{o.order_number}</div>
              <div style={{ fontSize: 11, color: T.inkMute }}>{new Date(o.created_at).toLocaleDateString('he-IL')}</div>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6,
                padding: '4px 10px', borderRadius: 999,
                background: `color-mix(in oklab, ${T.accent}, transparent 80%)`,
                color: T.accent, fontSize: 11, fontWeight: 600,
              }}>
                <Icon name="check" size={12} strokeWidth={2.4} />
                {o.status === 'paid' ? 'שולם' : o.status}
              </div>
              <div style={{ fontFamily: displayFont, fontSize: 17, fontWeight: 700 }}>{fmt(o.total)}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

// ── Single order detail ──
function OrderDetailScreen({ T, displayFont, orderId, onBack }) {
  const [order, setOrder] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;
    window.API.get('/orders/' + orderId)
      .then(r => { if (!cancelled) setOrder(r.order); })
      .catch(e => { if (!cancelled) setError(e.message || 'load_failed'); });
    return () => { cancelled = true; };
  }, [orderId]);

  if (error) return <div style={{ padding: 60, color: T.accent, textAlign: 'center' }}>שגיאה בטעינה</div>;
  if (!order) return <div style={{ padding: 60, color: T.inkDim, textAlign: 'center' }}>טוען...</div>;

  const addr = order.address || {};
  const SHIP_LABEL = { express: 'אקספרס · מחר', regular: 'משלוח רגיל', pickup: 'איסוף עצמי' };
  const PAY_LABEL  = { credit: 'כרטיס אשראי', apple_pay: 'Apple Pay', paypal: 'PayPal', bit: 'Bit' };

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.5 }}>הזמנה</div>
          <div style={{ fontFamily: displayFont, fontSize: 18, color: T.ink, fontWeight: 700 }}>{order.order_number}</div>
        </div>
      </div>

      <div style={{ padding: '0 16px' }}>
        <div style={{
          padding: 16, borderRadius: 16,
          background: `color-mix(in oklab, ${T.accent}, transparent 85%)`,
          border: `1px solid color-mix(in oklab, ${T.accent}, transparent 60%)`,
          marginBottom: 16,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, color: T.accent, fontSize: 13, fontWeight: 700 }}>
            <Icon name="check" size={16} strokeWidth={2.5} /> {order.status === 'paid' ? 'התשלום אושר' : order.status}
          </div>
          <div style={{ marginTop: 6, fontSize: 11, color: T.inkDim }}>
            {new Date(order.created_at).toLocaleString('he-IL')}
          </div>
        </div>

        {/* Items */}
        <div style={{ marginBottom: 16 }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 1, fontWeight: 600, marginBottom: 8, textTransform: 'uppercase' }}>פריטים</div>
          {(order.items || []).map(it => (
            <div key={it.id} style={{ display: 'flex', gap: 12, padding: '10px 0', borderBottom: `1px solid ${T.line}` }}>
              <div style={{ width: 64, height: 76, borderRadius: 12, overflow: 'hidden', flexShrink: 0, background: T.bgCard }}>
                <Img src={it.img} style={{ width: '100%', height: '100%' }} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 9.5, color: T.inkMute }}>{it.brand}</div>
                <div style={{ fontFamily: displayFont, fontSize: 13.5, color: T.ink, marginTop: 3, fontWeight: 600, lineHeight: 1.3 }}>{it.name}</div>
                <div style={{ fontSize: 11, color: T.inkDim, marginTop: 4 }}>
                  {it.size && <>מידה: {it.size} · </>}כמות: {it.qty}
                </div>
              </div>
              <div style={{ fontFamily: displayFont, fontSize: 14, color: T.ink, fontWeight: 700 }}>{fmt(it.price * it.qty)}</div>
            </div>
          ))}
        </div>

        {/* Address */}
        <div style={{ marginBottom: 16, padding: 14, borderRadius: 14, border: `1px solid ${T.line}` }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 1, fontWeight: 600, textTransform: 'uppercase', marginBottom: 6 }}>כתובת משלוח</div>
          <div style={{ fontSize: 13, color: T.ink, lineHeight: 1.65 }}>
            {addr.name && <>{addr.name}<br/></>}
            {addr.street}<br/>
            {addr.city}{addr.zip ? ` · ${addr.zip}` : ''}<br/>
            {addr.phone}
          </div>
        </div>

        {/* Totals */}
        <div style={{ padding: '8px 0', borderTop: `1px solid ${T.line}` }}>
          <Row T={T} l="סכום ביניים" v={fmt(order.subtotal)} />
          <Row T={T} l="משלוח" v={order.shipping ? fmt(order.shipping) : 'חינם'} />
          <Row T={T} l="אופן משלוח" v={SHIP_LABEL[order.shipping_method] || order.shipping_method} />
          <Row T={T} l="תשלום" v={PAY_LABEL[order.payment_method] || order.payment_method} />
          <div style={{ display: 'flex', justifyContent: 'space-between', padding: '12px 0 6px', borderTop: `1px solid ${T.line}`, marginTop: 8 }}>
            <span style={{ color: T.ink, fontWeight: 700 }}>סך הכל</span>
            <span style={{ color: T.ink, fontWeight: 700, fontFamily: displayFont, fontSize: 18 }}>{fmt(order.total)}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Profile edit ──
function ProfileEditScreen({ T, displayFont, user, onBack, onSave }) {
  const [name, setName] = useState(user?.name || '');
  const [phone, setPhone] = useState(user?.phone || '');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  const inputStyle = {
    width: '100%', padding: '14px 16px', borderRadius: 14,
    background: T.bgCard, border: `1px solid ${T.line}`,
    color: T.ink, fontSize: 14, fontFamily: 'inherit',
    direction: 'rtl', outline: 'none', boxSizing: 'border-box',
  };

  async function submit(e) {
    e.preventDefault();
    setError(''); setSaving(true);
    try { await onSave({ name, phone: phone || null }); }
    catch (err) { setError('שגיאה בשמירה'); }
    finally { setSaving(false); }
  }

  return (
    <div style={{ paddingBottom: 120 }}>
      <div style={{ padding: '54px 20px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <IconBtn T={T} icon="right" onClick={onBack} />
        <div style={{ fontFamily: displayFont, fontSize: 22, color: T.ink, fontWeight: 700 }}>פרטים אישיים</div>
      </div>

      <form onSubmit={submit} style={{ padding: '8px 16px', display: 'flex', flexDirection: 'column', gap: 12 }}>
        <label style={{ display: 'block' }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.4, marginBottom: 6, textTransform: 'uppercase' }}>שם מלא</div>
          <input type="text" value={name} required onChange={e => setName(e.target.value)} style={inputStyle} />
        </label>
        <label style={{ display: 'block' }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.4, marginBottom: 6, textTransform: 'uppercase' }}>טלפון</div>
          <input type="tel" value={phone} onChange={e => setPhone(e.target.value)} placeholder="050-1234567" style={inputStyle} />
        </label>
        <label style={{ display: 'block' }}>
          <div style={{ fontSize: 11, color: T.inkMute, letterSpacing: 0.4, marginBottom: 6, textTransform: 'uppercase' }}>אימייל</div>
          <input type="email" value={user?.email || ''} disabled style={{ ...inputStyle, opacity: 0.55 }} />
        </label>

        {error && (
          <div style={{ padding: 12, borderRadius: 12, background: 'rgba(220,80,80,0.12)', color: '#ffb8b8', fontSize: 13 }}>{error}</div>
        )}

        <button type="submit" disabled={saving} style={{
          padding: '15px 18px', borderRadius: 999,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
          letterSpacing: 0.4, cursor: saving ? 'wait' : 'pointer', marginTop: 8,
        }}>
          {saving ? '...' : 'שמירה'}
        </button>
      </form>
    </div>
  );
}

// ── Newsletter form (used by home + desktop home) ──
function NewsletterForm({ T, compact = false }) {
  const [email, setEmail] = useState('');
  const [state, setState] = useState('idle'); // idle | sending | done | error

  async function submit(e) {
    e.preventDefault();
    if (!email.includes('@')) { setState('error'); return; }
    setState('sending');
    try {
      await window.API.post('/newsletter', { email });
      setState('done'); setEmail('');
    } catch { setState('error'); }
  }

  if (compact) {
    return (
      <form onSubmit={submit} style={{ display: 'flex', gap: 8, marginTop: 12 }}>
        <input type="email" value={email} onChange={e => setEmail(e.target.value)} required
          placeholder={state === 'done' ? 'הצטרפת ✓' : 'כתובת המייל שלך'}
          disabled={state === 'sending' || state === 'done'} style={{
            flex: 1, padding: '13px 16px', borderRadius: 14,
            background: T.bgCard, border: `1px solid ${T.line}`,
            color: T.ink, fontSize: 12, outline: 'none', fontFamily: 'inherit',
            textAlign: 'right', direction: 'rtl',
          }} />
        <button type="submit" disabled={state === 'sending' || state === 'done'} style={{
          padding: '0 18px', borderRadius: 14,
          background: T.accent, color: T.bg, border: 'none',
          fontSize: 11, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit',
        }}>{state === 'done' ? 'תודה' : state === 'sending' ? '...' : 'הרשמה'}</button>
      </form>
    );
  }

  return (
    <form onSubmit={submit} className="lp-newsletter-form">
      <input type="email" value={email} onChange={e => setEmail(e.target.value)} required
        placeholder={state === 'done' ? 'תודה שהצטרפת ✓' : 'כתובת המייל שלך'}
        disabled={state === 'sending' || state === 'done'} />
      <button type="submit" disabled={state === 'sending' || state === 'done'}>
        {state === 'done' ? 'תודה' : state === 'sending' ? '...' : 'הרשמה'}
      </button>
    </form>
  );
}

// ── App shell ──
function App() {
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const T = THEMES[tweaks.theme] || THEMES.emerald;

  const [tab, setTab] = useState('home');
  const [searchOpen, setSearchOpen] = useState(false);
  const [stack, setStack] = useState([]);
  // Cart + wishlist are persisted to localStorage so guests don't lose them on refresh.
  // When customer accounts are on AND the user is logged in, the boot effect overwrites
  // these from the server (server is the source of truth in that case).
  const [cart, setCart] = useState(() => {
    try { return JSON.parse(localStorage.getItem('lp_cart') || '[]'); } catch { return []; }
  });
  const [wishlist, setWishlist] = useState(() => {
    try { return JSON.parse(localStorage.getItem('lp_wishlist') || '[]'); } catch { return []; }
  });
  const [toast, setToast] = useState({ msg: '', show: false });
  const [user, setUser] = useState(null);
  const [bootError, setBootError] = useState(null);
  const [dataVersion, setDataVersion] = useState(0); // bumped after API replaces CATEGORIES/PRODUCTS/BRANDS
  const scrollRef = useRef(null);

  const isDesktop = useMediaQuery('(min-width: 768px)');

  useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, [stack, tab]);
  useEffect(() => { window.scrollTo({ top: 0 }); }, [tab, stack.length]);

  // Persist cart + wishlist to localStorage on every change so a refresh keeps them.
  // Skipped when the user is logged in — server is the source of truth in that case.
  useEffect(() => {
    if (user) return;
    try { localStorage.setItem('lp_cart', JSON.stringify(cart)); } catch {}
  }, [cart, user]);
  useEffect(() => {
    if (user) return;
    try { localStorage.setItem('lp_wishlist', JSON.stringify(wishlist)); } catch {}
  }, [wishlist, user]);

  // Track page scroll for transparent-topnav-over-hero on desktop home
  const [pageScrolled, setPageScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setPageScrolled(window.scrollY > 80);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // ── Boot: detect ?reset=TOKEN in the URL and push the reset screen ──
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const t = params.get('reset');
    if (t) {
      setStack([{ type: 'reset-password', token: t }]);
      // Strip the param so refresh doesn't re-trigger
      const cleanUrl = window.location.pathname + window.location.hash;
      window.history.replaceState({}, '', cleanUrl);
    }
  }, []);

  // ── Boot: fetch catalog + settings + IG from API + restore session if token exists ──
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const [c, b, p, s, ig, sh, pm, sl] = await Promise.all([
          window.API.get('/categories'),
          window.API.get('/brands'),
          window.API.get('/products'),
          window.API.get('/settings').catch(() => ({ settings: SETTINGS })),
          window.API.get('/instagram/posts').catch(() => ({ posts: [] })),
          window.API.get('/shipping').catch(() => ({ methods: SHIPPING_METHODS })),
          window.API.get('/payments').catch(() => ({ methods: PAYMENT_METHODS })),
          window.API.get('/home-slides').catch(() => ({ slides: [] })),
        ]);
        if (cancelled) return;
        if (c.categories?.length) CATEGORIES = c.categories;
        if (b.brands?.length)     BRANDS     = b.brands;
        if (p.products?.length)   PRODUCTS   = p.products;
        if (s.settings)           SETTINGS   = { ...SETTINGS, ...s.settings };
        if (ig.posts)             IG_POSTS   = ig.posts;
        if (sh.methods?.length)   SHIPPING_METHODS = sh.methods;
        if (pm.methods?.length)   PAYMENT_METHODS  = pm.methods;
        if (sl.slides)            HOME_SLIDES = sl.slides;
        setDataVersion(v => v + 1);
      } catch (err) {
        console.warn('[boot] catalog fetch failed, using offline fallback:', err.message);
        if (!cancelled) setBootError('catalog');
      }

      // Only restore a user session when customer accounts are enabled.
      // The admin token is stored under the same localStorage key by /admin, so without
      // this gate, signing in to admin would carry over to the storefront and hide
      // the guest checkout flow (no email field, "save address" toggle, etc.).
      if (FEATURES.customerAccounts && window.API.token) {
        try {
          const me = await window.API.get('/auth/me');
          if (!cancelled) setUser(me.user);
          // Hydrate cart + wishlist from the server
          const [cartRes, wishRes] = await Promise.all([
            window.API.get('/cart').catch(() => ({ items: [] })),
            window.API.get('/wishlist').catch(() => ({ items: [] })),
          ]);
          if (!cancelled) {
            setCart(cartRes.items.map(i => ({ product: i.product, size: i.size, qty: i.qty, serverId: i.id })));
            setWishlist(wishRes.items);
          }
        } catch (err) {
          // Token was rejected (likely expired) — drop it silently
          window.API.setToken(null);
        }
      }
    })();
    return () => { cancelled = true; };
  }, []);

  // ── Auth helpers ──
  const onAuthed = async (u) => {
    setUser(u);
    try {
      const [cartRes, wishRes] = await Promise.all([
        window.API.get('/cart').catch(() => ({ items: [] })),
        window.API.get('/wishlist').catch(() => ({ items: [] })),
      ]);
      setCart(cartRes.items.map(i => ({ product: i.product, size: i.size, qty: i.qty, serverId: i.id })));
      setWishlist(wishRes.items);
    } catch { /* empty cart on fresh signup is fine */ }
  };
  const logout = () => {
    window.API.setToken(null);
    setUser(null);
    setCart([]);
    setWishlist([]);
    setTab('home');
  };

  const flashToast = (msg) => {
    setToast({ msg, show: true });
    setTimeout(() => setToast(t => ({ ...t, show: false })), 1800);
  };

  const updateProfile = async (patch) => {
    const { user: updated } = await window.API.patch('/auth/me', patch);
    setUser(updated);
    return updated;
  };

  // ── Cart actions: add / setQty / remove / clear ───────────────────────────
  // When logged in, every mutation hits /api/cart and we mirror the server response.
  // When logged out, mutations stay local. Cart shape: { product, size, qty, serverId? }
  const cartActions = {
    add: async (product, size, variantId = null, qty = 1) => {
      if (user) {
        try {
          const { items } = await window.API.post('/cart', { productId: product.id, variantId, size: size || null, qty });
          setCart(items.map(i => ({ product: i.product, size: i.size, qty: i.qty, variantId: i.variantId, serverId: i.id })));
        } catch (err) {
          console.error('[cart.add]', err);
          flashToast('שגיאה בהוספה לסל');
          return;
        }
      } else {
        setCart(c => {
          const ix = c.findIndex(x => x.product.id === product.id && x.size === size && x.variantId === variantId);
          if (ix >= 0) { const next = [...c]; next[ix] = { ...next[ix], qty: next[ix].qty + qty }; return next; }
          return [...c, { product, size, variantId, qty }];
        });
      }
      flashToast('נוסף לסל');
      // After a successful add, jump to the cart so the user sees what they just added.
      setStack([]);
      setTab('cart');
    },
    setQty: async (item, qty) => {
      if (user && item.serverId) {
        try {
          const { items } = await window.API.patch(`/cart/${item.serverId}`, { qty });
          setCart(items.map(i => ({ product: i.product, size: i.size, qty: i.qty, serverId: i.id })));
          return;
        } catch (err) {
          console.error('[cart.setQty]', err);
          flashToast('שגיאה בעדכון');
          return;
        }
      }
      setCart(c => qty <= 0
        ? c.filter(x => !(x.product.id === item.product.id && x.size === item.size))
        : c.map(x => (x.product.id === item.product.id && x.size === item.size) ? { ...x, qty } : x)
      );
    },
    remove: (item) => cartActions.setQty(item, 0),
    clearLocal: () => setCart([]),
  };

  // ── Wishlist actions: toggle / has ────────────────────────────────────────
  const wishActions = {
    has: (productId) => wishlist.some(w => w.id === productId),
    toggle: async (product) => {
      if (user) {
        try {
          const has = wishActions.has(product.id);
          const { items } = await (has
            ? window.API.del(`/wishlist/${product.id}`)
            : window.API.post('/wishlist', { productId: product.id }));
          setWishlist(items);
          flashToast(has ? 'הוסר מהמועדפים' : 'נשמר במועדפים');
        } catch (err) {
          console.error('[wishlist]', err);
          flashToast('שגיאה');
        }
      } else {
        setWishlist(w => {
          const has = w.some(x => x.id === product.id);
          if (has) return w.filter(x => x.id !== product.id);
          return [...w, { id: product.id, name: product.name, brand: product.brand, price: product.price, was: product.was, img: product.img, tag: product.tag, cat: product.cat }];
        });
        flashToast(wishActions.has(product.id) ? 'הוסר מהמועדפים' : 'נשמר במועדפים');
      }
    },
  };

  const top = stack[stack.length - 1];
  const openCategory = (id) => setStack(s => [...s, { type: 'category', id }]);
  const openBrand    = (id) => setStack(s => [...s, { type: 'brand', id }]);
  const openAllBrands = () => setStack(s => [...s, { type: 'brands-all' }]);
  const openProduct  = (p) => setStack(s => [...s, { type: 'product', product: p }]);
  const openCheckout = () => setStack(s => [...s, { type: 'checkout' }]);
  const openOrders   = () => setStack(s => [...s, { type: 'orders' }]);
  const openOrderDetail = (orderId) => setStack(s => [...s, { type: 'order-detail', orderId }]);
  const openProfileEdit = () => setStack(s => [...s, { type: 'profile-edit' }]);
  const openAddresses   = () => setStack(s => [...s, { type: 'addresses' }]);
  const openTrackOrder  = () => setStack(s => [...s, { type: 'track-order' }]);
  const openForgotPwd   = () => setStack(s => [...s, { type: 'forgot-password' }]);
  const openLegal       = (page) => setStack(s => [...s, { type: 'legal', page }]);
  const openOrderSuccess = () => setStack([{ type: 'order-success' }]);
  const back         = () => setStack(s => s.slice(0, -1));

  const cartCount = cart.reduce((n, x) => n + x.qty, 0);

  let content;
  if (top?.type === 'product') {
    content = <ProductScreen T={T} displayFont={tweaks.displayFont} showGlow={tweaks.showGlow}
                product={top.product} onBack={back} onAdd={cartActions.add}
                inWishlist={wishActions.has(top.product.id)}
                onToggleWish={() => wishActions.toggle(top.product)} />;
  } else if (top?.type === 'orders') {
    content = <OrdersScreen T={T} displayFont={tweaks.displayFont} onBack={back}
                onOpenOrder={openOrderDetail} />;
  } else if (top?.type === 'order-detail') {
    content = <OrderDetailScreen T={T} displayFont={tweaks.displayFont} orderId={top.orderId} onBack={back} />;
  } else if (top?.type === 'profile-edit') {
    content = <ProfileEditScreen T={T} displayFont={tweaks.displayFont} user={user} onBack={back}
                onSave={async (patch) => { await updateProfile(patch); back(); flashToast('הפרופיל עודכן'); }} />;
  } else if (top?.type === 'addresses') {
    content = <AddressesScreen T={T} displayFont={tweaks.displayFont} onBack={back} />;
  } else if (top?.type === 'track-order') {
    content = <TrackOrderScreen T={T} displayFont={tweaks.displayFont} onBack={back} />;
  } else if (top?.type === 'forgot-password') {
    content = <ForgotPasswordScreen T={T} displayFont={tweaks.displayFont} onBack={back} />;
  } else if (top?.type === 'reset-password') {
    content = <ResetPasswordScreen T={T} displayFont={tweaks.displayFont} token={top.token} onDone={() => { back(); setTab('account'); flashToast('הסיסמה הוחלפה — התחברי שוב'); }} />;
  } else if (top?.type === 'legal') {
    content = <LegalPageScreen T={T} displayFont={tweaks.displayFont} page={top.page} onBack={back} />;
  } else if (top?.type === 'checkout') {
    content = <CheckoutScreen T={T} displayFont={tweaks.displayFont} items={cart} user={user}
                onBack={back}
                onPlace={async (form) => {
                  const paymentMap = { card: 'credit', apple: 'apple_pay', paypal: 'paypal', bit: 'bit', cod: 'cod', credit: 'credit' };
                  const address = {
                    name:  form.addr.name,
                    email: form.addr.email,
                    street: form.addr.street, city: form.addr.city,
                    zip: form.addr.zip, phone: form.addr.phone,
                  };
                  const body = {
                    address,
                    shippingMethod: form.delivery,
                    paymentMethod:  paymentMap[form.pay] || 'cod',
                  };

                  if (user) {
                    // Logged-in: server cart is the source of truth. Mirror local → server, then place.
                    // Carry variantId across so the server records the right price/stock per line.
                    await window.API.del('/cart').catch(() => {});
                    for (const it of cart) {
                      await window.API.post('/cart', {
                        productId: it.product.id,
                        variantId: it.variantId || null,
                        size: it.size || null,
                        qty: it.qty,
                      });
                    }
                  } else {
                    // Guest: items + (optional) account creation flow into the body.
                    body.items = cart.map(it => ({
                      productId: it.product.id,
                      variantId: it.variantId || null,
                      size: it.size || null,
                      qty: it.qty,
                    }));
                    if (form.wantAccount && form.password) {
                      body.createAccount = true;
                      body.password = form.password;
                    }
                  }

                  let result;
                  try {
                    result = await window.API.post('/orders', body);
                  } catch (err) {
                    if (err.message === 'out_of_stock') {
                      const lines = (err.data?.items || []).map(i => `${i.name} (זמין: ${i.available}, ביקשת: ${i.requested})`).join('\n');
                      throw new Error('אזלו פריטים מהמלאי:\n' + lines);
                    }
                    if (err.message === 'email_taken')        throw new Error('האימייל כבר רשום במערכת — נסי להתחבר במקום ליצור חשבון.');
                    if (err.message === 'guest_email_required') throw new Error('נדרש אימייל לסיום הזמנת אורח');
                    if (err.message === 'address_incomplete')   throw new Error('נא למלא את כל פרטי המשלוח');
                    if (err.message === 'cart_empty')          throw new Error('הסל ריק');
                    throw err;
                  }
                  console.log('[order placed]', result.order.orderNumber, '₪' + result.order.total);

                  // If we created an account during checkout, sign the user in seamlessly.
                  if (result.auth) {
                    window.API.setToken(result.auth.token);
                    setUser(result.auth.user);
                  }

                  // Redirect to Grow if the server returned a payment URL (card / wallets)
                  // Save the address for next time if user opted in (logged in only)
                  if (form.saveAddress && (user || result.auth)) {
                    window.API.post('/addresses', {
                      label: '', street: form.addr.street, city: form.addr.city,
                      zip: form.addr.zip || null, phone: form.addr.phone, isDefault: false,
                    }).catch(() => {});
                  }

                  if (result.paymentUrl) { window.location.href = result.paymentUrl; return; }

                  setCart([]);
                  openOrderSuccess();
                }} />;
  } else if (top?.type === 'order-success') {
    content = <OrderSuccessScreen T={T} displayFont={tweaks.displayFont}
                onDone={() => { setStack([]); setTab('home'); }} />;
  } else if (top?.type === 'category' && top.id === '__all') {
    content = <ShopScreen T={T} displayFont={tweaks.displayFont} showGlow={tweaks.showGlow}
                onOpenCategory={openCategory} onOpenSearch={() => setTab('search')} onBack={back} />;
  } else if (top?.type === 'category') {
    content = <CategoryScreen T={T} displayFont={tweaks.displayFont} denseGrid={tweaks.denseGrid}
                catId={top.id} onBack={back} onOpenProduct={openProduct} />;
  } else if (top?.type === 'brands-all') {
    content = <BrandsScreen T={T} displayFont={tweaks.displayFont}
                onBack={back} onOpenBrand={openBrand} />;
  } else if (top?.type === 'brand') {
    content = <BrandScreen T={T} displayFont={tweaks.displayFont}
                brandId={top.id} onBack={back} onOpenProduct={openProduct} />;
  } else if (tab === 'shop') {
    content = <ShopScreen T={T} displayFont={tweaks.displayFont} showGlow={tweaks.showGlow}
                onOpenCategory={openCategory} onOpenSearch={() => setSearchOpen(true)} />;
  } else if (tab === 'wishlist') {
    content = <WishlistScreen T={T} displayFont={tweaks.displayFont}
                items={wishlist}
                onOpenProduct={openProduct}
                onRemove={(p) => wishActions.toggle(p)} />;
  } else if (tab === 'cart') {
    content = <CartScreen T={T} displayFont={tweaks.displayFont}
                items={cart} actions={cartActions}
                onBack={() => setTab('home')} onCheckout={openCheckout} />;
  } else if (tab === 'track') {
    // No onBack → back button hidden; user switches tabs to leave
    content = <TrackOrderScreen T={T} displayFont={tweaks.displayFont} />;
  } else if (tab === 'account' && FEATURES.customerAccounts) {
    content = user
      ? <AccountScreen T={T} displayFont={tweaks.displayFont} user={user}
          onOpenOrders={openOrders}
          onOpenProfile={openProfileEdit}
          onOpenAddresses={openAddresses}
          onLogout={logout} />
      : <AuthScreen   T={T} displayFont={tweaks.displayFont} onAuthed={onAuthed} onForgot={openForgotPwd} />;
  } else {
    content = <HomeScreen T={T} displayFont={tweaks.displayFont} showGlow={tweaks.showGlow}
                onOpenProduct={openProduct} onOpenCategory={openCategory} onOpenBrand={openBrand}
                onOpenAllBrands={openAllBrands}
                onOpenSearch={() => setSearchOpen(true)} onOpenTrackOrder={openTrackOrder}
                onOpenLegal={openLegal}
                scrollRef={scrollRef} />;
  }

  // Show tab bar only on root tabs (not when drilled into stack)
  const showTabBar = stack.length === 0;

  // Helpers wired to desktop nav: jumping to a tab or category resets the screen stack
  const goTab = (t) => { setStack([]); setTab(t); };
  const goCategory = (id) => { setTab('home'); setStack([{ type: 'category', id }]); };

  // Desktop home shows the full-bleed editorial layout. All other screens fall back to the
  // centred mobile shell on desktop (intentional — it's a v1 scope decision).
  const isDesktopHome = isDesktop && tab === 'home' && stack.length === 0;
  const topnavTransparent = isDesktopHome && !pageScrolled;

  return (
    <>
      {/* Desktop topnav lives only on the desktop home page; column views use their own in-screen header */}
      {isDesktopHome && (
        <DesktopTopNav active={tab} cartCount={cartCount}
          transparent={topnavTransparent}
          onTab={goTab}
          onOpenCategory={goCategory}
          onSearch={() => setSearchOpen(true)} />
      )}

      {isDesktopHome ? (
        <DesktopHome
          onOpenCategory={openCategory}
          onOpenBrand={openBrand}
          onOpenAllBrands={openAllBrands}
          onOpenProduct={openProduct}
          onOpenSearch={() => setSearchOpen(true)} />
      ) : (
        <div className="lp-mobile-shell">
          <div ref={scrollRef} className="hide-scroll" style={{
            position: 'absolute', inset: 0,
            background: T.bg, color: T.ink,
            fontFamily: 'Heebo, ui-sans-serif, system-ui, sans-serif',
            overflowY: 'auto', overflowX: 'hidden',
            WebkitOverflowScrolling: 'touch',
            direction: 'rtl',
          }}
          data-screen-label={
            top?.type === 'product' ? `Product · ${top.product.name}` :
            top?.type === 'checkout' ? 'Checkout' :
            top?.type === 'order-success' ? 'Order success' :
            top?.type === 'category' ? `Category · ${top.id}` :
            tab.charAt(0).toUpperCase() + tab.slice(1)
          }>
            <div key={`${tab}-${stack.length}`} style={{ animation: 'slideIn 0.4s cubic-bezier(0.2,0.8,0.2,1)' }}>
              {content}
            </div>
          </div>

          {/* Fixed tab bar — OUTSIDE scrollable region, hidden on desktop via class */}
          {showTabBar && <TabBar T={T} active={tab} onNav={setTab} cartCount={cartCount} />}

          <Toast T={T} message={toast.msg} show={toast.show} />
        </div>
      )}

      {searchOpen && (
        <SearchOverlay T={T} displayFont={tweaks.displayFont} onClose={() => setSearchOpen(false)}
          onOpenProduct={(p) => { setSearchOpen(false); openProduct(p); }}
          onOpenCategory={(id) => { setSearchOpen(false); openCategory(id); }} />
      )}

      <DesktopFooter onTab={goTab} onOpenCategory={goCategory} onOpenTrackOrder={openTrackOrder} onOpenLegal={openLegal} />
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
