// TAHAANN storefront chrome — light header, cart drawer, toast, footer
const { IconButton, Input, Button } = window.TAHANDesignSystem_a07997;

// Icon-only brand mark, now used solely by the mobile slide-out drawer — the
// header and footer carry the full lockup. The full-colour glyph replaces the
// red/navy duotone; at 36px in a narrow panel the letterform reads better than
// the wide lockup would.
const Mark = ({ h = 66, onDark = false }) => (
  <span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0, height: h, padding: onDark ? "7px 10px" : 0, background: onDark ? "#FFFFFF" : "transparent", borderRadius: onDark ? "8px" : 0 }}>
    <img src="tahan/assets/tahan-logo-mark-colour.png" alt="TAHAANN" style={{ height: "100%", width: "auto", display: "block" }} />
  </span>
);

const Ico = ({ d, size = 20, stroke = "currentColor", fill = "none", sw = 1.75 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" aria-hidden>{d}</svg>
);
const IHeart = <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" />;
const IBag = <><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" /><path d="M3 6h18" /><path d="M16 10a4 4 0 0 1-8 0" /></>;
const IUser = <><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></>;
const ISearch = <><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></>;
const ITruck = <><path d="M1 3h15v13H1z" /><path d="M16 8h4l3 3v5h-7" /><circle cx="5.5" cy="18.5" r="2" /><circle cx="18.5" cy="18.5" r="2" /></>;
const IPhone = <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.362 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.338 1.85.573 2.81.7A2 2 0 0 1 22 16.92z" />;
const IFacebook = <path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />;
const IInstagram = <><rect x="2" y="2" width="20" height="20" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none" /></>;
const IYouTube = <><path d="M23 7a4 4 0 0 0-3-3.9C18 2.5 12 2.5 12 2.5s-6 0-8 .6A4 4 0 0 0 1 7a42 42 0 0 0 0 10 4 4 0 0 0 3 3.9c2 .6 8 .6 8 .6s6 0 8-.6a4 4 0 0 0 3-3.9 42 42 0 0 0 0-10z" /><path d="m10 15 5-3-5-3z" fill="currentColor" stroke="none" /></>;

// Accepted payment rails shown in the sub-footer. Third entry is the artwork:
// each logo is trimmed to its ink and centred on one common transparent canvas
// (192x64), so a single CSS height gives the whole row even sizing and spacing.
// A rail with no artwork is simply left out of the row.
const PAY_MARKS = [["Visa", "visa", "tahan/assets/pay-visa.png"], ["Mastercard", "mastercard", "tahan/assets/pay-mastercard.png"], ["PhonePe", "phonepe", "tahan/assets/pay-phonepe.png"], ["Google Pay", "gpay", "tahan/assets/pay-gpay.png"]];

const CART_KEY = "tahan-cart-v1";
function loadCart() { try { return JSON.parse(localStorage.getItem(CART_KEY)) || {}; } catch (e) { return {}; } }
function saveCart(c) { try { localStorage.setItem(CART_KEY, JSON.stringify(c)); } catch (e) {} }
function useCart() {
  const [cart, setCart] = React.useState(loadCart);
  React.useEffect(() => { saveCart(cart); }, [cart]);
  return [cart, setCart];
}

const WISH_KEY = "tahan-wishlist-v1";
function loadWish() { try { return JSON.parse(localStorage.getItem(WISH_KEY)) || {}; } catch (e) { return {}; } }
function saveWish(w) { try { localStorage.setItem(WISH_KEY, JSON.stringify(w)); } catch (e) {} }
function useWishlist() {
  const [wish, setWish] = React.useState(loadWish);
  React.useEffect(() => { saveWish(wish); }, [wish]);
  return [wish, setWish];
}

function Badgeable({ count, children }) {
  return (
    <span style={{ position: "relative", display: "inline-flex" }}>
      {children}
      {count > 0 && (
        <span style={{ position: "absolute", top: "-6px", right: "-8px", minWidth: "18px", height: "18px", padding: "0 5px", borderRadius: "999px", background: "var(--burgundy-800)", color: "var(--cream-100)", fontFamily: "var(--font-ui)", fontSize: "10.5px", fontWeight: 700, display: "flex", alignItems: "center", justifyContent: "center", border: "2px solid var(--surface-page)" }}>{count}</span>
      )}
    </span>
  );
}

function ActionBtn({ icon, label, count, onClick }) {
  return (
    <button onClick={onClick} style={{ background: "none", border: "none", cursor: "pointer", display: "flex", alignItems: "center", gap: "7px", color: "var(--forest-800)", fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 600, padding: "4px" }}>
      <Badgeable count={count}><Ico d={icon} size={19} /></Badgeable>
      <span className="tahan-action-label">{label}</span>
    </button>
  );
}

const IMenu = <><path d="M3 6h18" /><path d="M3 12h18" /><path d="M3 18h18" /></>;
const IClose = <><path d="M6 6l12 12" /><path d="M18 6 6 18" /></>;
const IHome = <><path d="M3 10.5 12 3l9 7.5" /><path d="M5 9.5V21h14V9.5" /></>;
const IMail = <><rect x="2" y="4" width="20" height="16" rx="2" /><path d="m2 7 10 6 10-6" /></>;
const IPin = <><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0z" /><circle cx="12" cy="10" r="3" /></>;
const IGrid = <><rect x="3" y="3" width="7" height="7" rx="1.5" /><rect x="14" y="3" width="7" height="7" rx="1.5" /><rect x="3" y="14" width="7" height="7" rx="1.5" /><rect x="14" y="14" width="7" height="7" rx="1.5" /></>;

// Fixed bottom tab bar for phones. Sits below Bootstrap's md alongside the
// collapsed header, and reuses the cart drawer and category drawer already
// wired into Header, so no page needs new props.
function MobileTabBar({ page, cartCount, onCart, onCategory }) {
  const tab = (active) => ({
    flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
    gap: "4px", padding: "9px 0 7px", background: "none", border: "none", cursor: "pointer",
    textDecoration: "none", fontFamily: "var(--font-ui)", fontSize: "10.5px", fontWeight: 600,
    color: active ? "var(--coral-deep)" : "var(--text-muted)",
  });
  return (
    <nav className="tahan-tabbar" aria-label="Primary" style={{ position: "fixed", left: 0, right: 0, bottom: 0, zIndex: 60, display: "none", alignItems: "stretch", background: "#FFFFFF", borderTop: "1px solid var(--border-hairline)", boxShadow: "0 -2px 10px rgba(11,31,58,0.06)" }}>
      <a href="Home.html" style={tab(page === "Home")}><Ico d={IHome} size={20} />Home</a>
      <button onClick={onCategory} style={tab(page === "Shop by Category")}><Ico d={IGrid} size={20} />Category</button>
      <button onClick={onCart} style={tab(false)}><Badgeable count={cartCount}><Ico d={IBag} size={20} /></Badgeable>Cart</button>
      <a href="Profile.html" style={tab(page === "Profile")}><Ico d={IUser} size={20} />Profile</a>
    </nav>
  );
}

function MobileDrawer({ open, onClose, nav, page, addToHome, addToHomeStyle }) {
  // Store details for the drawer's foot, from the admin's Contact page. The
  // nav list above takes the free space, so this block sits at the bottom of
  // the panel. Each line is omitted when the admin has not filled it in.
  const contact = (window.TAHAN_DATA && window.TAHAN_DATA.contact) || null;
  const emails = contact ? [contact.email1, contact.email2].filter(Boolean) : [];
  const hasContact = !!contact && !!(contact.address.length || contact.phone || contact.whatsapp || emails.length);
  const line = { display: "flex", alignItems: "flex-start", gap: "9px", color: "var(--navy)", textDecoration: "none", lineHeight: 1.5 };
  const icon = { flexShrink: 0, marginTop: "1px", color: "var(--text-muted)", display: "flex" };
  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 70, background: "rgba(11,31,58,0.5)", opacity: open ? 1 : 0, pointerEvents: open ? "auto" : "none", transition: "opacity var(--dur-med) var(--ease-standard)" }}></div>
      <aside style={{ position: "fixed", top: 0, left: 0, bottom: 0, width: "min(320px, 84vw)", zIndex: 71, background: "#FFFFFF", boxShadow: "var(--shadow-lg)", transform: open ? "translateX(0)" : "translateX(-100%)", transition: "transform var(--dur-slow) var(--ease-entrance)", display: "flex", flexDirection: "column", fontFamily: "var(--font-ui)" }}>
        <div style={{ padding: "18px 20px", borderBottom: "1px solid var(--border-hairline)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <a href="Home.html" style={{ display: "flex", alignItems: "center", textDecoration: "none" }}><Mark h={36} /></a>
          <button onClick={onClose} aria-label="Close menu" style={{ background: "none", border: "none", cursor: "pointer", color: "var(--navy)", padding: "4px" }}><Ico d={IClose} size={20} /></button>
        </div>
        <div style={{ flex: 1, overflowY: "auto", padding: "8px 8px" }}>
          {nav.map(([label, caret, menu, href]) => (
            <div key={label}>
              <a href={href || "#"} onClick={(e) => { if (!href) e.preventDefault(); }} style={{ display: "block", padding: "14px 12px", fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "16px", color: label === page ? "var(--coral-deep)" : "var(--navy)", textDecoration: "none", borderBottom: "1px solid var(--border-hairline)" }}>{label}</a>
              {menu && (
                <div style={{ padding: "2px 12px 10px 22px", display: "flex", flexDirection: "column", gap: "2px", borderBottom: "1px solid var(--border-hairline)" }}>
                  {menu.map(([m, key]) => (
                    <a key={m} href={`Shop?cat=${key}`} style={{ padding: "8px 0", fontFamily: "var(--font-ui)", fontSize: "13.5px", fontWeight: 600, color: "var(--text-muted)", textDecoration: "none" }}>{m}</a>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
        {/* Phones: the header's add-to-home-screen button lives here. Passed in
            by Header only while the browser offers it. */}
        {addToHome && (
          <div style={{ padding: "12px 20px" }}>
            <button type="button" onClick={() => { addToHome(); onClose(); }} style={{ ...addToHomeStyle, width: "100%" }}>Install Now</button>
          </div>
        )}
        {hasContact && (
          <div style={{ borderTop: "1px solid var(--border-hairline)", background: "var(--surface-page)", padding: "16px 20px 18px", display: "flex", flexDirection: "column", gap: "11px", fontFamily: "var(--font-ui)", fontSize: "12.5px" }}>
            <div style={{ fontSize: "11px", fontWeight: 700, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--text-muted)" }}>Contact us</div>
            {contact.address.length > 0 && (
              <div style={{ ...line, color: "var(--text-muted)" }}><span style={icon}><Ico d={IPin} size={14} /></span><span>{contact.address.join(", ")}</span></div>
            )}
            {contact.phone && (
              <a href={`tel:${contact.phone.replace(/\s/g, "")}`} style={line}><span style={icon}><Ico d={IPhone} size={14} /></span><span>{contact.phone}</span></a>
            )}
            {contact.whatsapp && (
              <a href={`https://wa.me/${contact.whatsapp.replace(/\D/g, "")}`} target="_blank" rel="noopener" style={line}><span style={{ ...icon, color: "#25D366" }}><Ico d={IWhatsApp} size={14} fill="currentColor" sw={0} /></span><span>WhatsApp · {contact.whatsapp}</span></a>
            )}
            {emails.map((e) => (
              <a key={e} href={`mailto:${e}`} style={{ ...line, overflowWrap: "anywhere" }}><span style={icon}><Ico d={IMail} size={14} /></span><span>{e}</span></a>
            ))}
          </div>
        )}
      </aside>
    </>
  );
}

const ANNOUNCEMENTS = [
  "Free Shipping on orders above ₹499",
  "Easy Returns — Hassle Free",
  "Secure Packaging — Safe Delivery",
  "Support Bengali Makers — Read, Taste & Wear",
];

// The marquee needs @keyframes, which inline styles can't express, and this
// chrome is shared by every page — injecting the rule once here beats editing
// eleven HTML files. Paused under prefers-reduced-motion, where an endlessly
// moving strip is exactly what the setting asks us not to do.
function ensureChromeStyles() {
  if (document.getElementById("tahan-chrome-style")) return;
  const el = document.createElement("style");
  el.id = "tahan-chrome-style";
  el.textContent =
    "@keyframes tahanMarquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}" +
    ".tahan-marquee-track{animation:tahanMarquee var(--tahan-marquee-dur,26s) linear infinite}" +
    "@media(prefers-reduced-motion:reduce){.tahan-marquee-track{animation:none}}" +
    // Payment marks: even spacing, one common height, no boxes or rules. The
    // width cap stops a long mark (PhonePe) dwarfing a stacked one (GPay), and
    // object-fit keeps every logo in proportion inside that cap.
    ".tahan-payrow{display:flex;align-items:center;flex-wrap:wrap;gap:14px}" +
    ".tahan-pay-mark{height:26px;width:auto;object-fit:contain;display:block;flex-shrink:0}" +
    "@media(max-width:575.98px){.tahan-payrow{gap:10px}.tahan-pay-mark{height:22px}}";
  document.head.appendChild(el);
}

// Mobile gets a continuous horizontal scroll instead of the vertical rotator,
// whose fixed-height lines truncated every message with an ellipsis on a narrow
// strip. The list is rendered twice and shifted by exactly -50%, so the second
// copy is in place the moment the first scrolls out and the loop is seamless.
function AnnouncementMarquee({ messages }) {
  React.useEffect(() => { ensureChromeStyles(); }, []);
  // Roughly constant reading speed regardless of how many messages there are.
  const seconds = Math.max(18, Math.round(messages.join("").length / 3.2));
  const run = messages.concat(messages);
  return (
    <span style={{ flex: 1, minWidth: 0, overflow: "hidden", display: "block" }}>
      <span className="tahan-marquee-track" style={{ display: "inline-flex", alignItems: "center", whiteSpace: "nowrap", willChange: "transform", "--tahan-marquee-dur": seconds + "s" }}>
        {run.map((msg, i) => (
          <span key={i} style={{ display: "inline-flex", alignItems: "center", fontWeight: 600 }}>
            {msg}
            <span aria-hidden style={{ opacity: 0.55, padding: "0 18px" }}>•</span>
          </span>
        ))}
      </span>
    </span>
  );
}

function AnnouncementTicker({ messages, interval = 3200 }) {
  const LINE_H = 20;
  const loop = React.useMemo(() => [...messages, messages[0]], [messages]);
  const [index, setIndex] = React.useState(0);
  const [instant, setInstant] = React.useState(false);

  React.useEffect(() => {
    const t = setInterval(() => setIndex((i) => i + 1), interval);
    return () => clearInterval(t);
  }, [interval]);

  React.useEffect(() => {
    if (index !== loop.length - 1) return;
    const t = setTimeout(() => {
      setInstant(true);
      setIndex(0);
      requestAnimationFrame(() => requestAnimationFrame(() => setInstant(false)));
    }, 520);
    return () => clearTimeout(t);
  }, [index, loop.length]);

  return (
    <span style={{ position: "relative", height: LINE_H, overflow: "hidden", display: "inline-block", flex: 1, minWidth: 0 }}>
      <span style={{ position: "absolute", inset: 0, transform: `translateY(${index * LINE_H}px)`, transition: instant ? "none" : "transform 520ms ease" }}>
        {loop.map((msg, i) => (
          <span key={i} style={{ position: "absolute", top: -i * LINE_H, left: 0, right: 0, height: LINE_H, display: "flex", alignItems: "center", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{msg}</span>
        ))}
      </span>
    </span>
  );
}

// `inPanel` is the phone version, opened by the header's search button. It is
// the same box with the same suggestions — only the class differs, because
// .tahan-header-search is display:none below 767.98px for the inline pill.
function SearchBox({ inPanel }) {
  const data = window.useTahanData ? window.useTahanData() : window.TAHAN_DATA;
  const [query, setQuery] = React.useState("");
  const [suggestions, setSuggestions] = React.useState([]);
  const [showSuggestions, setShowSuggestions] = React.useState(false);
  const inputRef = React.useRef(null);
  React.useEffect(() => { if (inPanel && inputRef.current) inputRef.current.focus(); }, [inPanel]);

  const handleSearch = (e) => {
    const value = e.target.value;
    setQuery(value);

    if (value.trim().length === 0) {
      setSuggestions([]);
      setShowSuggestions(false);
      return;
    }

    const catalog = (data && data.catalog) || [];
    const filtered = catalog
      .filter((item) => item.title && item.title.toLowerCase().includes(value.toLowerCase()))
      .slice(0, 5);

    setSuggestions(filtered);
    setShowSuggestions(true);
  };

  const handleSuggestionClick = (itemId) => {
    window.location.href = `Product?id=${itemId}`;
  };

  return (
    <div style={{ position: "relative", flex: 1, maxWidth: inPanel ? "none" : "420px" }}>
      <label className={inPanel ? undefined : "tahan-header-search"} style={{ flex: 1, maxWidth: inPanel ? "none" : "420px", display: "flex", alignItems: "center", gap: "10px", background: "transparent", border: "1px solid var(--border-strong)", borderRadius: "var(--radius-pill)", padding: "10px 16px", minWidth: 0 }}>
        <Ico d={ISearch} size={16} stroke="var(--text-muted)" />
        <input
          ref={inputRef}
          type="search"
          placeholder="Search books, tea, crafts…"
          value={query}
          onChange={handleSearch}
          onFocus={() => query && setSuggestions(suggestions.length > 0 ? suggestions : [])}
          style={{ flex: 1, minWidth: 0, border: "none", outline: "none", background: "transparent", fontFamily: "var(--font-ui)", fontSize: "13.5px", color: "var(--text-body)" }}
        />
      </label>
      {showSuggestions && suggestions.length > 0 && (
        <div style={{ position: "absolute", top: "100%", left: 0, right: 0, marginTop: "8px", background: "#FFFFFF", border: "1px solid var(--border-hairline)", borderRadius: "8px", boxShadow: "0 4px 12px rgba(11,31,58,0.15)", zIndex: 50, overflow: "hidden" }}>
          {suggestions.map((item) => (
            <button
              key={item.id}
              onClick={() => handleSuggestionClick(item.id)}
              style={{ display: "flex", width: "100%", alignItems: "center", gap: "12px", padding: "12px 16px", border: "none", background: "none", cursor: "pointer", textAlign: "left", borderBottom: "1px solid var(--border-hairline)", transition: "background var(--dur-fast)" }}
              onMouseEnter={(e) => e.currentTarget.style.background = "var(--cream-50)"}
              onMouseLeave={(e) => e.currentTarget.style.background = "transparent"}
            >
              <div style={{ width: "40px", height: "50px", flexShrink: 0, borderRadius: "4px", overflow: "hidden", background: "var(--cream-200)" }}>
                <image-slot id={`tahan-search-${item.id}`} shape="rect" fit="cover" placeholder="" src={item.image || ""} style={{ width: "100%", height: "100%" }}></image-slot>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, color: "var(--text-heading)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{item.title}</div>
                <div style={{ fontFamily: "var(--font-ui)", fontSize: "12px", color: "var(--text-muted)", marginTop: "2px" }}>₹{item.price?.toLocaleString("en-IN") || "N/A"}</div>
              </div>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// The announcement strip swaps behaviour by viewport, and an inline style
// cannot hold a media query — so the breakpoint is read here instead. 767.98px
// is the same phone breakpoint the stylesheets already use.
function useIsMobileBar() {
  const q = "(max-width: 767.98px)";
  const [is, setIs] = React.useState(() => window.matchMedia(q).matches);
  React.useEffect(() => {
    const m = window.matchMedia(q);
    const on = (e) => setIs(e.matches);
    if (m.addEventListener) m.addEventListener("change", on); else m.addListener(on);
    return () => { if (m.removeEventListener) m.removeEventListener("change", on); else m.removeListener(on); };
  }, []);
  return is;
}

// "Add TAHAANN to Home Screen": each page's <head> keeps the browser's
// add-to-home-screen event (window.__tahanInstallEvent) and announces it with
// "tahan-installable". The header button appears only while that event is
// available and TAHAANN isn't already opened from the home screen; tapping it
// hands over to the browser's own native flow.
function useHomeScreenPrompt() {
  const onHomeScreen = () => {
    try {
      return window.matchMedia("(display-mode: standalone)").matches ||
        window.matchMedia("(display-mode: fullscreen)").matches ||
        window.matchMedia("(display-mode: minimal-ui)").matches ||
        window.navigator.standalone === true;
    } catch (e) { return false; }
  };
  const [available, setAvailable] = React.useState(() => !!window.__tahanInstallEvent && !onHomeScreen());
  React.useEffect(() => {
    const onReady = () => setAvailable(!!window.__tahanInstallEvent && !onHomeScreen());
    const onAdded = () => { window.__tahanInstallEvent = null; setAvailable(false); };
    window.addEventListener("tahan-installable", onReady);
    window.addEventListener("appinstalled", onAdded);
    onReady();
    return () => {
      window.removeEventListener("tahan-installable", onReady);
      window.removeEventListener("appinstalled", onAdded);
    };
  }, []);
  const add = () => {
    const ev = window.__tahanInstallEvent;
    window.__tahanInstallEvent = null;   // the native prompt can be used once
    setAvailable(false);
    if (ev && typeof ev.prompt === "function") ev.prompt();
  };
  return [available, add];
}

function Header({ cartCount, wishCount, onCart, onWish }) {
  const isMobileBar = useIsMobileBar();
  const [canAddToHome, addToHome] = useHomeScreenPrompt();
  const addToHomeStyle = { background: "transparent", border: "1px solid var(--border-strong)", borderRadius: "var(--radius-pill)", padding: "9px 16px", cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 700, color: "var(--navy)", whiteSpace: "nowrap" };
  const page = window.TAHAN_PAGE || "Home";
  const catData = window.useTahanData ? window.useTahanData() : window.TAHAN_DATA;
  const cats = (catData && catData.groups) || [];
  // Top-bar socials come from the admin's Contact details, same as the footer's.
  const topSocial = (catData && catData.contact) || {};
  const nav = [["Home", false, null, "Home.html"], ...cats.map((c) => [c.label, false, null, `Shop?cat=${c.key}`])];
  const [drawerOpen, setDrawerOpen] = React.useState(false);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [isAuth, setIsAuth] = React.useState(false);
  const [authLoading, setAuthLoading] = React.useState(true);

  React.useEffect(() => {
    if (!window.TAHAN_AUTH_SUBSCRIBE) return;
    const unsub = window.TAHAN_AUTH_SUBSCRIBE(function (user, loading) {
      setIsAuth(user != null);
      setAuthLoading(loading);
    });
    return unsub;
  }, []);

  const logout = async (e) => {
    e.preventDefault();
    if (window.TAHAN_SIGN_OUT) {
      await window.TAHAN_SIGN_OUT();
    } else {
      try {
        if (window.TAHAN_AUTH) {
          await window.TAHAN_AUTH.signOut();
        }
      } catch (err) {
        console.error("Firebase sign out failed:", err);
      }
      try {
        localStorage.removeItem("tahan_session");
        localStorage.removeItem("tahan-profile-v1");
        localStorage.removeItem("tahan-addresses-v1");
      } catch (e) {}
    }
    window.location.href = "Login.html";
  };

  return (
    <>
      <div style={{ background: "var(--coral)", color: "#FFFFFF", fontSize: "12.5px", fontFamily: "var(--font-ui)" }}>
        <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "7px 24px", display: "flex", alignItems: "center", gap: "10px" }}>
          <Ico d={ITruck} size={15} />
          {isMobileBar ? <AnnouncementMarquee messages={ANNOUNCEMENTS} /> : <AnnouncementTicker messages={ANNOUNCEMENTS} />}
          <span style={{ display: "flex", alignItems: "center", gap: "16px", flexShrink: 0 }}>
            {topSocial.phone ? <a href={`tel:${topSocial.phone.replace(/\s/g, "")}`} aria-label={`Call ${topSocial.phone}`} style={{ display: "inline-flex", alignItems: "center", gap: "6px", color: "#FFFFFF", fontWeight: 600 }}><Ico d={IPhone} size={13} />{isMobileBar ? null : topSocial.phone}</a> : null}
            <span style={{ display: "flex", gap: "10px" }}>
              {topSocial.facebook ? <a href={topSocial.facebook} target="_blank" rel="noopener" aria-label="Facebook" style={{ color: "#FFFFFF", display: "flex" }}><Ico d={IFacebook} size={14} fill="currentColor" sw={0} /></a> : null}
              {topSocial.instagram ? <a href={topSocial.instagram} target="_blank" rel="noopener" aria-label="Instagram" style={{ color: "#FFFFFF", display: "flex" }}><Ico d={IInstagram} size={14} /></a> : null}
              {topSocial.youtube ? <a href={topSocial.youtube} target="_blank" rel="noopener" aria-label="YouTube" style={{ color: "#FFFFFF", display: "flex" }}><Ico d={IYouTube} size={14} /></a> : null}
            </span>
          </span>
        </div>
      </div>
    <header style={{ background: "var(--surface-card)", position: "sticky", top: 0, zIndex: 40, fontFamily: "var(--font-ui)" }}>
      <div style={{ borderBottom: "1px solid var(--border-hairline)" }}>
        <div className="tahan-header-row" style={{ maxWidth: "1280px", margin: "0 auto", padding: "16px 24px", display: "flex", alignItems: "center", gap: "40px" }}>
          <button onClick={() => setDrawerOpen(true)} aria-label="Open menu" className="tahan-hamburger-btn" style={{ display: "none", background: "none", border: "none", cursor: "pointer", color: "var(--navy)", padding: "4px", flexShrink: 0 }}><Ico d={IMenu} size={22} /></button>
          <a href="Home.html" style={{ display: "flex", alignItems: "center", gap: "10px", textDecoration: "none", flexShrink: 0 }}>
            {/* Full lockup: the mark, wordmark and tagline are all in the
                artwork, so the typeset "TAHAANN / Tales of Bengal" that used to
                sit beside the icon would now be a duplicate. */}
            <img src="tahan/assets/tahan-logo-lockup.png" alt="TAHAANN — Tales of Bengal" style={{ height: "48px", width: "auto", display: "block", flexShrink: 0 }} />
          </a>
          <SearchBox />
          <div style={{ display: "flex", gap: "16px", marginLeft: "auto" }}>
            {/* Desktop: beside the header actions. Phones get it in the menu
                drawer instead (MobileDrawer), as it won't fit here. */}
            {!isMobileBar && canAddToHome && <button type="button" onClick={addToHome} style={{ ...addToHomeStyle, alignSelf: "center" }}>Install Now</button>}
            {/* Phones only: the inline pill above is hidden by CSS below
                767.98px, so this opens the same search in a strip under the
                header. Desktop keeps the pill itself and needs no button. */}
            {isMobileBar && <ActionBtn icon={ISearch} label="Search" onClick={() => setSearchOpen((v) => !v)} />}
            <ActionBtn icon={IHeart} label="Wishlist" count={wishCount} onClick={onWish || (() => { window.location.href = "Wishlist.html"; })} />
            <ActionBtn icon={IBag} label="Cart" count={cartCount} onClick={onCart} />
            {/* Desktop only: phones reach the same places from the bottom tab
                bar's Profile tab, so the account menu is dropped there rather
                than duplicating it. Same breakpoint as the tab bar (767.98px). */}
            {!isMobileBar && (
            <div className="tahan-nav-item" style={{ position: "relative" }}>
              <ActionBtn icon={IUser} label="Account" />
              <div className="tahan-nav-menu" style={{ position: "absolute", top: "100%", right: 0, minWidth: "170px", background: "#FFFFFF", border: "1px solid rgba(11,31,58,0.12)", borderRadius: "6px", boxShadow: "0 10px 28px rgba(11,31,58,0.16)", padding: "6px 0", zIndex: 45 }}>
                {!authLoading && isAuth ? (
                  [["Profile", "Profile.html", false], ["Orders", "Orders.html", false], ["Log out", "Login.html", true]].map(([m, href, isLogout]) => (
                    isLogout ? (
                      <button key={m} onClick={logout} className="tahan-nav-menu-link" style={{ display: "block", width: "100%", textAlign: "left", padding: "10px 18px", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, color: "var(--brand-secondary)", textDecoration: "none", whiteSpace: "nowrap", border: "none", background: "none", cursor: "pointer", borderTop: "1px solid rgba(11,31,58,0.10)", marginTop: "5px", paddingTop: "12px" }}>{m}</button>
                    ) : (
                      <a key={m} href={href} className="tahan-nav-menu-link" style={{ display: "block", padding: "10px 18px", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, color: "var(--navy)", textDecoration: "none", whiteSpace: "nowrap" }}>{m}</a>
                    )
                  ))
                ) : (
                  <a href="Login.html" className="tahan-nav-menu-link" style={{ display: "block", padding: "10px 18px", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, color: "var(--navy)", textDecoration: "none", whiteSpace: "nowrap" }}>Log in</a>
                )}
              </div>
            </div>
            )}
          </div>
        </div>
        {/* Phones only — the strip exists solely because the inline pill is
            hidden below 767.98px. The × closes it again, for people who opened
            it by accident or are done searching. */}
        {isMobileBar && searchOpen && (
          <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "0 24px 14px", display: "flex", alignItems: "center", gap: "10px" }}>
            <SearchBox inPanel />
            <button onClick={() => setSearchOpen(false)} aria-label="Close search" style={{ flexShrink: 0, background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)", display: "flex", alignItems: "center", justifyContent: "center", padding: "8px" }}><Ico d={IClose} size={20} /></button>
          </div>
        )}
      </div>
      <nav style={{ borderBottom: "1px solid var(--border-hairline)" }} className="tahan-navrow tahan-desktop-nav">
        <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "0 24px", display: "flex", justifyContent: "center", gap: "42px" }}>
          {nav.map(([label, caret, menu, href], i) => (
            <div key={label} className="tahan-nav-item" style={{ position: "relative" }}>
            <a href={href || "#"} onClick={(e) => { if (!href) e.preventDefault(); }} className="tahan-nav-link" style={{ display: "inline-flex", alignItems: "center", gap: "6px", padding: "28px 0", fontSize: "13px", fontWeight: 700, letterSpacing: "0.04em", textTransform: "uppercase", color: label === page ? "var(--coral-deep)" : "var(--navy)" }}>
              {label}{caret && <span style={{ fontSize: "9px", opacity: 0.6 }}>▼</span>}
              <span className="u"></span>
            </a>
            {menu && (
              <div className="tahan-nav-menu" style={{ position: "absolute", top: "100%", left: "-14px", minWidth: "210px", background: "#FFFFFF", border: "1px solid rgba(11,31,58,0.12)", borderRadius: "6px", boxShadow: "0 10px 28px rgba(11,31,58,0.16)", padding: "8px 0", zIndex: 40 }}>
                {menu.map(([m, key]) => (
                  <a key={m} href={`Shop?cat=${key}`} className="tahan-nav-menu-link" style={{ display: "block", padding: "10px 18px", fontFamily: "var(--font-ui)", fontSize: "13px", fontWeight: 600, color: "var(--navy)", textDecoration: "none", whiteSpace: "nowrap" }}>{m}</a>
                ))}
              </div>
            )}
            </div>
          ))}
        </div>
      </nav>
    </header>
    <MobileDrawer open={drawerOpen} onClose={() => setDrawerOpen(false)} nav={nav} page={page} addToHome={isMobileBar && canAddToHome ? addToHome : null} addToHomeStyle={addToHomeStyle} />
    <MobileTabBar page={page} cartCount={cartCount} onCart={onCart} onCategory={() => setDrawerOpen(true)} />
    </>
  );
}

function CartDrawer({ open, onClose, items, data, inc, dec, remove }) {
  const list = Object.entries(items).map(([id, qty]) => ({ book: (data.catalog || data.books).find((b) => b.id === id), qty })).filter((x) => x.book);
  const subtotal = list.reduce((s, x) => s + x.book.price * x.qty, 0);
  const toFree = Math.max(0, 499 - subtotal);
  const totalQty = list.reduce((s, x) => s + x.qty, 0);
  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 60, background: "rgba(34,30,23,0.5)", opacity: open ? 1 : 0, pointerEvents: open ? "auto" : "none", transition: "opacity var(--dur-med) var(--ease-standard)" }}></div>
      <aside style={{ position: "fixed", top: 0, right: 0, bottom: 0, width: "min(420px, 92vw)", zIndex: 61, background: "var(--surface-page)", boxShadow: "var(--shadow-lg)", transform: open ? "translateX(0)" : "translateX(100%)", transition: "transform var(--dur-slow) var(--ease-entrance)", display: "flex", flexDirection: "column", fontFamily: "var(--font-ui)" }}>
        <div style={{ padding: "22px 24px", borderBottom: "1px solid var(--border-hairline)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div>
            <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "20px", color: "var(--text-heading)" }}>Your bag</div>
            <div style={{ fontSize: "12.5px", color: "var(--text-muted)", marginTop: "2px" }}>{totalQty} item{totalQty === 1 ? "" : "s"}</div>
          </div>
          <button onClick={onClose} aria-label="Close" style={{ background: "none", border: "none", cursor: "pointer", fontSize: "22px", color: "var(--text-muted)", lineHeight: 1 }}>×</button>
        </div>
        <div style={{ flex: 1, overflowY: "auto", padding: "8px 24px" }}>
          {list.length === 0 ? (
            <div style={{ textAlign: "center", padding: "72px 12px", color: "var(--text-muted)" }}>
              <div style={{ fontSize: "40px", color: "var(--saffron)", marginBottom: "12px" }}>❦</div>
              <div style={{ fontFamily: "var(--font-display)", fontSize: "18px", color: "var(--text-heading)" }}>Your bag is empty</div>
              <p style={{ fontSize: "14px", lineHeight: 1.6, marginTop: "8px" }}>When a story catches you, add it to your shelf.</p>
            </div>
          ) : list.map(({ book, qty }) => (
            <div key={book.id} style={{ display: "flex", gap: "14px", padding: "18px 0", borderBottom: "1px solid var(--border-hairline)" }}>
              <div style={{ width: "64px", height: "80px", flexShrink: 0, borderRadius: "6px", overflow: "hidden", background: "var(--cream-200)", boxShadow: "var(--shadow-book)" }}>
                <image-slot id={`tahan-cart-${book.id}`} shape="rect" fit="cover" placeholder="" src={book.image || ""}></image-slot>
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: "15px", color: "var(--text-heading)" }}>{book.title}</div>
                <div style={{ fontSize: "12.5px", color: "var(--text-muted)", marginTop: "1px" }}>{book.author || book.tagline}</div>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: "10px" }}>
                  <div style={{ display: "flex", alignItems: "center", border: "1px solid var(--border-strong)", borderRadius: "var(--radius-md)", overflow: "hidden" }}>
                    <button onClick={() => dec(book.id)} style={qtyBtn}>−</button>
                    <span style={{ minWidth: "26px", textAlign: "center", fontSize: "14px", fontWeight: 600 }}>{qty}</span>
                    <button onClick={() => inc(book.id)} style={qtyBtn}>+</button>
                  </div>
                  <span style={{ fontFamily: "var(--font-ui)", fontWeight: 600, color: "var(--text-body)" }}>₹{(book.price * qty).toLocaleString("en-IN")}</span>
                </div>
                <button onClick={() => remove(book.id)} style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)", fontSize: "12px", padding: "8px 0 0", textDecoration: "underline" }}>Remove</button>
              </div>
            </div>
          ))}
        </div>
        {list.length > 0 && (
          <div style={{ padding: "20px 24px 24px", borderTop: "1px solid var(--border-hairline)", background: "var(--surface-card)" }}>
            {toFree > 0 ? (
              <div style={{ fontSize: "12.5px", color: "var(--text-muted)", marginBottom: "14px" }}>Add ₹{toFree.toLocaleString("en-IN")} more for free shipping.</div>
            ) : (
              <div style={{ fontSize: "12.5px", color: "var(--forest-700)", marginBottom: "14px" }}>✓ You've unlocked free shipping.</div>
            )}
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: "16px" }}>
              <span style={{ fontSize: "14px", color: "var(--text-body)" }}>Subtotal</span>
              <span style={{ fontFamily: "var(--font-ui)", fontWeight: 600, fontSize: "18px", color: "var(--text-heading)" }}>₹{subtotal.toLocaleString("en-IN")}</span>
            </div>
            <a href="Checkout.html" style={{ display: "flex", alignItems: "center", justifyContent: "center", background: "var(--navy)", color: "#FFFFFF", fontFamily: "var(--font-ui)", fontWeight: 700, fontSize: "13px", letterSpacing: "0.08em", textTransform: "uppercase", padding: "15px 20px", borderRadius: "6px", textDecoration: "none" }}>Checkout</a>
            <button onClick={onClose} style={{ background: "none", border: "none", cursor: "pointer", color: "var(--text-muted)", fontSize: "13px", width: "100%", marginTop: "12px" }}>Continue browsing</button>
          </div>
        )}
      </aside>
    </>
  );
}
const qtyBtn = { background: "none", border: "none", cursor: "pointer", width: "30px", height: "30px", fontSize: "16px", color: "var(--text-body)", lineHeight: 1 };

function Toast({ msg }) {
  return (
    <div style={{ position: "fixed", bottom: "28px", left: "50%", transform: `translateX(-50%) translateY(${msg ? "0" : "20px"})`, zIndex: 80, opacity: msg ? 1 : 0, pointerEvents: "none", transition: "opacity var(--dur-med) var(--ease-standard), transform var(--dur-med) var(--ease-entrance)", background: "var(--forest-900)", color: "var(--cream-100)", fontFamily: "var(--font-ui)", fontSize: "14px", padding: "13px 22px", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lg)", display: "flex", alignItems: "center", gap: "10px" }}>
      <span style={{ color: "var(--gold-300)" }}>✓</span>{msg}
    </div>
  );
}

function NewsletterBand() {
  const [email, setEmail] = React.useState("");
  const [done, setDone] = React.useState(false);
  return (
    <section style={{ background: "var(--sage-deep)", position: "relative", overflow: "hidden" }}>
      <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "36px 24px", position: "relative", display: "flex", alignItems: "center", justifyContent: "space-between", gap: "28px", flexWrap: "wrap" }}>
        <h3 style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: "clamp(1.3rem, 2vw, 1.7rem)", color: "#FFFFFF", margin: 0, lineHeight: 1.25, maxWidth: "22ch" }}>Stay Updated with Our Stories &amp; New Releases</h3>
        {done ? (
          <div style={{ fontFamily: "var(--font-ui)", fontSize: "15px", color: "var(--saffron-tint, var(--saffron))" }}>✓ Thank you — a welcome note is on its way.</div>
        ) : (
          <form onSubmit={(e) => { e.preventDefault(); if (email) setDone(true); }} style={{ display: "flex", gap: "0", borderRadius: "var(--radius-pill)", overflow: "hidden" }}>
            <input value={email} onChange={(e) => setEmail(e.target.value)} type="email" required placeholder="Enter your email address" style={{ width: "260px", maxWidth: "56vw", border: "none", outline: "none", padding: "14px 20px", fontFamily: "var(--font-ui)", fontSize: "14px", background: "#FFFFFF", color: "var(--text-body)" }} />
            <button type="submit" style={{ border: "none", cursor: "pointer", background: "var(--coral)", color: "#FFFFFF", fontFamily: "var(--font-ui)", fontWeight: 700, fontSize: "13px", letterSpacing: "0.08em", textTransform: "uppercase", padding: "0 26px" }}>Subscribe</button>
          </form>
        )}
      </div>
    </section>
  );
}

// WhatsApp glyph — filled, so it is drawn with fill and no stroke.
const IWhatsApp = <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0 0 20.464 3.488" />;

// Floating WhatsApp button, pinned bottom-right on every page that has the
// footer. The number is the admin's WhatsApp field (the `contact` doc), so no
// button shows until one is saved. On phones it lifts clear of the 64px bottom
// tab bar and shrinks a little; the breakpoint is the tab bar's own (767.98px).
function WhatsAppFab() {
  const isMobileBar = useIsMobileBar();
  const contact = (window.TAHAN_DATA && window.TAHAN_DATA.contact) || null;
  const digits = contact && contact.whatsapp ? contact.whatsapp.replace(/\D/g, "") : "";
  if (!digits) return null;
  const size = isMobileBar ? 52 : 58;
  return (
    <a
      href={`https://wa.me/${digits}`}
      target="_blank"
      rel="noopener"
      aria-label="Chat with us on WhatsApp"
      title="Chat with us on WhatsApp"
      style={{
        position: "fixed", right: isMobileBar ? "16px" : "24px", bottom: isMobileBar ? "80px" : "24px",
        zIndex: 50, width: size + "px", height: size + "px", borderRadius: "999px",
        background: "#25D366", color: "#FFFFFF", display: "flex", alignItems: "center", justifyContent: "center",
        boxShadow: "0 6px 18px rgba(11,31,58,0.22)", textDecoration: "none",
        transition: "transform var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard)",
      }}
      onMouseEnter={(e) => { e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.boxShadow = "0 10px 24px rgba(11,31,58,0.28)"; }}
      onMouseLeave={(e) => { e.currentTarget.style.transform = "none"; e.currentTarget.style.boxShadow = "0 6px 18px rgba(11,31,58,0.22)"; }}
    >
      <Ico d={IWhatsApp} size={isMobileBar ? 27 : 30} fill="currentColor" sw={0} />
    </a>
  );
}

function Footer() {
  // Footer categories come from the live Firestore taxonomy, so they can never drift
  // from the catalogue, and each links into the Shop filter it actually maps to.
  // Firestore lands after first paint and mutates TAHAN_DATA in place, so re-render
  // on the data event rather than relying on a changed object reference.
  const [, bumpFooter] = React.useReducer((n) => n + 1, 0);
  // The shared stylesheet also carries the payment-row rules, and the marquee
  // that used to inject it renders on phones only — so the footer asks for it
  // too, or the marks would be unstyled on desktop.
  React.useEffect(function () { ensureChromeStyles(); }, []);
  React.useEffect(function () {
    var h = function () { bumpFooter(); };
    window.addEventListener("tahan-data", h);
    return function () { window.removeEventListener("tahan-data", h); };
  }, []);
  const catList = ((window.TAHAN_DATA && window.TAHAN_DATA.categories) || []).map(function (c) {
    return { href: "Shop?cat=" + c.id, label: c.label, bn: c.bn };
  });
  // FAQ and Track Your Order point at the pages that actually hold them: the
  // questions live in the Home page's "Frequently Asked" section (there is no
  // separate FAQ page), and order tracking is the Orders page. The rest have no
  // page yet, so linkCol leaves them inert as before.
  const support = [{ label: "FAQ", href: "Home.html#sec-faq" }, "Shipping & Delivery", { label: "Refund & Cancellation Policy", href: "Refund.html" }, { label: "Terms & Conditions", href: "Terms.html" }, { label: "Privacy Policy", href: "Privacy.html" }, { label: "Track Your Order", href: "Orders.html" }];
  const about = ["About Tahaann", "Blog", "Contact Us"];
  const linkCol = (title, items) => (
    <div>
      <div style={{ fontFamily: "var(--font-ui)", fontSize: "12px", fontWeight: 700, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--navy)", marginBottom: "12px" }}>{title}</div>
      <div style={{ display: "flex", flexDirection: "column", gap: "7px" }}>
        {items.map((i) => {
          const obj = i && typeof i === "object";
          const label = obj ? i.label : i;
          const href = obj ? i.href : i === "Contact Us" ? "Contact" : i === "About Tahaann" ? "About" : i === "Blog" ? "Blog.html" : "#";
          const inert = href === "#";
          return (
            <a key={label} href={href} onClick={inert ? (e) => e.preventDefault() : undefined} style={{ color: "var(--text-muted)", fontFamily: "var(--font-ui)", fontSize: "13px", textDecoration: "none" }}>
              {obj && i.bn ? <>{i.bn} <span style={{ color: "var(--ink-300)", fontSize: "12.5px" }}>({label})</span></> : label}
            </a>
          );
        })}
      </div>
    </div>
  );
  // Facebook, Instagram and YouTube only. Paired with a name so each link gets
  // a real accessible label instead of four identical "Social link" entries.
  // The addresses come from the admin's Contact details (the `contact` doc),
  // so an icon shows only once that profile has a link saved.
  const contact = (window.TAHAN_DATA && window.TAHAN_DATA.contact) || null;
  const social = [
    ["Facebook", <><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" /></>, contact && contact.facebook],
    ["Instagram", <><rect x="2" y="2" width="20" height="20" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none" /></>, contact && contact.instagram],
    ["YouTube", <><path d="M23 7a4 4 0 0 0-3-3.9C18 2.5 12 2.5 12 2.5s-6 0-8 .6A4 4 0 0 0 1 7a42 42 0 0 0 0 10 4 4 0 0 0 3 3.9c2 .6 8 .6 8 .6s6 0 8-.6a4 4 0 0 0 3-3.9 42 42 0 0 0 0-10z" /><path d="m10 15 5-3-5-3z" fill="currentColor" stroke="none" /></>, contact && contact.youtube],
  ].filter(function (s) { return s[2]; });
  return (
    <footer style={{ background: "#FFFFFF", color: "var(--navy)", borderTop: "1px solid var(--border-hairline)" }}>
      <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "64px 24px 32px", display: "grid", gridTemplateColumns: "1.7fr 1.1fr 1.1fr 1fr", gap: "40px" }} className="tahan-footer-grid">
        <div>
          <a href="Home.html" style={{ display: "flex", alignItems: "center", gap: "12px", textDecoration: "none" }}>
            <img src="tahan/assets/tahan-logo-lockup.png" alt="TAHAANN — Tales of Bengal" style={{ height: "62px", width: "auto", display: "block", flexShrink: 0 }} />
          </a>
          <p style={{ fontFamily: "var(--font-ui)", fontSize: "14px", lineHeight: 1.6, color: "var(--text-muted)", maxWidth: "32ch", marginTop: "16px" }}>We publish and gather what celebrates Bengal — its books, its kitchen, its looms and its clay.</p>
          <div style={{ display: "flex", flexDirection: "column", gap: "6px", marginTop: "16px", fontFamily: "var(--font-ui)", fontSize: "13px", color: "var(--text-muted)" }}>
            <a href="tel:+919007477417" style={{ color: "var(--navy)", fontWeight: 600, textDecoration: "none" }}>+91 90074 77417</a>
            <span>Business queries · <a href="mailto:operations@tahaann.com" style={{ color: "var(--coral-deep)", textDecoration: "none" }}>operations@tahaann.com</a></span>
            <span>Customer care · <a href="mailto:customercare@tahaann.com" style={{ color: "var(--coral-deep)", textDecoration: "none" }}>customercare@tahaann.com</a></span>
          </div>
          <div style={{ display: "flex", gap: "9px", marginTop: "16px" }}>
            {social.map(([name, d, url]) => (
              <a key={name} href={url} target="_blank" rel="noopener" aria-label={name} style={{ width: "32px", height: "32px", borderRadius: "var(--radius-pill)", border: "1px solid var(--border-hairline)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--navy)" }}><Ico d={d} size={17} /></a>
            ))}
          </div>
        </div>
        {linkCol("Categories", catList)}
        {linkCol("Customer Support", support)}
        {linkCol("About Us", about)}
      </div>
      <div style={{ borderTop: "1px solid var(--border-hairline)" }}>
        <div style={{ maxWidth: "1280px", margin: "0 auto", padding: "18px 24px", fontFamily: "var(--font-ui)", fontSize: "12px", color: "var(--text-muted)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: "20px", flexWrap: "wrap" }}>
          <span>
            © Copyright {new Date().getFullYear()} <span aria-hidden style={{ opacity: 0.4, margin: "0 4px" }}>|</span> Tahaann: Tales of Bengal. Designed and developed by <a href="https://branditconsultancy.in/" target="_blank" rel="noopener" style={{ color: "var(--coral-deep)", fontWeight: 600, textDecoration: "none" }}>Brandit Consultancy</a>.
          </span>
          {/* Accepted payment marks: one evenly spaced row, no rules or boxes
              between them. Each logo is trimmed artwork on a transparent
              ground, held to a common height so the set reads as one line;
              `contain` keeps a wide mark from stretching when it hits the
              width cap. Sizes and gap step down on phones (CSS below). */}
          <span className="tahan-payrow">
            {PAY_MARKS.map(([label, slug, art]) => (
              art ? <img key={slug} className="tahan-pay-mark" src={art} alt={label} title={label} loading="lazy" /> : null
            ))}
          </span>
        </div>
      </div>
      <WhatsAppFab />
    </footer>
  );
}

Object.assign(window, { Header, Footer, CartDrawer, Toast, Badgeable, NewsletterBand, Mark, Ico, useCart, loadCart, saveCart, useWishlist, loadWish, saveWish });
