/* global React, Icon */
// Shared UI primitives — Button, Kicker, cards, banners, info blocks.

// ───────────────────────── Button ─────────────────────────
function Button({
  variant = "primary",
  size = "md",
  iconLeft,
  iconRight,
  as = "button",
  href,
  onClick,
  disabled,
  children,
  className = "",
  type = "button",
  ariaLabel
}) {
  const base = "inline-flex items-center justify-center gap-2 font-sans font-semibold uppercase tracking-eyebrow rounded-btn transition-all duration-200 ease-out select-none";
  const sizes = {
    sm: "text-[12px] px-3 h-9 tracking-[0.10em]",
    md: "text-[13px] px-5 h-12 tracking-[0.08em]",
    lg: "text-[14px] px-7 h-14 tracking-[0.08em]"
  };
  const variants = {
    primary: "bg-primary text-white shadow-soft hover:bg-primary-dark hover:shadow-card",
    secondary: "bg-foam text-primary hover:bg-primary hover:text-white",
    "primary-light": "bg-white text-primary hover:bg-foam",
    "outline-light": "bg-white/15 text-white backdrop-blur-sm hover:bg-white hover:text-primary",
    tertiary: "text-primary hover:text-primary-dark normal-case tracking-normal !font-semibold !text-[15px] !px-0 !h-auto",
    ghost: "text-ink/80 hover:bg-foam normal-case tracking-normal",
    danger: "bg-danger text-white hover:bg-red-800"
  };
  const cls = [
  base,
  sizes[size],
  variants[variant],
  disabled ? "opacity-50 cursor-not-allowed pointer-events-none" : "cursor-pointer",
  className].
  join(" ");

  const inner =
  <>
      {iconLeft && <Icon name={iconLeft} size={size === "lg" ? 18 : 16} />}
      <span>{children}</span>
      {iconRight && <Icon name={iconRight} size={size === "lg" ? 18 : 16} />}
    </>;


  if (as === "a") {
    return <a href={href} className={cls} aria-label={ariaLabel} onClick={onClick}>{inner}</a>;
  }
  return <button type={type} disabled={disabled} onClick={onClick} className={cls} aria-label={ariaLabel}>{inner}</button>;
}

// ───────────────────────── Kicker ─────────────────────────
function Kicker({ children, className = "" }) {
  return <div className={"eyebrow " + className}>{children}</div>;
}

// ───────────────────────── SectionHead ─────────────────────────
function SectionHead({ kicker, title, lead, center, light }) {
  const c = center ? "text-center mx-auto" : "";
  return (
    <div className={(center ? "text-center max-w-[760px] mx-auto " : "max-w-[760px] ") + "mb-10 md:mb-14"}>
      {kicker && <div className={"eyebrow mb-3 " + (light ? "!text-foam/80" : "")}>{kicker}</div>}
      {title && <h2 className={"h-section " + (light ? "!text-white" : "") + " " + c}>{title}</h2>}
      {lead && <p className={"lead mt-4 " + (light ? "!text-white/85" : "")}>{lead}</p>}
    </div>);

}

// ───────────────────────── OysterCard ─────────────────────────
// Type-driven, no photo — un vrai libellé d'étiquette ostréicole.
function OysterCard({ calibre, name, meta, weight, count, onClick }) {
  // Visual size — bigger oyster = smaller calibre number
  const sizes = { "2": 1.0, "3": 0.84, "4": 0.7, "5": 0.58 };
  const s = sizes[String(calibre)] ?? 0.8;
  return (
    <a
      onClick={onClick}
      className="group block cursor-pointer rounded-card overflow-hidden bg-white shadow-soft hover:shadow-marine transition-all duration-300">
      
      {/* Top label area — clean, type-led */}
      <div className="relative px-5 pt-6 pb-5 bg-foam/50 overflow-hidden">
        {/* Watermark numeral */}
        <span
          aria-hidden="true"
          className="absolute -right-4 -bottom-10 font-serif text-primary/5 leading-none select-none pointer-events-none"
          style={{ fontSize: `${180 * s}px` }}>
          
          n°{calibre}
        </span>
        <div className="relative">
          <div className="eyebrow !text-primary/70 text-[11px]">Gigas Meduli</div>
          <div className="font-serif text-primary text-[44px] md:text-[56px] leading-[0.95] mt-1">n°{calibre}</div>
          <div className="font-serif text-primary text-[16px] md:text-[18px] italic leading-tight mt-1.5 whitespace-nowrap overflow-hidden text-ellipsis">{name}</div>
        </div>
      </div>
      {/* Bottom data */}
      <div className="p-5">
        <dl className="space-y-1.5 text-[14px]">
          <div className="flex justify-between gap-3"><dt className="text-mute">Poids</dt><dd className="text-ink font-medium text-right">{weight || meta?.split('·')[0]?.trim()}</dd></div>
          <div className="flex justify-between gap-3"><dt className="text-mute">Quantité</dt><dd className="text-ink font-medium text-right">{count || meta?.split('·')[1]?.trim()}</dd></div>
        </dl>
      </div>
    </a>);

}

// ───────────────────────── ProductCard (other) ─────────────────────────
function ProductCard({ name, hint, tag, img, origin }) {
  return (
    <div className="panel overflow-hidden hover:shadow-marine transition-shadow duration-300 flex flex-col">
      <div className="aspect-photo overflow-hidden bg-foam relative">
        {img ? <img src={img} alt="" className="w-full h-full object-cover" loading="lazy" /> : <div className="w-full h-full img-shimmer" />}
        {tag && <div className="absolute top-3 left-3 bg-white/95 text-primary text-[11px] font-semibold tracking-eyebrow uppercase px-2.5 py-1 rounded-full shadow-soft">{tag}</div>}
      </div>
      <div className="p-5 flex-1 flex flex-col">
        <h3 className="font-serif text-primary text-[20px] leading-tight mb-1">{name}</h3>
        {hint && <p className="text-[14px] text-ink/75 leading-snug mb-3">{hint}</p>}
        {origin &&
        <div className="mt-auto pt-3">
            <span className="text-[12px] text-mute uppercase tracking-eyebrow">{origin}</span>
          </div>
        }
      </div>
    </div>);

}

// ───────────────────────── PlaceCard ─────────────────────────
function PlaceCard({ icon = "store", kind, name, address, hours, phone, accent, children }) {
  return (
    <div className={"panel p-6 md:p-7 flex flex-col gap-3 " + (accent ? "bg-foam" : "")}>
      <div className="flex items-center gap-2 eyebrow">
        <Icon name={icon} size={14} />
        <span>{kind}</span>
      </div>
      <h3 className="font-serif text-primary text-[24px] md:text-[26px] leading-tight">{name}</h3>
      {address && <p className="text-ink/85 text-[15px] leading-snug flex items-start gap-2"><Icon name="map-pin" size={16} className="text-primary-light mt-1" /><span>{address}</span></p>}
      {hours && <p className="text-ink/85 text-[15px] leading-snug flex items-start gap-2"><Icon name="clock" size={16} className="text-primary-light mt-1" /><span>{hours}</span></p>}
      {phone && <a href={"tel:" + phone.replace(/\s+/g, '')} className="text-primary text-[15px] flex items-center gap-2 hover:text-primary-dark"><Icon name="phone" size={16} />{phone}</a>}
      {children}
    </div>);

}

// ───────────────────────── CTA Banner ─────────────────────────
function CtaBanner({ image, title, subtitle, primary, secondary, onPrimary, onSecondary }) {
  return (
    <section className="relative overflow-hidden">
      <div className="absolute inset-0">
        {image ? <img src={image} alt="" className="w-full h-full object-cover" /> : <div className="w-full h-full bg-primary-dark" />}
        <div className="absolute inset-0 bg-primary-dark/70" />
        <div className="absolute inset-0 bg-gradient-to-r from-primary-dark/40 to-transparent" />
      </div>
      <div className="container-x relative py-20 md:py-28 text-white">
        <div className="max-w-[760px]">
          <h2 className="font-serif text-[32px] md:text-[52px] leading-[1.05] tracking-[-0.01em] text-white">{title}</h2>
          {subtitle && <p className="mt-5 text-[18px] md:text-[20px] text-white/85 max-w-prose-tight leading-[1.55]">{subtitle}</p>}
          <div className="mt-8 flex flex-wrap gap-3">
            {primary && <Button variant="primary-light" size="lg" iconRight="arrow-right" onClick={onPrimary}>{primary}</Button>}
            {secondary && <Button variant="outline-light" size="lg" onClick={onSecondary}>{secondary}</Button>}
          </div>
        </div>
      </div>
    </section>);

}

// ───────────────────────── Press strip ─────────────────────────
function PressStrip({ onMore }) {
  const items = [
  { name: "France 3", src: "assets/press/france-3.png" },
  { name: "Agence Nouvelle-Aquitaine", src: "assets/press/aana.png" },
  { name: "Mes Escapades", src: "assets/press/mes-escapades.png" },
  { name: "Bordeauxfood", src: "assets/press/bordeauxfood.png" }];

  return (
    <section className="py-14 md:py-16 bg-foam/40">
      <div className="container-x">
        <div className="flex flex-wrap items-center justify-between gap-4 mb-8">
          <div>
            <div className="eyebrow mb-1">Vu dans la presse</div>
            <h3 className="font-serif text-primary text-[24px] md:text-[28px] leading-tight">Ils parlent de nous</h3>
          </div>
          {onMore && <Button variant="tertiary" iconRight="arrow-right" onClick={onMore}>Toutes nos parutions</Button>}
        </div>
        <div className="flex flex-wrap items-center justify-center gap-x-10 md:gap-x-14 gap-y-6">
          {items.map((it) =>
          <div key={it.name} className="h-12 md:h-14 grid place-items-center">
              <img src={it.src} alt={it.name} className="max-h-full max-w-[120px] w-auto object-contain opacity-90 grayscale-[10%] hover:grayscale-0 hover:opacity-100 transition" loading="lazy" />
            </div>
          )}
        </div>
      </div>
    </section>);

}

// ───────────────────────── InfoBox ─────────────────────────
function InfoBox({ icon = "info", title, children, variant = "info" }) {
  const styles = {
    info: "bg-foam text-ink",
    warning: "bg-[#FFFBEB] text-[#92400E]",
    success: "bg-[#ECFDF5] text-[#065F46]"
  };
  const iconColor = {
    info: "text-primary",
    warning: "text-warning",
    success: "text-success"
  };
  return (
    <div className={"rounded-card p-4 md:p-5 flex gap-3 items-start " + styles[variant]}>
      <Icon name={icon} size={20} className={iconColor[variant]} />
      <div className="flex-1">
        {title && <div className="font-semibold text-[15px] mb-1">{title}</div>}
        <div className="text-[14px] md:text-[15px] leading-[1.55]">{children}</div>
      </div>
    </div>);

}

// ───────────────────────── Stylized Map Mock ─────────────────────────
// Leaflet would be ideal in prod; we render a stylized SVG with the 3 markers
// for a polished offline-friendly mock. Markers can be enriched with hours,
// photo, address & a one-click itinerary link.
function MapMock({ height = 380, markers = [], compact = false, className = "" }) {
  const [activeIdx, setActiveIdx] = React.useState(null);
  // 3 markers default if none
  const m = markers.length ? markers : [
  { label: "Boutique", x: 22, y: 28, tone: "primary" },
  { label: "Marché Saint-Vivien", x: 30, y: 36, tone: "primary" },
  { label: "Marché Eysines", x: 64, y: 72, tone: "primary" }];

  const active = activeIdx !== null ? m[activeIdx] : null;
  const isRich = (mk) => mk && (mk.hours || mk.photo || mk.address || mk.phone);

  return (
    <div className={"relative rounded-hero overflow-hidden shadow-soft " + className} style={{ height }}>
      {/* Stylized base layer */}
      <svg viewBox="0 0 100 100" preserveAspectRatio="none" className="absolute inset-0 w-full h-full">
        <defs>
          <linearGradient id="water" x1="0" x2="1" y1="0" y2="1">
            <stop offset="0%" stopColor="#DCE6EE" />
            <stop offset="100%" stopColor="#C7D6E2" />
          </linearGradient>
          <linearGradient id="land" x1="0" x2="1" y1="0" y2="1">
            <stop offset="0%" stopColor="#F4F0E8" />
            <stop offset="100%" stopColor="#E8DCC4" />
          </linearGradient>
          <pattern id="dots" width="3" height="3" patternUnits="userSpaceOnUse">
            <circle cx="1" cy="1" r="0.35" fill="#034B86" opacity="0.15" />
          </pattern>
        </defs>
        <rect width="100" height="100" fill="url(#water)" />
        {/* Coastline / Medoc peninsula */}
        <path d="M 0 0 L 100 0 L 100 18 Q 80 22 75 32 Q 70 42 60 50 Q 50 58 45 70 Q 40 82 30 90 Q 22 96 10 100 L 0 100 Z" fill="url(#land)" />
        <path d="M 0 0 L 100 0 L 100 18 Q 80 22 75 32 Q 70 42 60 50 Q 50 58 45 70 Q 40 82 30 90 Q 22 96 10 100 L 0 100 Z" fill="url(#dots)" />
        {/* Bordeaux south-east */}
        <path d="M 75 65 Q 78 70 82 68 Q 86 66 88 72 L 90 80 L 86 84 L 78 80 Z" fill="#E8DCC4" />
        <path d="M 75 65 Q 78 70 82 68 Q 86 66 88 72 L 90 80 L 86 84 L 78 80 Z" fill="url(#dots)" />
        {/* Roads */}
        <path d="M 18 22 Q 28 30 38 42 Q 48 54 60 64" stroke="#fff" strokeWidth="0.6" fill="none" strokeDasharray="0" />
        <path d="M 30 36 Q 38 48 50 60 Q 58 68 68 72" stroke="#fff" strokeWidth="0.4" fill="none" />
        {/* River traces */}
        <path d="M 80 10 Q 70 30 65 50 Q 60 70 50 90" stroke="#3A7AB0" strokeWidth="0.8" fill="none" opacity="0.5" />
        <path d="M 78 5 Q 72 25 68 48 Q 64 70 54 92" stroke="#3A7AB0" strokeWidth="0.4" fill="none" opacity="0.35" />
        {/* Compass */}
        {!compact &&
        <g transform="translate(92,10)">
            <circle r="3.5" fill="#fff" stroke="#034B86" strokeWidth="0.3" />
            <polygon points="0,-2.6 0.7,0 0,2.6 -0.7,0" fill="#034B86" />
            <text y="-4.5" textAnchor="middle" fontSize="2.2" fill="#034B86" fontWeight="700">N</text>
          </g>
        }
        {/* Labels */}
        {!compact &&
        <g fill="#034B86" opacity="0.5" fontSize="2.2" fontStyle="italic">
            <text x="55" y="20">Estuaire de la Gironde</text>
            <text x="15" y="55">Médoc</text>
            <text x="80" y="78">Bordeaux</text>
          </g>
        }
      </svg>
      {/* Markers */}
      {m.map((mk, i) => {
        const rich = isRich(mk);
        const isActive = activeIdx === i;
        return (
          <div key={i} className="absolute -translate-x-1/2 -translate-y-full" style={{ left: mk.x + "%", top: mk.y + "%" }}>
            <button
              type="button"
              onClick={(e) => {e.stopPropagation();if (rich) setActiveIdx(isActive ? null : i);}}
              disabled={!rich}
              aria-label={mk.label || mk.name || "Lieu"}
              className={"relative block " + (rich ? "cursor-pointer group" : "cursor-default") + " focus:outline-none"}>
              
              <div className={"w-7 h-7 rounded-full border-[3px] border-white grid place-items-center transition-all " + (
              isActive ? "bg-primary-dark shadow-marine-lg scale-110" : "bg-primary shadow-marine " + (rich ? "group-hover:bg-primary-dark group-hover:scale-110" : ""))}>
                <div className="w-2 h-2 rounded-full bg-white" />
              </div>
              <div className={"absolute left-1/2 -translate-x-1/2 top-7 w-0 h-0 border-l-[6px] border-r-[6px] border-t-[8px] border-l-transparent border-r-transparent transition-colors " + (
              isActive ? "border-t-primary-dark" : "border-t-primary")} />
              <div className={"absolute left-1/2 -translate-x-1/2 top-[34px] whitespace-nowrap px-2.5 py-1 rounded-full text-[12px] font-semibold shadow-soft " + (
              isActive ? "bg-primary text-white" : "bg-white text-primary")}>
                {mk.label || mk.name}
              </div>
            </button>
          </div>);

      })}

      {/* Rich popup */}
      {active && isRich(active) &&
      <div
        className="absolute z-10 -translate-x-1/2 w-[280px] bg-white rounded-card shadow-marine-lg overflow-hidden"
        style={{
          left: Math.min(Math.max(active.x, 22), 78) + "%",
          top: `calc(${active.y}% + 32px)`
        }}
        onClick={(e) => e.stopPropagation()}>
        
          {active.photo &&
        <div className="h-32 bg-foam overflow-hidden">
              <img src={active.photo} alt="" className="w-full h-full object-cover" loading="lazy" />
            </div>
        }
          <div className="p-4 relative">
            <button
            onClick={() => setActiveIdx(null)}
            className="absolute top-2 right-2 w-7 h-7 grid place-items-center rounded-full bg-foam hover:bg-primary hover:text-white text-ink transition-colors"
            aria-label="Fermer">
            
              <Icon name="x" size={14} />
            </button>
            <h4 className="font-serif text-primary text-[18px] leading-tight pr-6">{active.name || active.label}</h4>
            {active.kind && <div className="eyebrow text-[10px] mt-1">{active.kind}</div>}
            {active.address &&
          <p className="text-mute text-[13px] mt-2 leading-snug flex items-start gap-1.5">
                <Icon name="map-pin" size={13} className="text-primary-light mt-0.5 shrink-0" />
                <span>{active.address}</span>
              </p>
          }
            {active.hours &&
          <p className="text-mute text-[13px] mt-1.5 leading-snug flex items-start gap-1.5">
                <Icon name="clock" size={13} className="text-primary-light mt-0.5 shrink-0" />
                <span>{active.hours}</span>
              </p>
          }
            {active.phone &&
          <a href={"tel:" + active.phone.replace(/\s+/g, '')} className="text-primary text-[13px] mt-1.5 flex items-center gap-1.5 hover:text-primary-dark">
                <Icon name="phone" size={13} />
                {active.phone}
              </a>
          }
            <a
            href={"https://www.google.com/maps/search/?api=1&query=" + encodeURIComponent(active.address || active.name || active.label || "")}
            target="_blank"
            rel="noreferrer"
            className="mt-3 inline-flex items-center justify-center gap-1.5 h-9 px-3 rounded-btn bg-primary text-white text-[12px] font-semibold tracking-[0.08em] uppercase hover:bg-primary-dark transition-colors w-full">
            
              <Icon name="navigation" size={13} />
              Itinéraire Google Maps
            </a>
          </div>
        </div>
      }
    </div>);

}

// ───────────────────────── Logo (text+SVG) ─────────────────────────
function Logo({ variant = "blue", size = 36 }) {
  const src = variant === "white" ? "assets/logo-blanc.png" : "assets/logo-bleu.png";
  return <img src={src} alt="Gigas Meduli" style={{ height: size }} className="w-auto select-none" />;
}

// ───────────────────────── ProductImg (PNG icons) ─────────────────────────
const PRODUCT_ICON_IMG = {
  oyster: "assets/icons/huitre.png",
  shells: "assets/icons/coquillages.png",
  bigorneaux: "assets/icons/bigorneaux.png",
  bulot: "assets/icons/bulot.png",
  crab: "assets/icons/crabe.png",
  shrimp: "assets/icons/crevette.png",
  gambas: "assets/icons/gambas.png",
  lobster: "assets/icons/homard.png",
  sheep: "assets/icons/mouton.png"
};
function ProductImg({ name, size = 24, className = "" }) {
  const src = PRODUCT_ICON_IMG[name];
  if (!src) return null;
  return (
    <img
      src={src}
      alt=""
      style={{ width: size, height: size }}
      className={"object-contain shrink-0 inline-block " + className} />);


}

// ───────────────────────── PlaceIcon (PNG) ─────────────────────────
// Custom blue line-art icons for store / open-air market, supplied by the
// client. Used in place of the generic stroke icons on the Locations page.
const PLACE_ICON_IMG = {
  store:  "assets/icons/boutique.png",
  market: "assets/icons/marche.png",
};
function PlaceIcon({ kind, size = 24, className = "" }) {
  const src = PLACE_ICON_IMG[kind];
  if (!src) return null;
  return (
    <img
      src={src}
      alt=""
      style={{ width: size, height: size }}
      className={"object-contain shrink-0 inline-block " + className} />
  );
}

// ───────────────────────── Field primitives ─────────────────────────
function Field({ label, required, children, hint, error, full }) {
  return (
    <label className={"flex flex-col gap-1.5 min-w-0 " + (full ? "md:col-span-2" : "")}>
      <span className="text-[14px] font-semibold text-ink">
        {label}{required && <span className="text-danger"> *</span>}
      </span>
      {children}
      {hint && !error && <span className="text-[13px] text-mute">{hint}</span>}
      {error && <span className="text-[13px] text-danger">{error}</span>}
    </label>);

}

function Input(props) {
  return <input {...props} className={"font-sans text-[16px] px-3.5 h-12 rounded-btn bg-foam/70 text-ink outline-none w-full min-w-0 transition-shadow focus:bg-white focus:ring-2 focus:ring-primary/30 " + (props.className || "")} />;
}
function Textarea(props) {
  return <textarea {...props} className={"font-sans text-[16px] px-3.5 py-3 min-h-[120px] rounded-btn bg-foam/70 text-ink outline-none w-full min-w-0 transition-shadow focus:bg-white focus:ring-2 focus:ring-primary/30 " + (props.className || "")} />;
}
function Select(props) {
  return <select {...props} className={"font-sans text-[16px] px-3.5 h-12 rounded-btn bg-foam/70 text-ink outline-none w-full min-w-0 transition-shadow focus:bg-white focus:ring-2 focus:ring-primary/30 " + (props.className || "")} />;
}
function Checkbox({ checked, onChange, children }) {
  return (
    <label className="flex items-start gap-3 cursor-pointer group">
      <input type="checkbox" checked={checked} onChange={onChange} className="mt-1 w-5 h-5 accent-primary cursor-pointer" />
      <span className="text-[15px] leading-[1.5] text-ink/90">{children}</span>
    </label>);

}

// ───────────────────────── Email anti-scrape ─────────────────────────
// The address is stored as a char-code array so the literal "name@host.tld"
// never appears as a substring in the served source. Naive regex scrapers
// (the vast majority) see nothing. Decoded on the fly at render time.
const __EM = [101, 97, 117, 109, 101, 100, 111, 99, 49, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109];
function decodeEmail() {
  return String.fromCharCode.apply(null, __EM);
}
function ProtectedEmail({ className = "", linkClassName, withIcon = false, iconSize = 15, iconClassName = "text-primary" }) {
  // Lazy decode at mount — even if the bot extracts JSX strings, the literal
  // never appears inline.
  const [m, setM] = React.useState(null);
  React.useEffect(() => { setM(decodeEmail()); }, []);
  if (!m) {
    // Tiny placeholder while decoding so layout doesn't jump
    return <span className={className} aria-label="adresse email">···@···</span>;
  }
  const inner = (
    <>
      {withIcon && <Icon name="mail" size={iconSize} className={iconClassName} />}
      <span>{m}</span>
    </>
  );
  // href built by string-joining tokens so it can't be regex-matched in source either
  return (
    <a href={["ma", "il", "to:" + m].join("")} className={linkClassName || className}>
      {inner}
    </a>
  );
}

// ───────────────────────── Captcha ─────────────────────────
// Anti-bot guard for forms. Combines:
//   · A visible math question (accessible to seniors, screen-readers, no image)
//   · A honeypot field (invisible to humans; bots auto-fill it)
//   · A small fill-time delay (bots submit < 2s)
// Calls onValidChange(true|false) as the answer becomes correct / incorrect.
function makeCaptchaQuestion() {
  const a = 2 + Math.floor(Math.random() * 7);     // 2..8
  const b = 1 + Math.floor(Math.random() * 5);     // 1..5
  return { a, b, answer: a + b };
}
function Captcha({ onValidChange, label = "Vérification anti-robot" }) {
  const [q, setQ] = React.useState(makeCaptchaQuestion);
  const [val, setVal] = React.useState("");
  const [honey, setHoney] = React.useState("");
  const mountedAt = React.useRef(Date.now());

  const tooFast = () => Date.now() - mountedAt.current < 1500;
  const ok = !honey && val !== "" && parseInt(val, 10) === q.answer && !tooFast();
  const wrong = val !== "" && parseInt(val, 10) !== q.answer;

  React.useEffect(() => { onValidChange && onValidChange(ok); }, [ok, onValidChange]);

  const refresh = () => { setQ(makeCaptchaQuestion()); setVal(""); };

  return (
    <div className="rounded-card bg-foam/60 p-4 relative">
      <div className="flex items-start gap-3">
        <span className="w-10 h-10 rounded-card bg-white text-primary shadow-soft grid place-items-center shrink-0">
          <Icon name="shield-check" size={18} />
        </span>
        <div className="flex-1 min-w-0">
          <label className="block text-[13px] font-semibold text-ink mb-2 tracking-[0.02em]">{label}</label>
          <div className="flex items-center gap-3 flex-wrap">
            <span className="text-[15px] text-ink">
              Combien font{" "}
              <span className="font-serif text-primary text-[22px] tabular-nums align-middle mx-0.5">{q.a}</span>
              <span className="text-mute mx-1">+</span>
              <span className="font-serif text-primary text-[22px] tabular-nums align-middle mx-0.5">{q.b}</span>
              {" "}?
            </span>
            <input
              type="text"
              inputMode="numeric"
              autoComplete="off"
              value={val}
              onChange={(e) => setVal(e.target.value.replace(/\D/g, "").slice(0, 2))}
              placeholder="?"
              aria-label="Réponse à la question de vérification"
              className={
                "w-16 h-10 px-2 text-center rounded-btn bg-white font-semibold text-[16px] text-ink outline-none transition-all " + (
                ok ? "ring-2 ring-success bg-success/5" : wrong ? "ring-2 ring-danger bg-danger/5" : "focus:ring-2 focus:ring-primary/30")
              }
            />
            {ok && <Icon name="check-circle" size={20} className="text-success" />}
            {wrong && <span className="text-[12px] text-danger">Réponse incorrecte</span>}
            <button
              type="button"
              onClick={refresh}
              className="ml-auto text-mute hover:text-primary text-[12px] underline underline-offset-4"
              aria-label="Changer la question"
            >Nouvelle question</button>
          </div>
        </div>
      </div>
      {/* Honeypot — invisible to humans, auto-filled by spam bots */}
      <input
        type="text"
        name="website"
        tabIndex="-1"
        autoComplete="off"
        value={honey}
        onChange={(e) => setHoney(e.target.value)}
        aria-hidden="true"
        style={{ position: "absolute", left: "-9999px", top: "auto", width: "1px", height: "1px", opacity: 0, pointerEvents: "none" }}
      />
    </div>
  );
}

Object.assign(window, {
  Button, Kicker, SectionHead, OysterCard, ProductCard, PlaceCard,
  CtaBanner, PressStrip, InfoBox, MapMock, Logo, ProductImg, PlaceIcon, Field, Input, Textarea, Select, Checkbox,
  ProtectedEmail, decodeEmail, Captcha
});