/* ============ KIRO Jewelry — shared data, icons, components ============ */
const { useState, useEffect, useMemo, useRef, useCallback } = React;

/* ---------- Seed catalog ---------- */
const SEED_CATEGORIES = [
  { id: "anillos",  name: "Anillos",  tagline: "Para todos los días, para los días raros." },
  { id: "collares", name: "Collares", tagline: "Capas que cuentan una historia." },
  { id: "pulseras", name: "Pulseras", tagline: "El gesto que se queda en la muñeca." },
  { id: "aretes",   name: "Aretes",   tagline: "Pequeños detalles, grandes momentos." },
];

const SEED_PRODUCTS = [
  // Anillos
  { id: "p01", name: "Anillo Lumen",       price: 1290, category: "anillos",  material: "Plata 925 con baño de oro 18k", color: "gold",   sizes: ["5","6","7","8","9"], tag: "Nuevo",
    description: "Una banda fina con un solitario que captura la luz como una lágrima. Pensada para usarse sola o apilada con tus favoritos.",
    photos: 4 },
  { id: "p02", name: "Anillo Solenne",     price: 1690, category: "anillos",  material: "Oro 14k macizo", color: "gold",   sizes: ["5","6","7","8"],
    description: "Una silueta arquitectónica con una piedra central de circonia talla cojín. Para quien busca un statement discreto.",
    photos: 4 },
  { id: "p03", name: "Anillo Demi",        price: 890,  category: "anillos",  material: "Plata 925", color: "silver", sizes: ["6","7","8","9"], tag: "Bestseller",
    description: "El básico que no es básico: una banda media con textura cepillada y un acabado mate suave.",
    photos: 3 },
  // Collares
  { id: "p04", name: "Collar Aria",        price: 1450, category: "collares", material: "Oro 14k con perla cultivada", color: "gold",   sizes: ["40 cm","45 cm","50 cm"], tag: "Edición",
    description: "Una perla barroca suspendida sobre una cadena rolo ultra fina. Una pieza para los días en que quieres flotar.",
    photos: 4 },
  { id: "p05", name: "Collar Vega",        price: 1190, category: "collares", material: "Plata 925 con baño de oro 18k", color: "gold",   sizes: ["42 cm","45 cm"],
    description: "Cadena gargantilla de eslabón medio, terminada a mano. La pieza que se pone una vez y nunca se quita.",
    photos: 3 },
  { id: "p06", name: "Collar Mira",        price: 1590, category: "collares", material: "Oro 14k macizo", color: "gold",   sizes: ["40 cm","45 cm"], tag: "Nuevo",
    description: "Tres dijes geométricos en oro pulido, suspendidos de una cadena box delicada. Cada dije se mueve de forma independiente.",
    photos: 4 },
  // Pulseras
  { id: "p07", name: "Pulsera Sole",       price: 990,  category: "pulseras", material: "Oro 14k con piedras semipreciosas", color: "gold",   sizes: ["S (16 cm)","M (18 cm)","L (20 cm)"],
    description: "Una hilera de granates engastados a mano sobre una cadena cable. Se ajusta con un cierre desliable.",
    photos: 3 },
  { id: "p08", name: "Pulsera Cleo",       price: 1290, category: "pulseras", material: "Plata 925 envejecida", color: "silver", sizes: ["S","M","L"], tag: "Bestseller",
    description: "Eslabón cubano fundido en plata maciza, con un cierre de mosquetón firme. Pesa, y se siente.",
    photos: 4 },
  // Aretes
  { id: "p09", name: "Aretes Lila",        price: 690,  category: "aretes",   material: "Plata 925 con baño de oro 18k", color: "gold",   sizes: ["Único"],
    description: "Aros pequeños con textura martillada. Para usar todos los días, en pares o desparejados.",
    photos: 3 },
  { id: "p10", name: "Aretes Mer",         price: 1190, category: "aretes",   material: "Oro 14k con topacios", color: "gold",   sizes: ["Único"], tag: "Edición",
    description: "Aretes drop con un topacio azul talla pera. La piedra se mueve, atrapa luz, y desaparece bajo el cabello.",
    photos: 4 },
  { id: "p11", name: "Aretes Studs Pavé",  price: 890,  category: "aretes",   material: "Plata 925 con circonias", color: "silver", sizes: ["Único"],
    description: "Studs redondos de 6 mm cubiertos en pavé. La pieza que reemplaza a tus piercings básicos para siempre.",
    photos: 3 },
  { id: "p12", name: "Aretes Helena",      price: 1390, category: "aretes",   material: "Oro 14k con perlas cultivadas", color: "gold",   sizes: ["Único"], tag: "Nuevo",
    description: "Argollas medianas con una perla cultivada que se desliza libremente sobre el aro. Movimiento y luz.",
    photos: 4 },
];

/* ---------- Seed content (editable from admin) ---------- */
const SEED_CONTENT = {
  utilityBar: "Envío gratis en pedidos sobre S/ 350 · 30 días de garantía · Hecho en Perú",
  hero: {
    eyebrow: "Colección · Otoño / Invierno 26",
    titleLine1: "Pequeñas piezas,",
    titleLine2: "grandes rituales.",
    body: "Joyería hecha a mano para usarse a diario. Oro 14k macizo, plata 925 y piedras seleccionadas, fabricadas en Cusco en lotes pequeños.",
    cta1: "Ver colección",
    cta2: "Conoce los materiales",
    image: null,
    imagePositionMobile: "right center",
    cornerMeta: "01 — Lookbook",
    cornerCredit: "Fotografía: estudio kiro",
  },
  values: [
    { icon: "leaf",   title: "Materiales", body: "Oro 14k macizo, plata 925 reciclada y piedras seleccionadas a mano." },
    { icon: "truck",  title: "Envíos",     body: "Gratis a partir de S/ 350. Entregas de 2 a 5 días en todo Perú." },
    { icon: "shield", title: "Garantía",   body: "Reparaciones de por vida. Cambios y devoluciones sin preguntas durante 30 días." },
    { icon: "box",    title: "Empaque",    body: "Caja de cartón reciclado, bolsita de algodón orgánico, sin plásticos." },
  ],
  editorial: {
    eyebrow: "El taller",
    titleStart: "Cada pieza pasa",
    titleItalic: "por once manos",
    titleEnd: "antes de llegar a la tuya.",
    body: "Trabajamos con un equipo de orfebres en Cusco — una tradición platera viva desde la época prehispánica. Cada pieza se funde, lima, pule y engasta a mano. Sin máquinas, sin atajos, sin prisa.",
    cta: "Conocer a los artesanos",
    image: null,
  },
  footer: {
    tagline: "Joyería contemporánea hecha a mano en pequeños lotes. Diseñada en Lima, fabricada en Cusco.",
    col1Title: "Tienda",
    col2Title: "Cuidado",
    col2Body: "Damos mantenimiento gratuito de por vida a todas nuestras piezas: pulido, baño y ajustes. Reparaciones sin costo cuando son por uso natural. Solo escríbenos y nos encargamos.",
    col3Title: "Nosotros",
    col3Items: ["Historia", "Artesanos", "Sustentabilidad", "Tiendas físicas", "Contacto"],
    sizingTitle: "¿No sabes tu talla?",
    sizingButtonLabel: "Guía de tallas de anillos",
    sizingImage: null,
    sizingContent:
      "Hay tres formas confiables de saber tu talla de anillo en casa. Tómate un par de minutos, es más fácil de lo que parece.\n\n" +
      "MÉTODO 1 — Medir un anillo que ya te quede bien\n" +
      "1. Elige un anillo que uses en el dedo donde quieres el nuevo.\n" +
      "2. Apoya el anillo sobre una regla y mide el diámetro interior (de borde interno a borde interno) en milímetros.\n" +
      "3. Compara con nuestra tabla:\n" +
      "   • 15.7 mm → talla 5\n" +
      "   • 16.5 mm → talla 6\n" +
      "   • 17.3 mm → talla 7\n" +
      "   • 18.1 mm → talla 8\n" +
      "   • 18.9 mm → talla 9\n" +
      "   • 19.8 mm → talla 10\n\n" +
      "MÉTODO 2 — Tira de papel\n" +
      "1. Corta una tira de papel de aproximadamente 1 cm de ancho.\n" +
      "2. Envuélvela alrededor del dedo, justo en la base.\n" +
      "3. Marca con un lápiz dónde se cruzan los extremos.\n" +
      "4. Estira la tira y mide los milímetros entre las dos marcas: esa es la circunferencia.\n" +
      "5. Compara: 49 mm = talla 5 · 51.5 mm = talla 6 · 54 mm = talla 7 · 56.5 mm = talla 8 · 59 mm = talla 9 · 62 mm = talla 10.\n\n" +
      "MÉTODO 3 — Pídenos un medidor por WhatsApp\n" +
      "Si quieres tener total seguridad antes de comprar, escríbenos por WhatsApp y te enviamos un medidor de papel gratis a tu casa, o agendamos una cita para tomarte la medida en persona.\n\n" +
      "TIPS\n" +
      "• Mídete al final del día, cuando los dedos están un poco más hinchados.\n" +
      "• Evita medirte si tienes mucho frío o calor.\n" +
      "• Si quedas entre dos tallas, elige la mayor.\n" +
      "• Para anillos anchos (más de 6 mm) considera una talla más.",
    copyrightLeft: "© 2026 KIRO Jewelry",
    copyrightRight: "Hecho con cariño en PE · Lima → Cusco",
  },
  social: {
    instagram: "https://instagram.com/kirojewelry",
    tiktok:    "https://tiktok.com/@kirojewelry",
    whatsapp:  "https://wa.me/51954796222",
  },
};

/* ---------- Content deep-merge ----------
 * Used to fill in any missing keys on a partial content object loaded from
 * the DB. Keeps the app resilient to schema additions over time without
 * having to do a migration each time. */
function mergeContent(partial) {
  const c = partial || {};
  return {
    ...SEED_CONTENT,
    ...c,
    hero:      { ...SEED_CONTENT.hero,      ...(c.hero      || {}) },
    footer:    { ...SEED_CONTENT.footer,    ...(c.footer    || {}) },
    editorial: { ...SEED_CONTENT.editorial, ...(c.editorial || {}) },
    social:    { ...SEED_CONTENT.social,    ...(c.social    || {}) },
    values: c.values || SEED_CONTENT.values,
  };
}

/* ---------- Format ---------- */
const fmtPrice = (n) => "S/ " + Number(n).toLocaleString("es-PE");

/* ---------- Icons (line, burgundy) ---------- */
const Icon = ({ name, size = 18 }) => {
  const paths = {
    search:   <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
    user:     <><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/></>,
    bag:      <><path d="M5 7h14l-1.2 12.2a2 2 0 0 1-2 1.8H8.2a2 2 0 0 1-2-1.8L5 7Z"/><path d="M9 7V5a3 3 0 0 1 6 0v2"/></>,
    heart:    <><path d="M12 20s-7-4.5-9-9.5C1.5 6.5 5 4 7.5 4c1.7 0 3.3.9 4.5 2.4C13.2 4.9 14.8 4 16.5 4 19 4 22.5 6.5 21 10.5 19 15.5 12 20 12 20Z"/></>,
    menu:     <><path d="M4 7h16M4 12h16M4 17h16"/></>,
    arrow:    <><path d="M5 12h14M13 5l7 7-7 7"/></>,
    chevR:    <><path d="m9 6 6 6-6 6"/></>,
    chevD:    <><path d="m6 9 6 6 6-6"/></>,
    close:    <><path d="M6 6 18 18M6 18 18 6"/></>,
    plus:     <><path d="M12 5v14M5 12h14"/></>,
    edit:     <><path d="M16 3.5 20.5 8 8 20.5H3.5V16L16 3.5Z"/></>,
    trash:    <><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></>,
    check:    <><path d="m5 12 5 5L20 7"/></>,
    star:     <><path d="m12 3 2.6 6 6.4.6-4.8 4.3 1.5 6.3L12 17l-5.7 3.2L7.8 14 3 9.6 9.4 9z"/></>,
    truck:    <><path d="M3 7h11v10H3z"/><path d="M14 10h4l3 3v4h-7"/><circle cx="7" cy="18" r="2"/><circle cx="17" cy="18" r="2"/></>,
    shield:   <><path d="M12 3 4 6v6c0 5 3.5 8.5 8 9 4.5-.5 8-4 8-9V6l-8-3Z"/></>,
    leaf:     <><path d="M4 20c8 0 14-6 14-14V4h-2C8 4 4 10 4 18Z"/><path d="M4 20 14 10"/></>,
    // unused — whatsapp is rendered as a filled glyph below
    whatsapp: null,
    chart:    <><path d="M4 20V8M10 20V4M16 20v-8M22 20H2"/></>,
    box:      <><path d="m3 7 9-4 9 4M3 7v10l9 4 9-4V7M3 7l9 4M21 7l-9 4M12 11v10"/></>,
    tag:      <><path d="M3 12V3h9l9 9-9 9-9-9Z"/><circle cx="8" cy="8" r="1.5"/></>,
    instagram:<><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.6" fill="currentColor" stroke="none"/></>,
    tiktok:   <><path d="M13 4v10.5a3.5 3.5 0 1 1-3.5-3.5"/><path d="M13 4c.2 2.4 2 4.2 4.5 4.4"/></>,
  };
  if (name === "whatsapp") {
    return (
      <svg width={size} height={size} viewBox="0 0 24 24"
           fill="currentColor" stroke="none" aria-hidden="true">
        <path d="M19.05 4.91A9.816 9.816 0 0 0 12.04 2c-5.46 0-9.91 4.45-9.91 9.91 0 1.75.46 3.45 1.32 4.95L2.05 22l5.25-1.38c1.45.79 3.08 1.21 4.74 1.21h.01c5.46 0 9.91-4.45 9.91-9.91 0-2.65-1.03-5.14-2.91-7.01zm-7.01 15.24c-1.48 0-2.93-.4-4.2-1.15l-.3-.18-3.12.82.83-3.04-.2-.31a8.264 8.264 0 0 1-1.26-4.38c0-4.54 3.7-8.24 8.24-8.24 2.2 0 4.27.86 5.82 2.42a8.183 8.183 0 0 1 2.41 5.83c.02 4.54-3.68 8.23-8.22 8.23zm4.52-6.16c-.25-.12-1.47-.72-1.69-.81-.23-.08-.39-.12-.56.12-.17.25-.64.81-.78.97-.14.17-.29.19-.54.06-.25-.12-1.05-.39-1.99-1.23-.74-.66-1.23-1.47-1.38-1.72-.14-.25-.02-.38.11-.51.11-.11.25-.29.37-.43.12-.14.17-.25.25-.41.08-.17.04-.31-.02-.43-.06-.12-.56-1.34-.76-1.84-.2-.48-.41-.42-.56-.43h-.48c-.17 0-.43.06-.66.31-.22.25-.86.85-.86 2.07 0 1.22.89 2.4 1.01 2.56.12.17 1.75 2.67 4.23 3.74.59.26 1.05.41 1.41.52.59.19 1.13.16 1.56.1.48-.07 1.47-.6 1.67-1.18.21-.58.21-1.07.14-1.18s-.22-.16-.47-.28z"/>
      </svg>
    );
  }
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
         stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      {paths[name]}
    </svg>
  );
};

/* ---------- Image placeholder with deterministic style per product ---------- */
function ProductImg({ p, idx = 0, label }) {
  // If a real image is uploaded, prefer it
  const images = Array.isArray(p.images) ? p.images.filter(Boolean) : (p.image ? [p.image] : []);
  if (images.length > 0) {
    const src = images[idx % images.length] || images[0];
    return (
      <div className="img-ph" style={{ padding: 0, border: "1px solid var(--line-2)", background: "var(--cream)" }}>
        <img src={src} alt={p.name || ""} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }}/>
        {label && (
          <div className="label" style={{ position: "absolute", bottom: 10, left: 10 }}>{label}</div>
        )}
      </div>
    );
  }
  // deterministic background tint based on product id
  const seed = (p.id || "x").charCodeAt(0) + (p.id || "x").charCodeAt(p.id.length-1) + idx;
  const palette = [
    { bg: "#FBF1EE", grain: "rgba(107,31,37,0.06)" },
    { bg: "#F2D6D1", grain: "rgba(107,31,37,0.08)" },
    { bg: "#E8C9C3", grain: "rgba(107,31,37,0.1)" },
    { bg: "#6B1F25", grain: "rgba(255,255,255,0.06)", dark: true },
    { bg: "#3A1418", grain: "rgba(255,255,255,0.04)", dark: true },
  ];
  const sel = palette[seed % palette.length];
  // simple decorative shape suggestion based on category
  const cat = p.category;
  const shapeFor = {
    anillos:  <g><circle cx="100" cy="115" r="36" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/><circle cx="100" cy="115" r="44" stroke={sel.dark ? "rgba(252,234,231,0.3)":"rgba(107,31,37,0.22)"} strokeWidth="0.8" fill="none"/><path d="M91 71 L100 60 L109 71 L105 78 L95 78 Z" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/><path d="M95 78 L100 60 L105 78" stroke={sel.dark ? "rgba(252,234,231,0.3)":"rgba(107,31,37,0.22)"} strokeWidth="0.8" fill="none"/></g>,
    collares: <g><path d="M30 50 Q100 130 170 50" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none" strokeDasharray="2 4"/><circle cx="100" cy="130" r="10" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/></g>,
    pulseras: <g><ellipse cx="100" cy="115" rx="55" ry="18" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/><ellipse cx="100" cy="115" rx="55" ry="18" stroke={sel.dark ? "rgba(252,234,231,0.3)":"rgba(107,31,37,0.18)"} strokeWidth="0.8" fill="none" transform="rotate(8 100 115)"/></g>,
    aretes:   <g><circle cx="80" cy="100" r="22" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/><circle cx="120" cy="100" r="22" stroke={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.4)"} strokeWidth="1.2" fill="none"/><circle cx="80" cy="100" r="2" fill={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.5)"} /><circle cx="120" cy="100" r="2" fill={sel.dark ? "rgba(252,234,231,0.55)":"rgba(107,31,37,0.5)"} /></g>,
  }[cat];

  return (
    <div className="img-ph" style={{ background: `repeating-linear-gradient(135deg, ${sel.grain} 0 1px, transparent 1px 14px), ${sel.bg}`, borderColor: sel.dark ? "rgba(255,255,255,0.1)" : "rgba(107,31,37,0.1)" }}>
      <svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet"
           style={{ position:"absolute", inset:0, width:"100%", height:"100%" }}>
        {shapeFor}
      </svg>
      {label && (
        <div className="label" style={{ position:"absolute", bottom: 10, left: 10,
          color: sel.dark ? "rgba(252,234,231,0.7)" : "rgba(107,31,37,0.55)",
          background: sel.dark ? "rgba(0,0,0,0.25)" : "rgba(251,244,241,0.7)",
          borderColor: sel.dark ? "rgba(255,255,255,0.15)" : "rgba(107,31,37,0.2)" }}>
          {label}
        </div>
      )}
    </div>
  );
}

/* ---------- Brand logo lockup ---------- */
function BrandLogo({ size = 26, sub = true, color }) {
  const c = color || "var(--burgundy)";
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1 }}>
      <div style={{
        fontFamily: "var(--serif)", fontWeight: 500, fontSize: size,
        letterSpacing: "0.16em", color: c,
        display: "inline-flex", alignItems: "flex-end", gap: 0,
      }}>
        <span style={{ display: "inline-block" }}>KIR</span>
        <svg
          viewBox="0 0 100 140"
          width={size * 0.9}
          height={size * 1.26}
          fill="none"
          stroke={c}
          strokeWidth="6"
          strokeLinejoin="round"
          strokeLinecap="round"
          style={{ marginLeft: size * 0.12, display: "block", overflow: "visible" }}
          aria-hidden="true"
        >
          {/* diamond crown */}
          <path d="M30 56 L50 12 L70 56 Z"/>
          <path d="M30 56 L70 56"/>
          <path d="M42 56 L50 12 L58 56"/>
          {/* ring band (double circle) */}
          <circle cx="50" cy="96" r="38"/>
          <circle cx="50" cy="96" r="30"/>
        </svg>
      </div>
      {sub && (
        <div style={{
          fontFamily: "var(--serif)", fontSize: size * 0.36,
          letterSpacing: "0.36em", color: c,
          textTransform: "uppercase", marginTop: 4,
        }}>JEWELRY</div>
      )}
    </div>
  );
}

/* ---------- Social links (used in header + footer) ---------- */
function SocialLinks({ social, size = 20, variant = "default" }) {
  const items = [
    { key: "instagram", url: social?.instagram, label: "Instagram", icon: "instagram" },
    { key: "tiktok",    url: social?.tiktok,    label: "TikTok",    icon: "tiktok" },
    { key: "whatsapp",  url: social?.whatsapp,  label: "WhatsApp",  icon: "whatsapp" },
  ].filter(x => x.url && String(x.url).trim());
  if (items.length === 0) return null;
  return (
    <div className={`social-links social-links--${variant}`}>
      {items.map(it => (
        <a key={it.key}
           href={it.url}
           target="_blank"
           rel="noopener noreferrer"
           aria-label={it.label}
           className="social-link">
          <Icon name={it.icon} size={size}/>
        </a>
      ))}
    </div>
  );
}

/* ---------- Header ---------- */
function Header({ route, navigate, bagCount = 0, store }) {
  const cats = (store && store.categories) || SEED_CATEGORIES;
  const utilityText = store?.content?.utilityBar ?? SEED_CONTENT.utilityBar;
  const [menuOpen, setMenuOpen] = useState(false);

  // Close drawer when the route changes
  useEffect(() => { setMenuOpen(false); }, [route.path]);

  // Lock body scroll while drawer is open
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  const go = (path) => { setMenuOpen(false); navigate(path); };

  return (
    <>
      <div className="utility-bar">{utilityText}</div>
      <header className="site-header">
        <div className="header-inner">
          <nav className="nav-left">
            {cats.map(c => (
              <a key={c.id}
                 className={`nav-link ${route.path === "/c/"+c.id ? "active" : ""}`}
                 onClick={() => navigate("/c/" + c.id)}>{c.name}</a>
            ))}
          </nav>
          <button
            className={`menu-btn ${menuOpen ? "open" : ""}`}
            aria-label={menuOpen ? "Cerrar menú" : "Abrir menú"}
            aria-expanded={menuOpen}
            onClick={() => setMenuOpen(o => !o)}
          >
            <span/><span/><span/>
          </button>
          <a onClick={() => navigate("/")} style={{ cursor: "pointer", display: "inline-flex", alignItems: "center" }}>
            <span className="brand-logo-text" aria-label="KIRO Jewelry">KIRO</span>
          </a>
          <div className="nav-right">
            <SocialLinks
              social={{
                instagram: store?.content?.social?.instagram,
                tiktok:    store?.content?.social?.tiktok,
              }}
              size={20}
              variant="header"
            />
          </div>
        </div>
      </header>

      <nav className={`mobile-drawer ${menuOpen ? "open" : ""}`} aria-hidden={!menuOpen}>
        <a onClick={() => go("/")}>Inicio</a>
        {cats.map(c => (
          <a key={c.id} onClick={() => go("/c/" + c.id)}>{c.name}</a>
        ))}
        <a className="secondary" onClick={() => go("/")}>Buscar</a>
        <a className="secondary" onClick={() => go("/")}>
          Bolsa {bagCount > 0 ? `(${bagCount})` : ""}
        </a>
      </nav>
    </>
  );
}

/* ---------- Footer ---------- */
function Footer({ store, navigate, openSizeGuide }) {
  const f = store?.content?.footer ?? SEED_CONTENT.footer;
  const cats = (store && store.categories) || SEED_CATEGORIES;
  return (
    <footer className="site-footer">
      <div className="footer-grid">
        <div>
          <div style={{ display: "flex", marginBottom: 24 }}>
            <span className="footer-logo-text" aria-label="KIRO Jewelry">KIRO</span>
          </div>
          <p style={{ fontSize: 13, lineHeight: 1.7, color: "var(--pink-200)", maxWidth: 280 }}>
            {f.tagline}
          </p>
          <div className="footer-sizing-cta">
            <div className="footer-sizing-title">{f.sizingTitle}</div>
            <button
              type="button"
              className="footer-sizing-btn"
              onClick={() => openSizeGuide && openSizeGuide()}
            >
              {f.sizingButtonLabel} <span aria-hidden="true">→</span>
            </button>
          </div>
        </div>
        <div>
          <h4>{f.col1Title}</h4>
          <ul>
            {cats.map(c => (
              <li key={c.id}>
                <a
                  className="footer-link"
                  href={"#/c/" + c.id}
                  onClick={(e) => {
                    if (navigate) {
                      e.preventDefault();
                      navigate("/c/" + c.id);
                    }
                  }}
                >{c.name}</a>
              </li>
            ))}
          </ul>
        </div>
        <div>
          <h4>{f.col2Title}</h4>
          <p className="footer-paragraph">{f.col2Body}</p>
        </div>
        <div>
          <h4>{f.col3Title}</h4>
          <SocialLinks social={store?.content?.social} size={22} variant="footer"/>
        </div>
      </div>
      <div className="footer-bottom">
        <span>{f.copyrightLeft}</span>
        <span>{f.copyrightRight}</span>
      </div>
    </footer>
  );
}

/* ---------- Size guide modal ---------- */
function SizeGuideModal({ open, onClose, title, content, image }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [open, onClose]);

  if (!open) return null;
  return (
    <div className="size-guide-overlay" onClick={onClose}>
      <div className="size-guide-card" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
        <button className="size-guide-close" onClick={onClose} aria-label="Cerrar">
          <Icon name="close" size={20}/>
        </button>
        <div className="eyebrow" style={{ color: "var(--burgundy-soft)" }}>KIRO · Guía</div>
        <h2 className="size-guide-title">{title}</h2>
        {image ? (
          <img src={image} alt={title} className="size-guide-image"/>
        ) : (
          <div className="size-guide-body">{content}</div>
        )}
      </div>
    </div>
  );
}

/* ---------- Product card ---------- */
function ProductCard({ p, onClick }) {
  return (
    <div className="product-card" onClick={onClick}>
      <div className="img-wrap">
        <ProductImg p={p} />
        {p.tag && <span className="tag">{p.tag}</span>}
        <div className="quick">Vista rápida</div>
      </div>
      <div>
        <div className="name">{p.name}</div>
        <div className="price">{fmtPrice(p.price)}</div>
      </div>
    </div>
  );
}

/* Export to window so other JSX files can use them */
Object.assign(window, {
  SEED_CATEGORIES, SEED_PRODUCTS, SEED_CONTENT, mergeContent,
  fmtPrice,
  Icon, ProductImg, BrandLogo, Header, Footer, ProductCard, SizeGuideModal, SocialLinks,
});
