// TAHAANN home page — light imagery-led layout
const { BookCard } = window.TAHANDesignSystem_a07997;
const { ShopByCategory, ShelfSection, Reviews } = window;

const WRAP = { maxWidth: "1280px", margin: "0 auto", padding: "0 24px" };
const svg = (children, size = 24, sw = 1.6) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" aria-hidden>{children}</svg>;

function Hero({ banners }) {
  const list = banners || [];
  const [i, setI] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const touchX = React.useRef(null);
  React.useEffect(() => {
    if (paused || !list.length) return;
    const t = setTimeout(() => setI((n) => (n + 1) % list.length), 6500);
    return () => clearTimeout(t);
  }, [i, paused, list.length]);
  const go = (n) => setI((n + list.length) % list.length);
  // Banners come from Firestore with no seed behind them, so the first paint
  // and any all-blocked state have an empty list — b would be undefined and
  // reading b.id below would throw, taking the whole home page down.
  React.useEffect(() => { if (i >= list.length) setI(0); }, [list.length, i]);
  if (!list.length) return null;
  const b = list[i % list.length];
  const handleTouchStart = (e) => { touchX.current = e.touches[0].clientX; };
  const handleTouchEnd = (e) => {
    if (touchX.current == null) return;
    const dx = e.changedTouches[0].clientX - touchX.current;
    touchX.current = null;
    if (list.length > 1 && Math.abs(dx) > 40) go(dx < 0 ? 1 : -1);
  };
  return (
    <section onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)} onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd} style={{ ...WRAP, paddingTop: "28px" }}>
      <div style={{ position: "relative", borderRadius: "var(--radius-lg)", overflow: "hidden", background: "linear-gradient(105deg, #FFFFFF 0%, var(--neutral-100) 100%)" }}>
        <div key={b.id} className="tahan-hero-grid tahan-banner-in" style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1.1fr)", alignItems: "center" }}>
          <div style={{ padding: "clamp(28px, 3.6vw, 56px)" }}>
            {b.eyebrow ? <div style={{ fontFamily: "var(--font-ui)", fontSize: "11.5px", fontWeight: 700, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--coral)", marginBottom: "16px" }}>{b.eyebrow}</div> : null}
            {b.title ? <h1 style={{ fontFamily: "var(--font-display)", fontWeight: 800, fontSize: "clamp(1.45rem, 2.6vw, 2.3rem)", lineHeight: 1.15, letterSpacing: "-0.015em", textTransform: "uppercase", color: "var(--navy)", margin: 0, textWrap: "balance" }}>{b.title}</h1> : null}
            {b.body ? <p style={{ fontFamily: "var(--font-ui)", fontWeight: 400, fontSize: "clamp(0.95rem, 1.1vw, 1.05rem)", lineHeight: 1.65, color: "var(--text-muted)", margin: "18px 0 0", maxWidth: "40ch" }}>{b.body}</p> : null}
            <a href={b.link || "Shop.html"} style={{ display: "inline-flex", alignItems: "center", gap: "14px", marginTop: "30px", cursor: "pointer", border: "none", background: "var(--coral)", color: "#FFFFFF", fontFamily: "var(--font-ui)", fontWeight: 600, fontSize: "16px", padding: "10px 10px 10px 26px", borderRadius: "var(--radius-pill)", textDecoration: "none", transition: "background var(--dur-fast) var(--ease-standard)" }} onMouseEnter={(e) => { e.currentTarget.style.background = "var(--coral-deep)"; }} onMouseLeave={(e) => { e.currentTarget.style.background = "var(--coral)"; }}>
              Start browsing
              <span aria-hidden style={{ width: "34px", height: "34px", borderRadius: "999px", background: "#FFFFFF", color: "var(--coral)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: "15px", flexShrink: 0 }}>›</span>
            </a>
          </div>
          <div className="tahan-hero-art" style={{ position: "relative", aspectRatio: "16 / 9", background: b.tint }}>
            <image-slot id={`tahan-banner-${b.id}`} shape="rect" fit="cover" placeholder={`Drop banner ${i + 1} image`} src={b.img || ""}></image-slot>
          </div>
        </div>
        <div style={{ position: "absolute", bottom: "20px", left: 0, right: 0, display: "flex", justifyContent: "center", gap: "10px" }}>
          {list.map((s, n) => (
            <button key={s.id} onClick={() => go(n)} aria-label={`Banner ${n + 1}`} style={{ width: n === i ? "30px" : "10px", height: "10px", borderRadius: "999px", cursor: "pointer", border: "none", padding: 0, background: n === i ? "var(--coral)" : "rgba(11,31,58,0.24)", transition: "width var(--dur-med) var(--ease-standard), background var(--dur-med) var(--ease-standard)" }}></button>
          ))}
        </div>
      </div>
    </section>
  );
}

function TrustBar() {
  const items = [
    { t: "Sourced at the District", s: "Direct from makers", i: <><path d="M12 21s7-6.3 7-11a7 7 0 1 0-14 0c0 4.7 7 11 7 11z" /><circle cx="12" cy="10" r="2.5" /></> },
    { t: "Secure Packaging", s: "Safe Delivery", i: <><path d="M21 8V5l-9-3-9 3v3M3 8l9 3 9-3M3 8v8l9 3 9-3V8M12 11v10" /></> },
    { t: "Easy Returns", s: "Hassle Free", i: <><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><path d="M3 3v5h5" /></> },
    { t: "Support Bengali Makers", s: "Read, taste & wear", i: <><path d="M11 4a4 4 0 0 0-4 4c0 5 4 9 4 9s4-4 4-9a4 4 0 0 0-4-4z" /><path d="M11 17c-1 2-3 3-6 3M11 17c1 2 3 3 6 3" /></> },
  ];
  return (
    <section style={{ background: "var(--cream-100)", borderTop: "1px solid var(--border-hairline)", borderBottom: "1px solid var(--border-hairline)" }}>
      <div style={{ ...WRAP, display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "24px", padding: "26px 24px" }} className="tahan-trust-grid">
        {items.map((it) => (
          <div key={it.t} style={{ display: "flex", alignItems: "center", gap: "14px" }}>
            <span style={{ color: "var(--forest-700)", flexShrink: 0 }}>{svg(it.i, 30, 1.4)}</span>
            <span>
              <span style={{ display: "block", fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "15px", color: "var(--text-heading)", lineHeight: 1.2 }}>{it.t}</span>
              <span style={{ display: "block", fontFamily: "var(--font-ui)", fontSize: "12.5px", color: "var(--text-muted)", marginTop: "2px" }}>{it.s}</span>
            </span>
          </div>
        ))}
      </div>
    </section>
  );
}

function BookRow({ books, saved, toggleSave, addToCart }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "28px", marginTop: "24px" }} className="tahan-book-grid">
      {books.map((b) => (
        <a key={b.id} href={`Product?id=${b.id}`} style={{ display: "block", textDecoration: "none", cursor: "pointer" }} aria-label={b.title || b.titleBn}>
          <div onClick={(e) => e.preventDefault()}>
            <BookCard {...b} saved={!!saved[b.id]} onToggleSave={() => toggleSave(b.id)} onAdd={() => addToCart(b.id)} />
          </div>
        </a>
      ))}
    </div>
  );
}

const BOOK_TABS = [
  { key: "new", label: "New Releases" },
  { key: "best", label: "Bestsellers" },
  { key: "classics", label: "Classics" },
  { key: "Fiction", label: "Fiction" },
  { key: "Nonfiction", label: "Nonfiction" },
  { key: "Thriller", label: "Thriller" },
  { key: "Horror", label: "Horror" },
];

function bookTabList(books, key) {
  if (key === "new") return [...books].sort((a, b) => (b.badge && b.badge.tone === "new" ? 1 : 0) - (a.badge && a.badge.tone === "new" ? 1 : 0));
  if (key === "best") return [...books].sort((a, b) => b.ratingCount - a.ratingCount);
  if (key === "classics") return [...books].sort((a, b) => a.year - b.year);
  return books.filter((b) => b.genre === key);
}

function ShelfCard({ b, saved, toggleSave, addToCart, ratio = "2 / 3" }) {
  return (
    <article className="tahan-shelf-card" style={{ background: "var(--surface-card)", borderRadius: "10px", padding: "14px 14px 18px", display: "flex", flexDirection: "column", textAlign: "left" }}>
      <a href={`Product?id=${b.id}`} aria-label={b.title || b.titleBn} style={{ position: "relative", aspectRatio: ratio, borderRadius: "4px", overflow: "hidden", background: "var(--cream-200)", boxShadow: "var(--shadow-book)", display: "block", textDecoration: "none" }}>
        <image-slot id={`tahan-cover-${b.id}`} shape="rect" fit="cover" placeholder="Drop cover" src={b.image || b.cover || ""}></image-slot>
      </a>
      <a href={`Product?id=${b.id}`} style={{ fontFamily: "var(--font-bengali)", fontWeight: 700, fontSize: "16px", lineHeight: 1.3, color: "var(--navy)", marginTop: "16px", textDecoration: "none", display: "block" }}>{b.titleBn}</a>
      <div style={{ fontFamily: "var(--font-bengali)", fontSize: "12.5px", color: "var(--text-muted)", marginTop: "5px" }}>{b.authorBn}</div>
      <div style={{ display: "flex", alignItems: "baseline", gap: "8px", marginTop: "12px" }}>
        <span style={{ fontFamily: "var(--font-ui)", fontWeight: 600, fontSize: "16px", color: "var(--text-body)" }}>₹{b.price.toLocaleString("en-IN")}</span>
        {b.original && <span style={{ fontFamily: "var(--font-ui)", fontSize: "12.5px", color: "var(--text-muted)", textDecoration: "line-through" }}>₹{b.original.toLocaleString("en-IN")}</span>}
      </div>
      <div style={{ marginTop: "10px" }}><span style={{ display: "inline-flex", alignItems: "center", gap: "6px", color: "var(--navy)", fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 700 }}><span aria-hidden style={{ color: "var(--saffron)", fontSize: "13px", lineHeight: 1 }}>★</span>{b.rating.toFixed(1)} ({b.ratingCount})</span></div>
      <div style={{ display: "flex", gap: "8px", marginTop: "16px" }}>
        <button onClick={() => addToCart(b.id)} style={{ flex: 1, cursor: "pointer", border: "none", borderRadius: "6px", background: "var(--navy)", color: "#FFFFFF", fontFamily: "var(--font-ui)", fontSize: "12.5px", fontWeight: 700, padding: "10px 8px" }}>Add to cart</button>
        <button onClick={() => toggleSave(b.id)} aria-label={saved ? "Remove from wishlist" : "Save to wishlist"} style={{ width: "38px", cursor: "pointer", borderRadius: "6px", border: "1px solid var(--border-hairline)", background: "transparent", color: saved ? "var(--coral)" : "var(--text-muted)", display: "flex", alignItems: "center", justifyContent: "center" }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill={saved ? "currentColor" : "none"} stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" aria-hidden><path d="M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1a5.5 5.5 0 1 0-7.8 7.8L12 21l8.8-8.5a5.5 5.5 0 0 0 0-7.9z" /></svg>
        </button>
      </div>
    </article>
  );
}

function BengaliBooks({ data, saved, toggleSave, addToCart }) {
  const [tab, setTab] = React.useState("new");
  const [all, setAll] = React.useState(false);
  const full = bookTabList(data.books, tab);
  const books = all ? full : full.slice(0, 4);
  return (
    <section style={{ ...WRAP, paddingTop: "72px" }}>
      <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: "24px", flexWrap: "wrap" }}>
        <h2 style={{ fontFamily: "var(--font-ui)", fontWeight: 800, fontSize: "20px", letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--navy)", margin: 0 }}>Bengali Books</h2>
        <a href={window.tahanShopHref("books")} style={{ fontFamily: "var(--font-ui)", fontWeight: 700, fontSize: "13px", color: "var(--brand-secondary)", textDecoration: "none", whiteSpace: "nowrap" }}>View All →</a>
      </div>
      <div style={{ display: "flex", gap: "26px", flexWrap: "wrap", marginTop: "20px", borderBottom: "1px solid rgba(11,31,58,0.18)" }}>
        {BOOK_TABS.map((t) => {
          const on = tab === t.key;
          return (
            <button key={t.key} onClick={() => { setTab(t.key); setAll(false); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "0 0 12px", fontFamily: "var(--font-ui)", fontSize: "13.5px", fontWeight: on ? 800 : 600, color: on ? "var(--brand-secondary)" : "var(--navy)", borderBottom: on ? "3px solid var(--coral)" : "3px solid transparent", marginBottom: "-1px" }}>{t.label}</button>
          );
        })}
      </div>
      {books.length ? (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "20px", marginTop: "28px" }} className="tahan-shelf-grid">
          {books.map((b) => <ShelfCard key={b.id} b={b} ratio="3 / 3.2" saved={!!saved[b.id]} toggleSave={toggleSave} addToCart={addToCart} />)}
        </div>
      ) : (
        <p style={{ fontFamily: "var(--font-ui)", color: "var(--text-muted)", marginTop: "28px" }}>No titles in this shelf yet — more arriving soon.</p>
      )}
    </section>
  );
}

function FilterChip({ label, on, onClick }) {
  return (
    <button onClick={onClick} style={{ cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, padding: "8px 16px", borderRadius: "var(--radius-pill)", border: "1px solid " + (on ? "var(--forest-800)" : "var(--border-strong)"), background: on ? "var(--forest-800)" : "transparent", color: on ? "var(--cream-100)" : "var(--text-body)", transition: "background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard)" }}>{label}</button>
  );
}

const fmtDate = (s) => {
  const d = new Date(s);
  return isNaN(d.getTime()) ? s : d.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
};

function CouponCard({ c }) {
  const [copied, setCopied] = React.useState(false);
  const copy = () => {
    try {
      navigator.clipboard.writeText(c.code);
      setCopied(true);
      setTimeout(() => setCopied(false), 1600);
    } catch (e) { /* clipboard unavailable — the code stays visible to type */ }
  };
  const save = c.type === "percent" ? `Save ${c.value}%` : `Save ₹${Number(c.value).toLocaleString("en-IN")}`;
  const terms = [c.min ? `on orders above ₹${c.min.toLocaleString("en-IN")}` : "on any order", c.freeShip ? "+ free shipping" : ""].filter(Boolean).join(" ");
  return (
    <div style={{ display: "flex", alignItems: "center", gap: "16px", flexWrap: "wrap", background: "#FFFFFF", borderRadius: "var(--radius-md)", borderLeft: "5px solid var(--saffron)", padding: "16px 18px" }}>
      <div style={{ flex: 1, minWidth: "170px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: "10px", flexWrap: "wrap" }}>
          <span style={{ background: "var(--saffron)", color: "var(--navy)", fontFamily: "var(--font-ui)", fontSize: "11.5px", fontWeight: 700, padding: "4px 10px", borderRadius: "var(--radius-pill)", whiteSpace: "nowrap" }}>{save}</span>
          <span style={{ fontFamily: "var(--font-ui)", fontSize: "13px", color: "var(--text-body)" }}>{terms}</span>
        </div>
        {c.expires && <div style={{ fontFamily: "var(--font-ui)", fontSize: "12px", color: "var(--text-muted)", marginTop: "8px" }}>Valid till {fmtDate(c.expires)}</div>}
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: "10px", border: "1.5px dashed var(--saffron-deep)", background: "var(--saffron-tint)", borderRadius: "var(--radius-sm)", padding: "7px 8px 7px 14px" }}>
        <span style={{ fontFamily: "var(--font-ui)", fontWeight: 800, fontSize: "14px", letterSpacing: "0.08em", color: "var(--navy)" }}>{c.code}</span>
        <button onClick={copy} style={{ display: "inline-flex", alignItems: "center", gap: "5px", cursor: "pointer", border: "none", background: "#FFFFFF", color: "var(--coral-deep)", fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 700, padding: "6px 12px", borderRadius: "var(--radius-pill)", whiteSpace: "nowrap" }}>
          {copied ? "Copied" : "Copy"}
        </button>
      </div>
    </div>
  );
}

// Offers band — renders whatever live coupons the catalogue carries. Renders
// nothing at all when there are none, so the homepage never shows an empty promo.
function OffersBand({ data }) {
  const today = new Date().setHours(0, 0, 0, 0);
  const coupons = ((data && data.coupons) || []).filter((c) => {
    // Only the home page is gated on this flag — checkout still resolves and
    // lists every live code, so an unadvertised coupon stays redeemable.
    if (c.showOnHomepage !== true) return false;
    if (!c.code || c.status === "expired" || c.status === "disabled") return false;
    // Never advertise a code the checkout would turn away.
    const ends = c.expires ? new Date(c.expires).setHours(0, 0, 0, 0) : NaN;
    return isNaN(ends) || ends >= today;
  });
  if (!coupons.length) return null;
  return (
    <section style={{ ...WRAP, paddingTop: "80px" }}>
      <div className="tahan-offers-grid" style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1.25fr)", gap: "36px", alignItems: "center", background: "linear-gradient(105deg, var(--coral-deep) 0%, var(--coral) 100%)", borderRadius: "var(--radius-lg)", padding: "clamp(28px, 3.4vw, 44px)" }}>
        <div>
          <span style={{ display: "inline-block", background: "rgba(255,255,255,0.22)", color: "#FFFFFF", fontFamily: "var(--font-ui)", fontSize: "11px", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", padding: "6px 14px", borderRadius: "var(--radius-pill)" }}>Offers</span>
          <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 800, fontSize: "clamp(1.5rem, 2.4vw, 2.1rem)", lineHeight: 1.15, color: "#FFFFFF", margin: "16px 0 0" }}>Save on Your Order</h2>
          <p style={{ fontFamily: "var(--font-ui)", fontSize: "15px", lineHeight: 1.65, color: "rgba(255,255,255,0.9)", margin: "12px 0 0", maxWidth: "42ch" }}>Copy a code and enter it at checkout — the discount is applied to your bag before you pay.</p>
          <a href="Shop.html" style={{ display: "inline-flex", alignItems: "center", gap: "8px", marginTop: "26px", background: "#FFFFFF", color: "var(--coral-deep)", fontFamily: "var(--font-ui)", fontWeight: 700, fontSize: "14px", padding: "14px 26px", borderRadius: "var(--radius-pill)", textDecoration: "none" }}>Start shopping <span aria-hidden>→</span></a>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: "14px" }}>
          {coupons.map((c) => <CouponCard key={c.id || c.code} c={c} />)}
        </div>
      </div>
    </section>
  );
}

// Full-width banner carousel that sits below the Books shelf.
function CollectionBanner({ data }) {
  // Slides are the Advertisements collection (db.js -> TAHAN_DATA.ads). The
  // frame, ratio, autoplay, hover-pause and dots are unchanged from the
  // collection carousel this replaced; only the source of the slides moved.
  const items = (data && data.ads) || [];
  const [i, setI] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  React.useEffect(() => {
    if (paused || items.length < 2) return;
    const t = setTimeout(() => setI((n) => (n + 1) % items.length), 6500);
    return () => clearTimeout(t);
  }, [i, paused, items.length]);
  // An out-of-range index would blank the carousel if an ad is removed while
  // the page is open, so clamp instead of trusting the previous position.
  React.useEffect(() => { if (i >= items.length) setI(0); }, [items.length, i]);
  if (!items.length) return null;
  const c = items[i % items.length];
  return (
    <section style={{ ...WRAP, paddingTop: "80px" }} onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      <a href={c.link || "Shop.html"} className="tahan-collection-banner" style={{ position: "relative", display: "block", aspectRatio: "21 / 9", borderRadius: "var(--radius-lg)", overflow: "hidden", background: "var(--navy)", textDecoration: "none" }}>
        <img key={c.id} className="tahan-banner-in" src={c.img} alt={c.name || "Advertisement"} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
      </a>
      {items.length > 1 && (
        <div style={{ display: "flex", justifyContent: "center", gap: "9px", marginTop: "18px" }}>
          {items.map((s, n) => (
            <button key={s.id} onClick={() => setI(n)} aria-label={`${s.name || "Advertisement"} banner`} style={{ width: n === i ? "26px" : "9px", height: "9px", borderRadius: "999px", cursor: "pointer", border: "none", padding: 0, background: n === i ? "var(--coral)" : "rgba(11,31,58,0.22)", transition: "width var(--dur-med) var(--ease-standard), background var(--dur-med) var(--ease-standard)" }}></button>
          ))}
        </div>
      )}
    </section>
  );
}

function App() {
  const data = window.useTahanData ? window.useTahanData() : window.TAHAN_DATA;
  const [saved, setSaved] = useWishlist();
  const [cart, setCart] = useCart();
  const [drawer, setDrawer] = React.useState(false);
  const [genre, setGenre] = React.useState(null);
  const [toast, setToast] = React.useState("");
  const toastTimer = React.useRef();
  const flash = (msg) => { setToast(msg); clearTimeout(toastTimer.current); toastTimer.current = setTimeout(() => setToast(""), 2200); };
  const find = (id) => data.catalog.find((x) => x.id === id);

  const toggleSave = (id) => setSaved((s) => { const n = { ...s }; if (n[id]) { delete n[id]; flash("Removed from wishlist"); } else { n[id] = true; flash("Saved to your wishlist"); } return n; });
  const addToCart = (id) => { setCart((c) => ({ ...c, [id]: (c[id] || 0) + 1 })); flash(`Added "${find(id).title}" to your bag`); };
  const inc = (id) => setCart((c) => ({ ...c, [id]: (c[id] || 0) + 1 }));
  const dec = (id) => setCart((c) => { const n = { ...c }; n[id] = (n[id] || 1) - 1; if (n[id] <= 0) delete n[id]; return n; });
  const remove = (id) => setCart((c) => { const n = { ...c }; delete n[id]; return n; });

  const cartCount = Object.values(cart).reduce((s, q) => s + q, 0);
  const wishCount = Object.keys(saved).length;
  const rowProps = { saved, toggleSave, addToCart };
  // Shelves follow the database categories — one section per category that has stock.
  const shelves = (data.groups || []).filter((g) => g.key !== "books" || !data.books.length).map((g) => ({
    key: g.key, label: g.label, items: data.products.filter((p) => p.cat === g.key),
  })).filter((g) => g.items.length);
  // The offers band sits after the Darjeeling Tea shelf. Live category keys are
  // slugified ("darjeeling-tea") while the seed uses "tea", so match on either;
  // with no tea shelf at all it falls in after the last one.
  const teaIdx = shelves.findIndex((g) => /tea/i.test(g.key) || /tea/i.test(g.label || ""));
  const bandAfter = teaIdx >= 0 ? teaIdx : shelves.length - 1;
  // The collection banner follows the Books shelf, matched the same tolerant way.
  const booksIdx = shelves.findIndex((g) => /book/i.test(g.key) || /book/i.test(g.label || ""));

  return (
    <div>
      <Header cartCount={cartCount} wishCount={wishCount} onCart={() => setDrawer(true)} />
      <Hero banners={data.banners} />
      <div id="sec-categories"><ShopByCategory data={data} /></div>
      {!!data.books.length && <div id="sec-books" style={{ marginTop: "84px", padding: "6px 0 76px" }}><BengaliBooks data={data} {...rowProps} /></div>}
      {shelves.map((g, i) => (
        <React.Fragment key={g.key}>
          <ShelfSection id={`sec-${g.key}`} shopCat={g.key} title={g.label} tint={i % 2 ? "var(--powder-100)" : "var(--beige)"} items={g.items} rowProps={rowProps} />
          {i === bandAfter && <OffersBand data={data} />}
          {i === booksIdx && <CollectionBanner data={data} />}
        </React.Fragment>
      ))}
      <Reviews data={data} />
      <HomeFaq data={data} />
      <TrustBar />
      <Footer />
      <CartDrawer open={drawer} onClose={() => setDrawer(false)} items={cart} data={data} inc={inc} dec={dec} remove={remove} />
      <Toast msg={toast} />
    </div>
  );
}

function HomeFaq({ data }) {
  // Questions and answers come only from Firestore, via the existing realtime layer
  // in tahan/db.js (which already listens to both `faq` and `faqs` and writes the
  // merged, visibility-filtered, order-sorted list to TAHAN_DATA.faqs). There is no
  // hardcoded fallback: showing invented questions when the real ones are missing
  // would put words in the shop's mouth.
  const faqs = (data && data.faqs) || [];
  const loading = !window.TAHAN_DATA_SOURCE;
  const [open, setOpen] = React.useState(0);
  // The footer's FAQ link points here (Home.html#sec-faq). Firestore lands after
  // first paint, so the browser's own jump to the anchor happens while this
  // section is still a skeleton — scroll once the questions are actually in.
  const faqRef = React.useRef(null);
  const jumped = React.useRef(false);
  React.useEffect(() => {
    if (jumped.current || !faqs.length) return;
    if (window.location.hash !== "#sec-faq") return;
    jumped.current = true;
    if (faqRef.current) faqRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
  }, [faqs.length]);

  if (loading) {
    return (
      <section style={{ background: "var(--beige)" }}>
        <div style={{ maxWidth: "940px", margin: "0 auto", padding: "72px 24px 76px" }}>
          <div style={{ fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--gold-500, var(--saffron))" }}>Good to know</div>
          <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "clamp(1.6rem, 2.6vw, 2.2rem)", letterSpacing: "-0.02em", color: "var(--text-heading)", margin: "12px 0 6px" }}>Frequently Asked</h2>
          <p style={{ fontFamily: "var(--font-ui)", fontSize: "15px", lineHeight: 1.65, color: "var(--text-muted)", margin: "0 0 30px" }}>Shipping, returns and the things people ask before their first order.</p>
          <div style={{ borderTop: "1px solid var(--border-hairline)" }}>
            {[0, 1, 2, 3].map((n) => (
              <div key={n} style={{ borderBottom: "1px solid var(--border-hairline)", padding: "24px 4px" }}>
                <span style={{ display: "block", height: "13px", width: `${58 - n * 6}%`, borderRadius: "3px", background: "rgba(11,31,58,0.09)" }}></span>
              </div>
            ))}
          </div>
        </div>
      </section>
    );
  }

  // Nothing published \u2014 drop the section rather than show an empty shell.
  if (!faqs.length) return null;
  return (
    <section id="sec-faq" ref={faqRef} style={{ background: "var(--beige)" }}>
      <div style={{ maxWidth: "940px", margin: "0 auto", padding: "72px 24px 76px" }}>
        <div style={{ fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--gold-500, var(--saffron))" }}>Good to know</div>
        <h2 style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "clamp(1.6rem, 2.6vw, 2.2rem)", letterSpacing: "-0.02em", color: "var(--text-heading)", margin: "12px 0 6px" }}>Frequently Asked</h2>
        <p style={{ fontFamily: "var(--font-ui)", fontSize: "15px", lineHeight: 1.65, color: "var(--text-muted)", margin: "0 0 30px" }}>Shipping, returns and the things people ask before their first order.</p>
        <div style={{ borderTop: "1px solid var(--border-hairline)" }}>
          {faqs.map(({ id, q, a }, i) => {
            const isOpen = open === i;
            return (
              <div key={id || q} style={{ borderBottom: "1px solid var(--border-hairline)" }}>
                <button onClick={() => setOpen(isOpen ? -1 : i)} aria-expanded={isOpen} style={{ width: "100%", background: "none", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "space-between", gap: "20px", textAlign: "left", padding: "20px 4px", fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "17px", color: isOpen ? "var(--forest-900)" : "var(--text-heading)" }}>
                  {q}
                  <span aria-hidden style={{ fontFamily: "var(--font-ui)", fontSize: "20px", lineHeight: 1, color: "var(--saffron)", transition: "transform var(--dur-med) var(--ease-standard)", transform: isOpen ? "rotate(45deg)" : "none" }}>+</span>
                </button>
                {/* pre-wrap keeps the admin's line breaks and blank lines — answers are
                    written as lists often enough that collapsing them loses meaning. */}
                {isOpen ? <p style={{ fontFamily: "var(--font-ui)", fontSize: "14.5px", lineHeight: 1.75, color: "var(--text-muted)", margin: "0 60px 22px 4px", maxWidth: "70ch", whiteSpace: "pre-wrap", overflowWrap: "anywhere" }}>{a}</p> : null}
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

ReactDOM.createRoot(document.getElementById("tahan-app")).render(<App />);
