// Shared UI components for Quiero.surf
// Uses window globals set from data.jsx and app.jsx

const { useState, useEffect, useRef, useMemo } = React;

// Icon set — minimal strokes, intentionally simple
function Icon({ name, size = 16 }) {
  const s = size;
  const common = { width: s, height: s, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.4, strokeLinecap: "round", strokeLinejoin: "round" };
  if (name === "search") return (
    <svg {...common}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>
  );
  if (name === "bag") return (
    <svg {...common}><path d="M5 8h14l-1 12H6z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>
  );
  if (name === "user") return (
    <svg {...common}><circle cx="12" cy="8" r="4"/><path d="M4 20c1.5-4 5-6 8-6s6.5 2 8 6"/></svg>
  );
  if (name === "heart") return (
    <svg {...common}><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10Z"/></svg>
  );
  if (name === "x") return (
    <svg {...common}><path d="M6 6l12 12M18 6 6 18"/></svg>
  );
  if (name === "arrow-right") return (
    <svg {...common}><path d="M5 12h14M13 6l6 6-6 6"/></svg>
  );
  if (name === "arrow-left") return (
    <svg {...common}><path d="M19 12H5M11 6l-6 6 6 6"/></svg>
  );
  if (name === "plus") return (
    <svg {...common}><path d="M12 5v14M5 12h14"/></svg>
  );
  if (name === "minus") return (
    <svg {...common}><path d="M5 12h14"/></svg>
  );
  if (name === "zoom") return (
    <svg {...common}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5M8 11h6M11 8v6"/></svg>
  );
  if (name === "menu") return (
    <svg {...common}><path d="M4 7h16M4 12h16M4 17h16"/></svg>
  );
  if (name === "instagram") return (
    <svg {...common}><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"/></svg>
  );
  return null;
}

// Sunburst mark used as brand flourish
function Sunburst({ size = 24, color = "currentColor" }) {
  const rays = 12;
  return (
    <svg width={size} height={size} viewBox="0 0 40 40" fill="none" stroke={color} strokeWidth="1" strokeLinecap="round">
      <circle cx="20" cy="20" r="5.5" />
      {Array.from({ length: rays }).map((_, i) => {
        const a = (i * 360 / rays) * Math.PI / 180;
        const r1 = 9, r2 = 13.5;
        const x1 = 20 + Math.cos(a) * r1, y1 = 20 + Math.sin(a) * r1;
        const x2 = 20 + Math.cos(a) * r2, y2 = 20 + Math.sin(a) * r2;
        return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} />;
      })}
    </svg>
  );
}

// Signature-style "Fernanda" script mark (just styled text)
function FernandaMark({ className = "", size = 26 }) {
  return <span className={`script ${className}`} style={{ fontSize: size, lineHeight: 1 }}>Fernanda Rodriguez</span>;
}

// Hairline, decorative section label
function SectionLabel({ children, align = "center" }) {
  return (
    <div className="micro" style={{ textAlign: align, color: "var(--ink-60)", display: "flex", gap: 12, alignItems: "center", justifyContent: align === "center" ? "center" : "flex-start" }}>
      <span style={{ width: 24, height: 1, background: "var(--ink-20)" }} />
      <span>{children}</span>
      <span style={{ width: 24, height: 1, background: "var(--ink-20)" }} />
    </div>
  );
}

// Placeholder block with optional "real photo" mode for hero
function ImageBlock({ tone = "warm", label, code, aspect = "3/4", children, real, realSrc, focus = "center", hoverZoom = false, eager = false, style = {}, onClick }) {
  const [hover, setHover] = useState(false);
  const body = real ? (
    <div
      style={{
        position: "absolute", inset: 0,
        backgroundImage: `url(${realSrc})`,
        backgroundSize: "cover",
        backgroundPosition: focus,
        transition: "transform 0.7s cubic-bezier(0.22,1,0.36,1)",
        transform: hoverZoom && hover ? "scale(1.04)" : "scale(1)",
      }}
    />
  ) : null;
  return (
    <div
      className={`placeholder ${tone}`}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      onClick={onClick}
      style={{ aspectRatio: aspect, width: "100%", cursor: onClick ? "pointer" : undefined, ...style }}
    >
      {body}
      {!real && (
        <div className="tag">
          <span>{label}</span>
          {code && <span>{code}</span>}
        </div>
      )}
      {children}
    </div>
  );
}

// Currency fmt
function fmt(n) { return "$" + n.toLocaleString("en-US"); }

// Live weather for Nosara (9.9667°N, 85.6500°W) — Open-Meteo, no key
function useNosaraWeather() {
  const [w, setW] = useState(null);
  useEffect(() => {
    let cancelled = false;
    const CACHE_KEY = "quiero_wx_v1";
    const MAX_AGE = 30 * 60 * 1000; // 30 min
    try {
      const cached = JSON.parse(localStorage.getItem(CACHE_KEY) || "null");
      if (cached && Date.now() - cached.t < MAX_AGE) { setW(cached.w); return; }
    } catch {}
    fetch("https://api.open-meteo.com/v1/forecast?latitude=9.9667&longitude=-85.65&current=temperature_2m&temperature_unit=celsius")
      .then(r => r.json())
      .then(d => {
        if (cancelled) return;
        const c = d?.current?.temperature_2m;
        if (typeof c === "number") {
          const next = { c: Math.round(c), f: Math.round(c * 9 / 5 + 32) };
          setW(next);
          try { localStorage.setItem(CACHE_KEY, JSON.stringify({ t: Date.now(), w: next })); } catch {}
        }
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);
  return w;
}

// Announcement bar
function Announce({ lang, setLang }) {
  const t = I18N[lang];
  const wx = useNosaraWeather();
  const [i, setI] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setI((p) => (p + 1) % t.announce.length), 4000);
    return () => clearInterval(id);
  }, [t.announce.length]);
  return (
    <div className="topbar">
      <span style={{ fontFamily: "var(--f-mono)", letterSpacing: "0.12em" }}>
        Nosara · {wx ? `${wx.f}°F · ${wx.c}°C` : "—"}
      </span>
      <span className="marquee">
        <span key={i} style={{ display: "inline-block", animation: "fadeSlide 4s ease" }}>{t.announce[i]}</span>
      </span>
      <div className="lang-toggle" role="tablist" aria-label="Language">
        <button className={lang === "en" ? "active" : ""} onClick={() => setLang("en")}>EN</button>
        <button className={lang === "es" ? "active" : ""} onClick={() => setLang("es")}>ES</button>
      </div>
      <style>{`
        @keyframes fadeSlide { 0%{opacity:0; transform:translateY(4px)} 12%{opacity:1; transform:translateY(0)} 88%{opacity:1; transform:translateY(0)} 100%{opacity:0; transform:translateY(-4px)} }
      `}</style>
    </div>
  );
}

// Header / navigation
function Header({ route, go, lang, setLang, bagCount, wishCount, openBag, openWish }) {
  const t = I18N[lang];
  const [menuOpen, setMenuOpen] = useState(false);
  const navItems = [
    ["shop", t.nav.shop],
    ["shop-suits", t.nav.suits],
    ["shop-onepiece", t.nav.onepiece],
    ["shop-bikini", t.nav.bikini],
    ["story", t.nav.story],
  ];
  const goAndClose = (r) => { go(r); setMenuOpen(false); };
  return (
    <>
      <Announce lang={lang} setLang={setLang} />
      <header className="header">
        <div className="header-inner">
          <button
            className="mobile-burger"
            onClick={() => setMenuOpen(true)}
            aria-label="Open menu"
            style={{ background: "transparent", border: 0, padding: 8, cursor: "pointer" }}
          >
            <Icon name="menu" size={20} />
          </button>
          <nav className="nav">
            {navItems.map(([r, label]) => (
              <a key={r} className={route === r ? "active" : ""} onClick={() => go(r)}>{label}</a>
            ))}
          </nav>
          <div className="logo" onClick={() => go("home")} role="button" style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 10 }}>
            <img src="img/qld-logo.png" alt="QLD Swimwear" style={{ height: 42, width: "auto", display: "block", mixBlendMode: "multiply" }} />
            <span style={{ fontFamily: "var(--f-display)", fontWeight: 300, fontSize: 28, letterSpacing: "0.04em" }}>Quiero</span>
          </div>
          <div className="header-right">
            <button className="icon-btn" title="Search"><Icon name="search" size={16} /></button>
            <button className="icon-btn" onClick={openWish} title="Wishlist">
              <Icon name="heart" size={16} />
              {wishCount > 0 && <span className="bag-count">{wishCount}</span>}
            </button>
            <button className="icon-btn" onClick={openBag} title="Cart">
              <Icon name="bag" size={16} /> <span>{lang === "en" ? "Cart" : "Carrito"}</span>
              {bagCount > 0 && <span className="bag-count">{bagCount}</span>}
            </button>
          </div>
        </div>
      </header>

      {/* Mobile nav drawer */}
      <div className={`mobile-nav-overlay ${menuOpen ? "open" : ""}`} onClick={() => setMenuOpen(false)} />
      <aside className={`mobile-nav ${menuOpen ? "open" : ""}`} aria-hidden={!menuOpen}>
        <div className="mobile-nav-head">
          <div style={{ fontFamily: "var(--f-display)", fontSize: 22, fontWeight: 300 }}>Quiero</div>
          <button onClick={() => setMenuOpen(false)} aria-label="Close menu" style={{ padding: 8 }}><Icon name="x" size={18} /></button>
        </div>
        <div className="mobile-nav-body">
          <a className={route === "home" ? "active" : ""} onClick={() => goAndClose("home")}>{lang === "en" ? "Home" : "Inicio"}</a>
          {navItems.map(([r, label]) => (
            <a key={r} className={route === r ? "active" : ""} onClick={() => goAndClose(r)}>{label}</a>
          ))}
        </div>
        <div className="mobile-nav-foot">
          <div className="lang-toggle" role="tablist">
            <button className={lang === "en" ? "active" : ""} onClick={() => setLang("en")}>EN</button>
            <button className={lang === "es" ? "active" : ""} onClick={() => setLang("es")}>ES</button>
          </div>
          <span className="mono" style={{ color: "var(--ink-60)" }}>Nosara · CR</span>
        </div>
      </aside>
    </>
  );
}

// Newsletter signup — POSTs to /api/subscribe
function NewsletterForm({ lang }) {
  const [email, setEmail] = useState("");
  const [hp, setHp] = useState(""); // honeypot
  const [state, setState] = useState("idle"); // idle | sending | ok | err
  const [msg, setMsg] = useState("");

  const L = lang === "es" ? {
    heading: "Boletín",
    blurb: "Piezas nuevas, notas desde Nosara. Sin spam.",
    placeholder: "tu correo",
    button: "Unirse",
    sending: "Enviando…",
    ok: "¡Listo! Revisa tu correo para la confirmación.",
    err: "No se pudo enviar. Intenta de nuevo.",
    invalid: "Correo inválido.",
  } : {
    heading: "Newsletter",
    blurb: "New pieces, notes from Nosara. No spam.",
    placeholder: "your email",
    button: "Join",
    sending: "Sending…",
    ok: "Done! Check your inbox to confirm.",
    err: "Something went wrong. Please try again.",
    invalid: "Invalid email.",
  };

  const submit = async (e) => {
    e.preventDefault();
    if (state === "sending") return;
    const em = email.trim().toLowerCase();
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(em) || em.length > 120) {
      setState("err"); setMsg(L.invalid); return;
    }
    setState("sending"); setMsg(L.sending);
    try {
      const r = await fetch("/api/subscribe", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: em, lang, website: hp }),
      });
      const j = await r.json().catch(() => ({}));
      if (r.ok && j.ok) { setState("ok"); setMsg(L.ok); setEmail(""); }
      else { setState("err"); setMsg(L.err); }
    } catch (_) { setState("err"); setMsg(L.err); }
  };

  return (
    <form onSubmit={submit} className="newsletter" style={{ display: "flex", flexDirection: "column", gap: 10, maxWidth: 360 }}>
      <h4 style={{ margin: 0 }}>{L.heading}</h4>
      <p style={{ color: "#ffffffAA", fontSize: 12, lineHeight: 1.55, margin: 0 }}>{L.blurb}</p>
      <div style={{ display: "flex", gap: 0, borderBottom: "1px solid #ffffff44", paddingBottom: 2 }}>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder={L.placeholder}
          required
          maxLength={120}
          autoComplete="email"
          disabled={state === "sending"}
          style={{
            flex: 1, background: "transparent", border: 0, color: "#fff", outline: "none",
            padding: "8px 0", fontFamily: "var(--f-mono)", fontSize: 12, letterSpacing: "0.08em",
          }}
        />
        <button
          type="submit"
          disabled={state === "sending"}
          style={{
            background: "transparent", border: 0, color: "#fff", cursor: "pointer",
            padding: "8px 0 8px 12px", fontFamily: "var(--f-mono)", fontSize: 11,
            letterSpacing: "0.22em", textTransform: "uppercase",
            opacity: state === "sending" ? 0.5 : 1,
          }}
        >
          {state === "sending" ? L.sending : L.button} →
        </button>
      </div>
      {/* honeypot: real users will never fill this */}
      <input
        type="text"
        name="website"
        value={hp}
        onChange={(e) => setHp(e.target.value)}
        autoComplete="off"
        tabIndex={-1}
        aria-hidden="true"
        style={{ position: "absolute", left: "-10000px", width: 1, height: 1, opacity: 0 }}
      />
      {msg && (
        <div
          role="status"
          aria-live="polite"
          style={{
            fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.1em", marginTop: 2,
            color: state === "ok" ? "#B7D39A" : state === "err" ? "#E6A39A" : "#ffffffAA",
          }}
        >
          {msg}
        </div>
      )}
    </form>
  );
}

// Footer
function Footer({ lang }) {
  return (
    <footer className="footer">
      <div className="row1">
        <div>
          <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
            <img src="img/qld-logo.png" alt="QLD Swimwear" style={{ height: 72, width: "auto", display: "block", filter: "invert(1) brightness(1.1)" }} />
            <div>
              <div className="signature" style={{ fontSize: 40 }}>Quiero</div>
              <div style={{ fontFamily: "var(--f-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "#ffffff88", marginTop: 4 }}>Limón Dulce · Swimwear</div>
            </div>
          </div>
          <div className="tag-line" style={{ marginTop: 20 }}>hecho en Nosara</div>
          <p style={{ marginTop: 24, maxWidth: 360, color: "#ffffffAA", fontSize: 13, lineHeight: 1.6 }}>
            {lang === "en"
              ? "A small atelier on the Pacific coast of Costa Rica. Hand-finished swim in small runs."
              : "Un pequeño atelier en la costa pacífica de Costa Rica. Trajes de baño terminados a mano en series cortas."}
          </p>
          <div style={{ marginTop: 28 }}>
            <NewsletterForm lang={lang} />
          </div>
        </div>
        <div>
          <h4>{lang === "en" ? "Shop" : "Tienda"}</h4>
          <ul>
            <li>(Bathing) Suits</li>
            <li>{lang === "en" ? "Suits" : "Conjuntos"}</li>
            <li>1 Piece</li>
            <li>Bikini</li>
            <li>{lang === "en" ? "The Archive" : "El Archivo"}</li>
            <li>{lang === "en" ? "Gift cards" : "Tarjetas regalo"}</li>
          </ul>
        </div>
        <div>
          <h4>Atelier</h4>
          <ul>
            <li>Fernanda Rodriguez</li>
            <li>{lang === "en" ? "Our atelier" : "Nuestro atelier"}</li>
            <li>{lang === "en" ? "Sustainability" : "Sostenibilidad"}</li>
            <li>Journal</li>
            <li>{lang === "en" ? "Stockists" : "Tiendas"}</li>
          </ul>
        </div>
        <div>
          <h4>{lang === "en" ? "Care" : "Ayuda"}</h4>
          <ul>
            <li>{lang === "en" ? "Size guide" : "Guía de tallas"}</li>
            <li>{lang === "en" ? "Shipping" : "Envíos"}</li>
            <li>{lang === "en" ? "Returns" : "Devoluciones"}</li>
            <li>Contact</li>
            <li>shop@quierolimondulce.com</li>
            <li>quierolimondulce.com</li>
          </ul>
        </div>
      </div>
      <div className="row2">
        <span>© MMXXVI Quiero · Nosara, CR</span>
        <span>Made with salt water</span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
          <a
            href="https://www.instagram.com/quierolimondulce"
            target="_blank"
            rel="noopener noreferrer"
            aria-label="Instagram @quierolimondulce"
            style={{ color: "inherit", display: "inline-flex", alignItems: "center", gap: 6, textDecoration: "none" }}
          >
            <Icon name="instagram" size={16} />
            <span>@quierolimondulce</span>
          </a>
        </span>
        <span>EN · ES</span>
      </div>
    </footer>
  );
}

// Wishlist heart on product card
function WishHeart({ on, onClick, size = 32 }) {
  return (
    <button className={`heart ${on ? "on" : ""}`} onClick={(e) => { e.stopPropagation(); onClick(); }} style={{ width: size, height: size }} aria-pressed={on}>
      <svg width="14" height="14" viewBox="0 0 24 24" fill={on ? "currentColor" : "none"} stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10Z"/>
      </svg>
    </button>
  );
}

// Product card — used on shop grids
function ProductCard({ p, lang, onOpen, wishOn, onWish, big = false }) {
  const [colorIdx, setColorIdx] = useState(0);
  const color = p.colors[colorIdx];
  const heroReal = p.photo?.hero;
  return (
    <article className="product-card" style={{ position: "relative" }}>
      <div style={{ position: "relative", cursor: "pointer" }} onClick={() => onOpen(p.id)}>
        {heroReal ? (
          <ImageBlock real realSrc={heroReal} aspect={big ? "4/5" : "3/4"} focus="center" hoverZoom />
        ) : (
          <ImageBlock
            tone={color.tone}
            label={`${p.name} / ${color.name[lang]}`}
            code={`QR-${p.id.slice(0,3).toUpperCase()}-${color.id.slice(0,2).toUpperCase()}`}
            aspect={big ? "4/5" : "3/4"}
            hoverZoom
          />
        )}
        {p.tag && (
          <span style={{
            position: "absolute", top: 12, left: 12,
            background: "var(--bone)", color: "var(--ink)",
            padding: "5px 10px", fontSize: 10, letterSpacing: "0.18em",
            textTransform: "uppercase", fontWeight: 500,
          }}>{p.tag[lang]}</span>
        )}
        <div style={{ position: "absolute", top: 12, right: 12 }}>
          <WishHeart on={wishOn} onClick={onWish} />
        </div>
      </div>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginTop: 16, gap: 12 }}>
        <div>
          <div className="display" style={{ fontSize: 20, lineHeight: 1.1 }}>{p.name}</div>
          <div style={{ fontSize: 12, color: "var(--ink-60)", marginTop: 4 }}>{p.subtitle[lang]}</div>
          <div className="swatch-row" style={{ marginTop: 10 }}>
            {p.colors.map((c, i) => (
              <button
                key={c.id}
                className={`swatch ${i === colorIdx ? "active" : ""}`}
                style={{ background: c.hex, width: 16, height: 16 }}
                onClick={(e) => { e.stopPropagation(); setColorIdx(i); }}
                aria-label={c.name[lang]}
              />
            ))}
          </div>
        </div>
        <div className="mono" style={{ whiteSpace: "nowrap" }}>{fmt(p.price)}</div>
      </div>
    </article>
  );
}

// Toast for "added to bag"
function Toast({ msg }) {
  return <div className={`toast ${msg ? "show" : ""}`}>{msg}</div>;
}

// Dimensions profile modal — measurements for made-to-order pieces
function DimensionsModal({ open, onClose, lang, profile, setProfile }) {
  const t = I18N[lang].pdp;
  const [draft, setDraft] = useState(profile);
  useEffect(() => { if (open) setDraft(profile); }, [open, profile]);

  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));
  const valid = draft.height && draft.bust && draft.waist;
  const unit = draft.units === "cm" ? "cm" : "in";
  const placeholder = draft.units === "cm"
    ? { height: "170", bust: "92", waist: "74" }
    : { height: "5'7\"", bust: "36", waist: "29" };

  const save = () => {
    if (!valid) return;
    setProfile(draft);
    onClose();
  };

  const clear = () => setDraft({ units: draft.units, height: "", bust: "", waist: "" });

  return (
    <>
      <div className={`modal-overlay ${open ? "open" : ""}`} onClick={onClose} />
      <div className={`modal ${open ? "open" : ""}`} role="dialog" aria-hidden={!open}>
        <div className="modal-head">
          <div>
            <div className="micro" style={{ color: "var(--terracotta)" }}>{t.madeToOrder}</div>
            <div className="title" style={{ marginTop: 8 }}><em>{t.dimensionsProfile}</em></div>
            <p style={{ fontSize: 13, color: "var(--ink-60)", marginTop: 10, maxWidth: 380, lineHeight: 1.55 }}>{t.dimensionsIntro}</p>
          </div>
          <button onClick={onClose} aria-label="Close" style={{ marginLeft: 12, marginTop: 4 }}><Icon name="x" size={18} /></button>
        </div>
        <div className="modal-body">
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <span className="micro" style={{ color: "var(--ink-60)" }}>{t.units}</span>
            <div className="unit-toggle">
              <button className={draft.units === "in" ? "active" : ""} onClick={() => set("units", "in")}>{t.inches}</button>
              <button className={draft.units === "cm" ? "active" : ""} onClick={() => set("units", "cm")}>{t.cm}</button>
            </div>
          </div>

          {[
            { key: "height", label: t.height, hint: t.howToHeight },
            { key: "bust",   label: t.bust,   hint: t.howToBust },
            { key: "waist",  label: t.waist,  hint: t.howToWaist },
          ].map(f => (
            <div key={f.key} className="dim-field">
              <div className="row">
                <label>{f.label}</label>
                <span className="mono" style={{ color: "var(--ink-40)" }}>01 · 02 · 03</span>
              </div>
              <div className="dim-input">
                <input
                  type="text"
                  value={draft[f.key]}
                  onChange={(e) => set(f.key, e.target.value)}
                  placeholder={placeholder[f.key]}
                  inputMode="decimal"
                />
                <span className="unit">{unit}</span>
              </div>
              <div className="hint">{f.hint}</div>
            </div>
          ))}

          <div style={{ marginTop: 24, padding: "16px", background: "var(--sand)", borderLeft: "2px solid var(--terracotta)" }}>
            <div className="script" style={{ fontSize: 22, color: "var(--terracotta)", lineHeight: 1 }}>
              {lang === "en" ? "Not sure?" : "¿Dudas?"}
            </div>
            <p style={{ fontSize: 13, color: "var(--ink-60)", marginTop: 6, lineHeight: 1.55 }}>
              {lang === "en"
                ? "Our atelier reviews every order — if anything looks off, Fernanda will email you before we cut a single thread."
                : "Nuestro atelier revisa cada pedido — si algo no encaja, Fernanda te escribirá antes de cortar un solo hilo."}
            </p>
          </div>
        </div>
        <div className="modal-foot">
          <button onClick={clear} className="micro" style={{ color: "var(--ink-60)", cursor: "pointer" }}>{t.clearProfile}</button>
          <button className="btn primary" onClick={save} disabled={!valid}>
            {t.saveProfile}
          </button>
        </div>
      </div>
    </>
  );
}

// Dimensions card on PDP — shows empty or filled state
function DimensionsCard({ lang, profile, onOpen }) {
  const t = I18N[lang].pdp;
  const filled = profile.height && profile.bust && profile.waist;
  return (
    <button className={`dim-card ${filled ? "filled" : ""}`} onClick={onOpen} style={{ width: "100%", textAlign: "left" }}>
      <div className="left">
        <div className="dots">
          <span className="dot" /><span className="dot" /><span className="dot" />
        </div>
        <div>
          <div className="micro">{filled ? t.savedProfile : t.addDimensions}</div>
          {filled ? (
            <div className="mono" style={{ marginTop: 6, color: "var(--ink-60)" }}>
              {t.height} {profile.height}{profile.units} · {t.bust} {profile.bust}{profile.units} · {t.waist} {profile.waist}{profile.units}
            </div>
          ) : (
            <div style={{ fontSize: 12, color: "var(--ink-60)", marginTop: 4 }}>{t.madeToOrderNote}</div>
          )}
        </div>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span className="micro" style={{ color: "var(--ink-60)" }}>{filled ? t.editDimensions : ""}</span>
        <Icon name={filled ? "arrow-right" : "plus"} size={14} />
      </div>
    </button>
  );
}

Object.assign(window, {
  Icon, Sunburst, FernandaMark, SectionLabel,
  ImageBlock, Announce, Header, Footer, Toast,
  WishHeart, ProductCard, fmt,
  DimensionsModal, DimensionsCard,
});
