// Mobile storefront — responsive ≤768px.
// Uses live products / i18n / assets from desktop site.
// Adapted from Passion's Petals Design System Mobile.jsx, with:
//   - Tweaks/IOSFrame/StatusBar removed
//   - State (lang, cart, route, activeId) shared via props from App
//   - Image paths rebased to ./assets/

const iconBtnM = { background: "transparent", border: 0, padding: 6, cursor: "pointer", color: "var(--pp-ink)", display: "inline-flex" };
const cartBadgeM = { position: "absolute", top: 0, right: 0, minWidth: 16, height: 16, padding: "0 4px", borderRadius: 8, background: "var(--pp-pink-deep)", color: "#fff", fontFamily: "var(--font-sans)", fontSize: 10, fontWeight: 700, display: "inline-flex", alignItems: "center", justifyContent: "center" };
const qtyBtnM = { width: 32, height: 32, borderRadius: 999, border: 0, background: "transparent", color: "var(--pp-ink)", cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center" };

function MobileTopBar({ t, lang, setLang, onMenu, onCart, cartCount, onSearch }) {
  return (
    <div style={{ position: "sticky", top: 0, zIndex: 30, background: "var(--bg)", borderBottom: "1px solid var(--hairline)" }}>
      <div style={{ background: "var(--pp-blush-bar)", color: "var(--pp-ink)", padding: "5px 16px", textAlign: "center", fontFamily: "var(--font-sans)", fontSize: 9, fontWeight: 600, letterSpacing: "0.18em", textTransform: "uppercase" }}>
        {t.promo}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "auto 1fr auto auto auto", alignItems: "center", gap: 6, padding: "12px 16px" }}>
        <button onClick={onMenu} style={iconBtnM} aria-label="Menu"><ICN.menu size={22} /></button>
        <a style={{ display: "flex", alignItems: "center", gap: 8, justifyContent: "center" }}>
          <img src="./assets/logo/passions-petals-logo.jpeg" alt="" style={{ width: 30, height: 30, borderRadius: 6, objectFit: "cover" }} />
          <span style={{ fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 18, color: "var(--pp-pink-deep)", letterSpacing: "0.02em" }}>Passion's Petals</span>
        </a>
        <button onClick={onSearch} style={iconBtnM} aria-label="Search"><ICN.search size={20} /></button>
        <button onClick={() => setLang(lang === "en" ? "zh" : "en")} style={{ ...iconBtnM, fontFamily: "var(--font-sans)", fontSize: 11, fontWeight: 700, letterSpacing: "0.1em" }} aria-label="Toggle language">{lang === "en" ? "中" : "EN"}</button>
        <button onClick={onCart} style={{ ...iconBtnM, position: "relative" }} aria-label="Cart">
          <ICN.bag size={20} />
          {cartCount > 0 && <span style={cartBadgeM}>{cartCount}</span>}
        </button>
      </div>
    </div>
  );
}

function MobileHero({ t, lang, onShop }) {
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  return (
    <section style={{ position: "relative", height: 460, backgroundImage: "url(./assets/photos/hero-pink-bouquet.png)", backgroundSize: "cover", backgroundPosition: "55% 50%" }}>
      <div style={{ position: "absolute", inset: 0, background: "linear-gradient(180deg, rgba(255,255,255,0) 30%, rgba(252,236,234,0.2) 100%)" }} />
      <div style={{ position: "absolute", left: 20, right: 20, bottom: 28, color: "var(--pp-ink)" }}>
        <div style={{ fontFamily: "var(--font-sans)", fontSize: 9, fontWeight: 600, letterSpacing: "0.28em", marginBottom: 12, whiteSpace: "pre-line", lineHeight: 1.5 }}>{t.hero_eyebrow}</div>
        <h1 style={{ fontFamily: disp, fontWeight: 400, fontSize: lang === "zh" ? 34 : 38, lineHeight: 1.06, margin: 0, letterSpacing: lang === "zh" ? "0.02em" : "-0.005em", textWrap: "balance" }}>
          {t.hero_title_a}<br />{t.hero_title_b}<br /><span className="pp-italic-accent">{t.hero_title_c}</span>
        </h1>
        <button onClick={onShop} style={{ marginTop: 16, fontFamily: lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)", fontSize: 11, fontWeight: 700, letterSpacing: "0.22em", padding: "12px 22px", borderRadius: 0, border: 0, background: "var(--pp-blush)", color: "var(--pp-ink)", boxShadow: "var(--shadow-2)", cursor: "pointer" }}>{t.hero_cta} →</button>
      </div>
    </section>
  );
}

function MobileFeatures({ t, lang }) {
  const items = [
    { icon: <ICN.flower size={20} />, label: t.feat_1_t },
    { icon: <ICN.leaf size={20} />, label: t.feat_3_t },
    { icon: <ICN.heart size={20} />, label: t.feat_4_t },
  ];
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  return (
    <section style={{ background: "var(--pp-paper-soft)", padding: "18px 8px", borderBottom: "1px solid var(--hairline)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 0 }}>
        {items.map((it, i) => (
          <div key={i} style={{ textAlign: "center", padding: "0 4px", borderRight: i < 2 ? "1px solid var(--pp-paper-edge)" : 0 }}>
            <div style={{ display: "flex", justifyContent: "center", marginBottom: 6, color: "var(--pp-ink)" }}>{it.icon}</div>
            <div style={{ fontFamily: ff, fontSize: lang === "zh" ? 10 : 8.5, fontWeight: 600, letterSpacing: lang === "zh" ? "0.04em" : "0.16em", textTransform: lang === "zh" ? "none" : "uppercase", color: "var(--pp-ink)", lineHeight: 1.3 }}>{it.label}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

function MobileCollections({ t, lang, onPickCollection }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  return (
    <section style={{ background: "var(--pp-collections-bg, #F5CFC6)", padding: "28px 16px" }}>
      <div style={{ textAlign: "center", marginBottom: 18, fontFamily: ff, fontSize: lang === "zh" ? 13 : 10, fontWeight: 600, letterSpacing: lang === "zh" ? "0.18em" : "0.32em", textTransform: lang === "zh" ? "none" : "uppercase", color: "var(--pp-ink)" }}>{t.shop_collections}</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 12 }}>
        {COLLECTIONS.map(c => (
          <article key={c.slug} onClick={() => onPickCollection(c.slug)} className="pp-card" style={{ background: "var(--bg-card)", overflow: "hidden", boxShadow: "var(--shadow-2)", cursor: "pointer" }}>
            <div className="pp-card-img-wrap" style={{ aspectRatio: "1/1" }}>
              <div style={{ width: "100%", height: "100%", backgroundImage: `url(./assets/photos/${c.cover})`, backgroundSize: "cover", backgroundPosition: "center" }} />
            </div>
            <div style={{ padding: "12px 8px 14px", textAlign: "center" }}>
              <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 700, letterSpacing: "0.18em", color: "var(--pp-ink)", textTransform: lang === "zh" ? "none" : "uppercase" }}>{lang === "zh" ? c.name_zh : c.name_en}</div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

// Mobile collection filter page — products whose `collections` includes the slug.
function MobileCollectionPage({ t, lang, slug, onPick }) {
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const meta = COLLECTIONS.find(c => c.slug === slug);
  const items = PRODUCTS.filter(p => (p.collections || []).includes(slug));
  return (
    <section style={{ background: "var(--bg)", padding: "20px 16px 32px" }}>
      <div style={{ marginBottom: 18 }}>
        <div style={{ fontFamily: ff, fontSize: 9, fontWeight: 600, letterSpacing: "0.32em", color: "var(--pp-pink-deep)", textTransform: lang === "zh" ? "none" : "uppercase" }}>{lang === "zh" ? "花束系列" : "Collections"}</div>
        <h2 style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 28 : 32, margin: "6px 0 4px", color: "var(--pp-ink)" }}>{meta ? (lang === "zh" ? meta.name_zh : meta.name_en) : slug}</h2>
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 13, color: "var(--pp-ink-soft)" }}>
          {items.length} {lang === "zh" ? "款花束" : (items.length === 1 ? "bouquet" : "bouquets")}
        </div>
      </div>
      {items.length > 0 ? (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 14 }}>
          {items.map(p => (
            <article key={p.id} onClick={() => onPick(p.id)} className="pp-card" style={{ background: "var(--bg-card)", overflow: "hidden", border: "1px solid var(--hairline)", cursor: "pointer", position: "relative" }}>
              <div className="pp-card-img-wrap" style={{ aspectRatio: "4/5", position: "relative" }}>
                <div style={{ width: "100%", height: "100%", backgroundImage: `url(./assets/photos/${p.photo})`, backgroundSize: "cover", backgroundPosition: "center", filter: p.isSoldOut ? "grayscale(0.4)" : "none" }} />
              </div>
              <div style={{ padding: "10px 10px 14px" }}>
                <div style={{ fontFamily: ff, fontSize: 8, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink-mute)" }}>NO. {p.code}</div>
                <div style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 16 : 17, color: "var(--pp-ink)", margin: "4px 0 6px", lineHeight: 1.15 }}>{lang === "zh" ? p.name_zh : p.name_en}</div>
                <div style={{ fontFamily: ff, fontSize: 12, fontWeight: 700, color: p.isSoldOut || p.isCustom ? "var(--pp-ink-mute)" : "var(--pp-pink-deep)", letterSpacing: p.isSoldOut || p.isCustom ? "0.18em" : "normal" }}>
                  {p.isSoldOut ? t.sold_out : p.isCustom ? t.custom_label : `S$ ${p.price}`}
                </div>
              </div>
            </article>
          ))}
        </div>
      ) : (
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 14, color: "var(--pp-ink-soft)", padding: "24px 0" }}>{lang === "zh" ? "暂无花束。" : "Nothing here yet."}</div>
      )}
    </section>
  );
}

// Mobile /collections index — list 4 collection cards.
function MobileCollectionsIndex({ t, lang, onPickCollection }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  return (
    <section style={{ background: "var(--bg)", padding: "20px 16px 36px" }}>
      <h2 style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 28 : 32, margin: "6px 0 16px", color: "var(--pp-ink)" }}>{lang === "zh" ? "花束系列" : "Collections"}</h2>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 12 }}>
        {COLLECTIONS.map(c => (
          <article key={c.slug} onClick={() => onPickCollection(c.slug)} className="pp-card" style={{ background: "var(--bg-card)", overflow: "hidden", boxShadow: "var(--shadow-2)", cursor: "pointer" }}>
            <div className="pp-card-img-wrap" style={{ aspectRatio: "1/1" }}>
              <div style={{ width: "100%", height: "100%", backgroundImage: `url(./assets/photos/${c.cover})`, backgroundSize: "cover", backgroundPosition: "center" }} />
            </div>
            <div style={{ padding: "12px 8px 14px", textAlign: "center" }}>
              <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 700, letterSpacing: "0.18em", color: "var(--pp-ink)", textTransform: lang === "zh" ? "none" : "uppercase" }}>{lang === "zh" ? c.name_zh : c.name_en}</div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

function MobileGrid({ t, lang, onPick, limit }) {
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const items = limit ? PRODUCTS.slice(0, limit) : PRODUCTS;
  return (
    <section style={{ background: "var(--bg)", padding: "32px 16px 36px" }}>
      <div style={{ textAlign: "center", marginBottom: 20 }}>
        <div style={{ fontFamily: ff, fontSize: 9, fontWeight: 600, letterSpacing: "0.32em", color: "var(--pp-pink-deep)" }}>{lang === "zh" ? "全部花束" : "SHOP ALL"}</div>
        <h2 style={{ fontFamily: disp, fontWeight: 400, fontSize: lang === "zh" ? 30 : 36, margin: "8px 0 0", color: "var(--pp-ink)" }}>{lang === "zh" ? "心动花束" : "Bouquets we love"}</h2>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 14 }}>
        {items.map(p => (
          <article key={p.id} onClick={() => onPick(p.id)} className="pp-card" style={{ background: "var(--bg-card)", overflow: "hidden", border: "1px solid var(--hairline)", cursor: "pointer", position: "relative" }}>
            <div className="pp-card-img-wrap" style={{ aspectRatio: "4/5", position: "relative" }}>
              <div style={{ width: "100%", height: "100%", backgroundImage: `url(./assets/photos/${p.photo})`, backgroundSize: "cover", backgroundPosition: "center", filter: p.isSoldOut ? "grayscale(0.4)" : "none" }} />
            </div>
            <div style={{ padding: "10px 10px 14px" }}>
              <div style={{ fontFamily: ff, fontSize: 8, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink-mute)" }}>NO. {p.code}</div>
              <div style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 16 : 17, color: "var(--pp-ink)", margin: "4px 0 6px", lineHeight: 1.15 }}>{lang === "zh" ? p.name_zh : p.name_en}</div>
              <div style={{ fontFamily: ff, fontSize: 12, fontWeight: 700, color: p.isSoldOut || p.isCustom ? "var(--pp-ink-mute)" : "var(--pp-pink-deep)", letterSpacing: p.isSoldOut || p.isCustom ? "0.18em" : "normal" }}>
                {p.isSoldOut ? t.sold_out : p.isCustom ? t.custom_label : `S$ ${p.price}`}
              </div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

function MobileAbout({ t, lang }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  return (
    <section style={{ position: "relative", aspectRatio: "1942/809", backgroundImage: "url(./assets/photos/about-pink-banner.png)", backgroundSize: "cover", backgroundPosition: "center" }}>
      <div style={{ position: "absolute", inset: 0, padding: "0 18px", display: "flex", flexDirection: "column", justifyContent: "center", maxWidth: "62%" }}>
        <div style={{ fontFamily: ff, fontSize: 8, fontWeight: 600, letterSpacing: "0.28em", color: "var(--pp-pink-deep)" }}>{t.about_eyebrow}</div>
        <h2 style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 22 : 26, lineHeight: 1.1, margin: "8px 0 8px", whiteSpace: "pre-line", color: "var(--pp-ink)" }}>{t.about_title}</h2>
        <button style={{ alignSelf: "flex-start", marginTop: 6, fontFamily: ff, fontSize: 9, fontWeight: 700, letterSpacing: "0.22em", textTransform: lang === "zh" ? "none" : "uppercase", padding: "10px 16px", borderRadius: 0, border: 0, background: "var(--pp-ink)", color: "var(--bg)", cursor: "pointer" }}>{t.about_cta} →</button>
      </div>
    </section>
  );
}

function MobileFooter({ t, lang }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const linkStyle = { fontFamily: "var(--font-serif)", fontSize: 14, color: "var(--bg)", textDecoration: "none", display: "block", padding: "4px 0", opacity: 0.85 };
  const headStyle = { fontFamily: ff, fontSize: 10, fontWeight: 700, letterSpacing: "0.22em", color: "var(--pp-blush)", marginBottom: 10, textTransform: lang === "zh" ? "none" : "uppercase" };
  return (
    <footer style={{ background: "var(--pp-ink)", color: "var(--bg)", padding: "32px 18px 24px" }}>
      <div style={{ fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 22, color: "var(--pp-blush)", marginBottom: 4 }}>Passion's Petals</div>
      <div style={{ fontFamily: ff, fontSize: 9, letterSpacing: "0.32em", color: "var(--pp-blush)", opacity: 0.7, marginBottom: 22 }}>· EST 2026 ·</div>

      <div style={{ marginBottom: 22 }}>
        <div style={headStyle}>{t.foot_help}</div>
        <a href="https://t.me/papapassion" target="_blank" rel="noopener noreferrer" style={linkStyle}>Telegram</a>
        <a href="https://wa.me/6588956482" target="_blank" rel="noopener noreferrer" style={linkStyle}>WhatsApp</a>
      </div>

      <div style={{ display: "flex", gap: 16, alignItems: "center", marginBottom: 24 }}>
        <a href="https://t.me/passionpetalbouquet" target="_blank" rel="noopener noreferrer" title="Telegram" style={{ color: "var(--bg)", display: "inline-flex" }}><ICN.tg size={20} /></a>
        <a href="https://www.instagram.com/passionatelypetals" target="_blank" rel="noopener noreferrer" title="Instagram" style={{ color: "var(--bg)", display: "inline-flex" }}><ICN.ig size={20} /></a>
        <a href="https://www.tiktok.com/@passionatelypetals" target="_blank" rel="noopener noreferrer" title="TikTok" style={{ color: "var(--bg)", display: "inline-flex" }}><ICN.tt size={20} /></a>
        <a href="https://xhslink.com/m/6K4j40mHbQf" target="_blank" rel="noopener noreferrer" title="小红书" style={{ fontFamily: "var(--font-cn-sans)", fontSize: 12, fontWeight: 600, letterSpacing: "0.05em", color: "var(--bg)", textDecoration: "none" }}>小红书</a>
      </div>

      <div style={{ fontFamily: ff, fontSize: 10, opacity: 0.55 }}>{t.foot_legal}</div>
    </footer>
  );
}

function MobileBottomNav({ route, onNav, onCart, cartCount, lang }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const items = [
    { id: "home", icon: <ICN.flower size={20} />, en: "Home", zh: "首页" },
    { id: "shop", icon: <ICN.search size={20} />, en: "Shop", zh: "选购" },
    { id: "fav",  icon: <ICN.heart size={20} />,  en: "Saved", zh: "收藏" },
    { id: "cart", icon: <ICN.bag size={20} />,    en: "Cart", zh: "购物车", badge: cartCount },
  ];
  return (
    <nav style={{ position: "sticky", bottom: 0, background: "rgba(252,247,243,0.96)", backdropFilter: "blur(10px)", borderTop: "1px solid var(--hairline)", display: "grid", gridTemplateColumns: "repeat(4,1fr)", padding: "8px 0 calc(12px + env(safe-area-inset-bottom))", boxShadow: "0 -4px 14px rgba(58,40,24,0.06)", zIndex: 25 }}>
      {items.map(it => {
        const active = route === it.id;
        return (
          <button key={it.id} onClick={() => it.id === "cart" ? onCart() : onNav(it.id === "fav" ? "shop" : it.id)} style={{ background: "transparent", border: 0, cursor: "pointer", display: "flex", flexDirection: "column", alignItems: "center", gap: 3, color: active ? "var(--pp-pink-deep)" : "var(--pp-ink-soft)", position: "relative" }}>
            <div style={{ position: "relative" }}>
              {it.icon}
              {it.badge > 0 && <span style={{ ...cartBadgeM, top: -4, right: -8 }}>{it.badge}</span>}
            </div>
            <div style={{ fontFamily: ff, fontSize: 10, fontWeight: active ? 700 : 500, letterSpacing: "0.06em" }}>{lang === "zh" ? it.zh : it.en}</div>
          </button>
        );
      })}
    </nav>
  );
}

function MobilePDP({ p, t, lang, onAdd, onBack }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  const disp = lang === "zh" ? "var(--font-cn-display)" : "var(--font-display)";
  const photos = [p.photo, ...(p.alts || [])];
  const [idx, setIdx] = React.useState(0);
  const [size, setSize] = React.useState(p.sizes[0]);
  const [qty, setQty] = React.useState(1);
  const [note, setNote] = React.useState("");
  // Per-product wrap & ribbon options; products without a brief entry get "—" only.
  const wrapMap = (typeof window !== "undefined" && window.WRAP_RIBBON_BY_CODE) || {};
  const wrapEntry = wrapMap[p.code];
  const variants = wrapEntry ? (lang === "zh" ? wrapEntry.zh : wrapEntry.en) : ["—"];
  const [variant, setVariant] = React.useState(variants[0]);
  React.useEffect(() => { setVariant(variants[0]); }, [p.code, lang]);
  const unit = p.price + size.delta;
  const touchRef = React.useRef({ x: 0, y: 0, active: false });
  const onTouchStart = (e) => {
    const t = e.touches[0];
    touchRef.current = { x: t.clientX, y: t.clientY, active: true };
  };
  const onTouchEnd = (e) => {
    if (!touchRef.current.active || photos.length < 2) return;
    const t = e.changedTouches[0];
    const dx = t.clientX - touchRef.current.x;
    const dy = t.clientY - touchRef.current.y;
    touchRef.current.active = false;
    if (Math.abs(dx) < 40 || Math.abs(dx) < Math.abs(dy)) return;
    if (dx < 0) setIdx(i => (i + 1) % photos.length);
    else setIdx(i => (i - 1 + photos.length) % photos.length);
  };

  return (
    <div style={{ background: "var(--bg)" }}>
      <div style={{ position: "sticky", top: 0, zIndex: 20, background: "rgba(252,247,243,0.94)", backdropFilter: "blur(10px)", borderBottom: "1px solid var(--hairline)", padding: "10px 12px", display: "flex", alignItems: "center", gap: 10 }}>
        <button onClick={onBack} style={iconBtnM} aria-label="Back"><ICN.chevL size={20} /></button>
        <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.18em", color: "var(--pp-ink-soft)" }}>{t.pdp_breadcrumb}</div>
      </div>

      <div onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} style={{ position: "relative", aspectRatio: "4/5", background: "var(--pp-paper)", overflow: "hidden", touchAction: "pan-y" }}>
        <div key={idx} style={{ width: "100%", height: "100%", backgroundImage: `url(./assets/photos/${photos[idx]})`, backgroundSize: "cover", backgroundPosition: "center", animation: "pp-fade-in 360ms ease-out" }} />
        {photos.length > 1 && (
          <div style={{ position: "absolute", bottom: 14, left: 0, right: 0, display: "flex", gap: 8, justifyContent: "center" }}>
            {photos.map((_, i) => (
              <button key={i} onClick={() => setIdx(i)} style={{ width: i === idx ? 26 : 8, height: 8, borderRadius: 4, background: i === idx ? "var(--pp-pink-deep)" : "rgba(255,255,255,0.85)", boxShadow: "0 1px 3px rgba(0,0,0,0.2)", border: 0, padding: 0, cursor: "pointer", transition: "width 200ms" }} aria-label={`Photo ${i + 1}`} />
            ))}
          </div>
        )}
      </div>

      <div style={{ padding: "20px 18px 16px" }}>
        <div style={{ fontFamily: ff, fontSize: 9, fontWeight: 600, letterSpacing: "0.28em", color: "var(--pp-ink-mute)" }}>NO. {p.code} · {p.coll.toUpperCase()}</div>
        <h1 style={{ fontFamily: disp, fontWeight: 500, fontSize: lang === "zh" ? 28 : 32, margin: "6px 0 8px", color: "var(--pp-ink)", lineHeight: 1.1 }}>{lang === "zh" ? p.name_zh : p.name_en}</h1>
        {p.isSoldOut ? (
          <div style={{ fontFamily: ff, fontSize: 10, fontWeight: 600, letterSpacing: "0.18em", color: "var(--pp-ink-faint)", marginTop: 6, display: "inline-flex", alignItems: "center", gap: 4 }}>
            <span style={{ width: 6, height: 6, borderRadius: 3, background: "var(--pp-ink-faint)" }} />{t.sold_out}
          </div>
        ) : p.isCustom ? (
          <div style={{ fontFamily: ff, fontSize: 10, fontWeight: 600, letterSpacing: "0.18em", color: "var(--pp-pink-deep)", marginTop: 6, display: "inline-flex", alignItems: "center", gap: 4 }}>
            <span style={{ width: 6, height: 6, borderRadius: 3, background: "var(--pp-pink-deep)" }} />{t.custom_label}
          </div>
        ) : (
          <>
            <div style={{ fontFamily: ff, fontSize: 18, fontWeight: 700, color: "var(--pp-pink-deep)" }}>S$ {unit}</div>
            <div style={{ fontFamily: ff, fontSize: 10, fontWeight: 600, letterSpacing: "0.18em", color: "var(--pp-leaf, #6B7E55)", marginTop: 6, display: "inline-flex", alignItems: "center", gap: 4 }}>
              <span style={{ width: 6, height: 6, borderRadius: 3, background: "var(--pp-leaf, #6B7E55)" }} />{t.pdp_in_stock}
            </div>
          </>
        )}
        {p.isSoldOut && <p style={{ fontFamily: "var(--font-serif)", fontSize: 13, color: "var(--pp-ink-soft)", lineHeight: 1.6, marginTop: 12 }}>{t.pdp_sold_out_desc}</p>}
      </div>

      {!p.isCustom && !p.isSoldOut && (
        <div style={{ padding: "0 18px 16px" }}>
          <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink)", marginBottom: 10 }}>{(t.pdp_size || "Size").toUpperCase()}</div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 10 }}>
            {p.sizes.map(s => {
              const active = s.id === size.id;
              const dis = !!s.disabled;
              return (
                <button key={s.id} onClick={() => !dis && setSize(s)} disabled={dis} style={{
                  padding: "12px 10px", textAlign: "left", borderRadius: 10,
                  border: dis ? "1px dashed var(--pp-ink-faint)" : (active ? "2px solid var(--pp-pink-deep)" : "1px solid var(--hairline)"),
                  background: dis ? "var(--bg-card)" : (active ? "var(--pp-blush-faint, var(--pp-blush))" : "var(--bg-card)"),
                  cursor: dis ? "not-allowed" : "pointer",
                  opacity: dis ? 0.5 : 1,
                }}>
                  <div style={{ fontFamily: ff, fontSize: 13, fontWeight: 700, color: dis ? "var(--pp-ink-faint)" : "var(--pp-ink)" }}>{lang === "zh" ? s.label_zh : s.label_en}</div>
                  {!dis && <div style={{ fontFamily: "var(--font-serif)", fontSize: 12, color: "var(--pp-ink-soft)", marginTop: 2 }}>{lang === "zh" ? s.stems_zh : s.stems_en}</div>}
                  <div style={{ fontFamily: ff, fontSize: 12, fontWeight: 600, color: dis ? "var(--pp-ink-faint)" : "var(--pp-pink-deep)", marginTop: 4 }}>{dis ? (lang === "zh" ? "暫不販售" : "Unavailable") : `S$ ${p.price + s.delta}`}</div>
                </button>
              );
            })}
          </div>
        </div>
      )}

      {!p.isCustom && !p.isSoldOut && (
        <div style={{ padding: "0 18px 16px" }}>
          <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink)", marginBottom: 10 }}>{(t.pdp_variant || "Wrap & ribbon").toUpperCase()}</div>
          <select value={variant} onChange={e => setVariant(e.target.value)} disabled={variants.length <= 1} style={{
            width: "100%", boxSizing: "border-box", padding: "12px 14px", borderRadius: 10,
            border: "1px solid var(--hairline)", background: "var(--bg-card)",
            fontFamily: ff, fontSize: 14, color: "var(--pp-ink)",
            cursor: variants.length <= 1 ? "default" : "pointer", outline: "none",
            opacity: variants.length <= 1 ? 0.7 : 1,
          }}>
            {variants.map(v => <option key={v}>{v}</option>)}
          </select>
        </div>
      )}

      {!p.isCustom && !p.isSoldOut && (
        <div style={{ padding: "0 18px 16px" }}>
          <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink)", marginBottom: 10 }}>{(t.pdp_card_t || "Gift Card").toUpperCase()}</div>
          <textarea value={note} onChange={e => setNote(e.target.value)} placeholder={t.pdp_card_p} rows={3} style={{ width: "100%", boxSizing: "border-box", padding: "10px 12px", borderRadius: 10, border: "1px solid var(--hairline)", background: "var(--bg-card)", fontFamily: "var(--font-serif)", fontSize: 13, color: "var(--pp-ink)", resize: "none" }} />
        </div>
      )}

      <div style={{ background: "var(--pp-paper-soft)", margin: "12px 0", padding: "16px 18px", borderTop: "1px solid var(--hairline)", borderBottom: "1px solid var(--hairline)" }}>
        <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink)", marginBottom: 8 }}>{(t.pdp_seasonal_t || "Seasonal").toUpperCase()}</div>
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 13, lineHeight: 1.55, color: "var(--pp-ink-soft)" }}>{t.pdp_seasonal_d}</div>
      </div>

      <div style={{ padding: "0 18px 24px" }}>
        <div style={{ fontFamily: ff, fontSize: 11, fontWeight: 600, letterSpacing: "0.22em", color: "var(--pp-ink)", marginBottom: 10 }}>{(t.pdp_delivery || "Delivery").toUpperCase()}</div>
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 13, lineHeight: 1.7, color: "var(--pp-ink-soft)" }}>
          • {t.pdp_pickup}<br />• {t.pdp_delivery_fee}
        </div>
      </div>

      {/* Sticky CTA — disabled for sold-out, Telegram link for custom, normal add-to-cart otherwise. */}
      <div style={{ position: "sticky", bottom: 0, background: "rgba(252,247,243,0.96)", backdropFilter: "blur(10px)", borderTop: "1px solid var(--hairline)", padding: "12px 16px calc(18px + env(safe-area-inset-bottom))", display: "flex", gap: 10, alignItems: "center", zIndex: 22 }}>
        {p.isSoldOut ? (
          <button disabled style={{ flex: 1, fontFamily: ff, fontSize: 12, fontWeight: 700, letterSpacing: "0.22em", padding: "14px 18px", borderRadius: 0, border: 0, background: "var(--pp-ink-faint)", color: "#fff", cursor: "not-allowed", textTransform: lang === "zh" ? "none" : "uppercase" }}>{t.not_available}</button>
        ) : p.isCustom ? (
          <a href="https://t.me/papapassion" target="_blank" rel="noopener noreferrer" style={{ flex: 1, textAlign: "center", textDecoration: "none", fontFamily: ff, fontSize: 12, fontWeight: 700, letterSpacing: "0.22em", padding: "14px 18px", borderRadius: 0, background: "var(--pp-pink-deep)", color: "#fff", textTransform: lang === "zh" ? "none" : "uppercase" }}>{t.custom_cta}</a>
        ) : (
          <>
            <div style={{ display: "inline-flex", alignItems: "center", gap: 0, border: "1px solid var(--hairline)", borderRadius: 999, background: "var(--bg-card)" }}>
              <button onClick={() => setQty(Math.max(1, qty - 1))} style={qtyBtnM} aria-label="-"><ICN.minus size={14} /></button>
              <div style={{ minWidth: 22, textAlign: "center", fontFamily: ff, fontSize: 14, fontWeight: 700 }}>{qty}</div>
              <button onClick={() => setQty(qty + 1)} style={qtyBtnM} aria-label="+"><ICN.plus size={14} /></button>
            </div>
            <button onClick={() => onAdd(p, { size, qty, variant, note, unitPrice: unit })} style={{
              flex: 1, fontFamily: ff, fontSize: 12, fontWeight: 700, letterSpacing: "0.22em", textTransform: lang === "zh" ? "none" : "uppercase",
              padding: "14px 18px", borderRadius: 0, border: 0, background: "var(--pp-pink-deep)", color: "#fff", cursor: "pointer",
            }}>{t.pdp_add} · S$ {unit * qty}</button>
          </>
        )}
      </div>
    </div>
  );
}

function MobileSideMenu({ open, onClose, t, lang, onNav, onPickCollection }) {
  const ff = lang === "zh" ? "var(--font-cn-sans)" : "var(--font-sans)";
  // Top-level nav. "contact" is an external link to Passion's Telegram instead of an internal route.
  const topItems = [
    { kind: "nav", id: "home", label: t.nav.home },
    { kind: "nav", id: "shop", label: t.nav.shop },
    { kind: "nav", id: "collections", label: t.nav.collections },
    { kind: "ext", href: "https://t.me/papapassion", label: t.nav.contact },
  ];
  const collItems = COLLECTIONS.map(c => ({ kind: "coll", slug: c.slug, label: lang === "zh" ? c.name_zh : c.name_en }));
  const items = [...topItems, ...collItems];
  return (
    <>
      {open && <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(58,40,24,0.32)", zIndex: 40 }} />}
      <aside style={{ position: "fixed", top: 0, left: 0, bottom: 0, width: 300, maxWidth: "85vw", background: "var(--bg)", zIndex: 41, transform: open ? "translateX(0)" : "translateX(-100%)", transition: "transform 280ms cubic-bezier(0.22,0.61,0.36,1)", boxShadow: open ? "var(--shadow-3)" : "none", display: "flex", flexDirection: "column" }}>
        <div style={{ padding: "20px 20px 14px", display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid var(--hairline)" }}>
          <span style={{ fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 22, color: "var(--pp-pink-deep)" }}>Menu</span>
          <button onClick={onClose} style={iconBtnM} aria-label="Close"><ICN.x size={20} /></button>
        </div>
        <nav style={{ padding: "8px 0", flex: 1 }}>
          {items.map((it, i) => {
            const sharedStyle = { display: "block", padding: "16px 20px", fontFamily: ff, fontSize: lang === "zh" ? 16 : 14, fontWeight: 600, letterSpacing: lang === "zh" ? "0.06em" : "0.18em", textTransform: lang === "zh" ? "none" : "uppercase", color: it.kind === "coll" ? "var(--pp-pink-deep)" : "var(--pp-ink)", borderBottom: "1px solid var(--hairline)", cursor: "pointer", textDecoration: "none" };
            if (it.kind === "ext") {
              return <a key={i} href={it.href} target="_blank" rel="noopener noreferrer" onClick={onClose} style={sharedStyle}>{it.label}</a>;
            }
            return <a key={i} onClick={() => { it.kind === "coll" ? onPickCollection(it.slug) : onNav(it.id); onClose(); }} style={sharedStyle}>{it.label}</a>;
          })}
        </nav>
      </aside>
    </>
  );
}

// MobileApp — receives all state from <App/> so cart/lang persist across breakpoint switches.
function MobileApp({ lang, setLang, t, route, setRoute, activeId, setActiveId, activeCollection, setActiveCollection, cart, addToCart, cartOpen, setCartOpen }) {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const product = activeId ? PRODUCTS.find(p => p.id === activeId) : null;
  const cartCount = cart.reduce((s, it) => s + it.qty, 0);

  const prevRouteRef = React.useRef("home");
  const prevScrollRef = React.useRef(0);
  const pick = id => {
    if (route !== "product") {
      prevRouteRef.current = route;
      prevScrollRef.current = window.scrollY;
    }
    window.__ppPushNav && window.__ppPushNav({ route: "product", activeId: id, activeCollection });
    setActiveId(id);
    setRoute("product");
    window.scrollTo({ top: 0 });
  };
  const pickCollection = slug => {
    window.__ppPushNav && window.__ppPushNav({ route: "collection", activeId: null, activeCollection: slug });
    setActiveCollection(slug);
    setActiveId(null);
    setRoute("collection");
    window.scrollTo({ top: 0 });
  };
  const back = () => {
    // Delegate to browser history so the back arrow matches the browser back button.
    if (window.history.length > 1) {
      window.history.back();
    } else {
      setRoute(prevRouteRef.current || "home");
      setActiveId(null);
      requestAnimationFrame(() => window.scrollTo({ top: prevScrollRef.current || 0 }));
    }
  };
  const nav = id => {
    window.__ppPushNav && window.__ppPushNav({ route: id, activeId: null, activeCollection });
    setRoute(id);
    setActiveId(null);
    window.scrollTo({ top: 0 });
  };

  let content;
  if (route === "product" && product) {
    content = <MobilePDP p={product} t={t} lang={lang} onAdd={addToCart} onBack={back} />;
  } else if (route === "collection" && activeCollection) {
    content = (
      <>
        <MobileTopBar t={t} lang={lang} setLang={setLang} onMenu={() => setMenuOpen(true)} onCart={() => setCartOpen(true)} cartCount={cartCount} onSearch={() => nav("shop")} />
        <MobileCollectionPage t={t} lang={lang} slug={activeCollection} onPick={pick} />
        <MobileFooter t={t} lang={lang} />
      </>
    );
  } else if (route === "collections") {
    content = (
      <>
        <MobileTopBar t={t} lang={lang} setLang={setLang} onMenu={() => setMenuOpen(true)} onCart={() => setCartOpen(true)} cartCount={cartCount} onSearch={() => nav("shop")} />
        <MobileCollectionsIndex t={t} lang={lang} onPickCollection={pickCollection} />
        <MobileFooter t={t} lang={lang} />
      </>
    );
  } else if (route === "shop") {
    content = (
      <>
        <MobileTopBar t={t} lang={lang} setLang={setLang} onMenu={() => setMenuOpen(true)} onCart={() => setCartOpen(true)} cartCount={cartCount} onSearch={() => nav("shop")} />
        <MobileGrid t={t} lang={lang} onPick={pick} />
        <MobileFooter t={t} lang={lang} />
      </>
    );
  } else {
    content = (
      <>
        <MobileTopBar t={t} lang={lang} setLang={setLang} onMenu={() => setMenuOpen(true)} onCart={() => setCartOpen(true)} cartCount={cartCount} onSearch={() => nav("shop")} />
        <MobileHero t={t} lang={lang} onShop={() => nav("shop")} />
        <MobileFeatures t={t} lang={lang} />
        <MobileCollections t={t} lang={lang} onPickCollection={pickCollection} />
        <MobileGrid t={t} lang={lang} onPick={pick} limit={6} />
        <MobileAbout t={t} lang={lang} />
        <MobileFooter t={t} lang={lang} />
      </>
    );
  }

  return (
    <div style={{ width: "100%", minHeight: "100vh", background: "var(--bg)", position: "relative" }}>
      {content}
      <MobileBottomNav route={route} onNav={nav} onCart={() => setCartOpen(true)} cartCount={cartCount} lang={lang} />
      <MobileSideMenu open={menuOpen} onClose={() => setMenuOpen(false)} t={t} lang={lang} onNav={nav} onPickCollection={pickCollection} />
    </div>
  );
}

window.MobileApp = MobileApp;
