// RIVA — composants du site
const { useState, useEffect, useRef, useMemo } = React;

// ====== VIGNETTE D'UN PLAT ======
// Affiche la photo si elle existe dans le dossier photos\, sinon une
// vignette propre avec les initiales du plat, aux couleurs de sa catégorie.
function PlatVisuel({ item, className = '', children }) {
  // 1. Une vraie photo déposée dans  photos\  passe avant tout le reste.
  if (item?.img) {
    return (
      <div className={className} style={{ backgroundImage: `url(${item.img})`, backgroundSize: 'cover', backgroundPosition: 'center' }}>
        {children}
      </div>
    );
  }

  // 2. Sinon, le plat reçoit son illustration, dessinée d'après sa catégorie
  //    et les ingrédients cités dans son nom (voir illustrations.js).
  let dessin = null;
  try {
    if (item?.name && typeof illustrationPlat === 'function') {
      dessin = illustrationPlat(item.catId || item.cat || '', item.name, item.teinte, item.desc);
    }
  } catch (e) {}

  if (dessin) {
    return (
      <div className={`${className} plat-illustre`}
           style={{ backgroundImage: `url("${dessin}")`, backgroundSize: 'cover', backgroundPosition: 'center' }}>
        {children}
      </div>
    );
  }

  // 3. Filet de sécurité : les initiales du plat, si le dessin a échoué.
  const initiales = String(item?.name || '')
    .replace(/[^\p{L}\p{N}\s]/gu, ' ')
    .split(/\s+/).filter(Boolean).slice(0, 2)
    .map(m => m[0].toUpperCase()).join('');
  return (
    <div className={`${className} plat-vide`} data-t={item?.teinte || 'vert'}>
      <span className="initiales">{initiales || '洋'}</span>
      {item?.catLabel && <span className="cat">{item.catLabel}</span>}
      {children}
    </div>
  );
}

// ====== ICONS ======
const Icon = {
  Star: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 2l3 7h7l-5.5 4.5L18 21l-6-4-6 4 1.5-7.5L2 9h7z"/></svg>,
  Bag: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><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"/></svg>,
  Close: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M18 6L6 18M6 6l12 12"/></svg>,
  Menu: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M3 12h18M3 6h18M3 18h18"/></svg>,
  Plus: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" {...p}><path d="M12 5v14M5 12h14"/></svg>,
  WhatsApp: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M17.5 14.4c-.3-.1-1.8-.9-2-1-.3-.1-.5-.1-.7.1-.2.3-.8 1-1 1.2-.2.2-.4.2-.7.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.4.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5-.1-.1-.7-1.6-.9-2.2-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.4 0 1.4 1 2.8 1.2 3 .1.2 2 3.1 4.9 4.3.7.3 1.2.5 1.6.6.7.2 1.3.2 1.8.1.5-.1 1.7-.7 1.9-1.4.2-.7.2-1.2.2-1.4-.1-.1-.3-.2-.6-.3zM12 2C6.5 2 2 6.5 2 12c0 1.8.5 3.5 1.3 5L2 22l5.1-1.3c1.4.8 3.1 1.2 4.9 1.2 5.5 0 10-4.5 10-10S17.5 2 12 2z"/></svg>,
  Phone: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><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.72 12.84 12.84 0 0 0 .7 2.81 2 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-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>,
  MapPin: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>,
  Clock: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>,
  Truck: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10 17h4V5H2v12h3"/><path d="M20 17h2v-3.34a4 4 0 0 0-1.17-2.83L19 9h-5"/><path d="M14 17h1"/><circle cx="7.5" cy="17.5" r="2.5"/><circle cx="17.5" cy="17.5" r="2.5"/></svg>,
  Store: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 9l1-5h16l1 5"/><path d="M3 9v11h18V9"/><path d="M9 22V12h6v10"/></svg>,
  Check: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="20 6 9 17 4 12"/></svg>,
  ArrowRight: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>,
  Trash: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/></svg>,
  Insta: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>,
  Spark: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 0l1.5 8.5L22 10l-8.5 1.5L12 20l-1.5-8.5L2 10l8.5-1.5z"/></svg>,
  Settings: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>,
  Flame: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M8.5 14.5c0-2 1.5-3 1.5-4.5C10 8 8 6.5 8 6.5s2 0 3.5 1.5C13 5.5 12 2 12 2s4 3.5 4 7c0 0 1-1 1.5-2 .5 2 1 4 1 5.5 0 3.5-3 6.5-6.5 6.5S5 16 5 13.5s2-3.5 2-3.5-.5 2 1.5 4.5z"/></svg>,
  Copy: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>,
  Sliders: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></svg>,
  Sparkles: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 2l1.5 5.5L19 9l-5.5 1.5L12 16l-1.5-5.5L5 9l5.5-1.5z" opacity="0.95"/><path d="M19 14l.7 2.3L22 17l-2.3.7L19 20l-.7-2.3L16 17l2.3-.7z" opacity="0.7"/><path d="M5 17l.5 1.5L7 19l-1.5.5L5 21l-.5-1.5L3 19l1.5-.5z" opacity="0.6"/></svg>,
  Printer: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg>,
  Lock: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>,
  CreditCard: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg>,
  Cash: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="2" y="6" width="20" height="12" rx="2"/><circle cx="12" cy="12" r="2"/><path d="M6 12h.01M18 12h.01"/></svg>,
  Mail: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>,
  Warning: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>,
};

// ====== LOGO ======
/* Le logo officiel de RIVA — l'image fournie par le restaurant, détourée
   (site/logo/), et RIEN d'autre : pas de redessin, pas de ligne ajoutée.
   Source : photos/logo-fond-noir.jpg.

   size      = hauteur de l'arche en pixels.
   sansTexte = l'arche seule, sans le mot RIVA.
   empile    = le logo complet, arche au-dessus du mot (pied de page). */
const LOGOS = Object.assign({
  arche: '/site/logo/riva-arche.png',
  mot: '/site/logo/riva-mot.png',
  complet: '/site/logo/riva-logo.png',
}, window.RIVA_LOGOS || {});   // version fichier unique : images intégrées

function Logo({ size = 40, sansTexte = false, empile = false }) {
  if (empile) {
    return <img src={LOGOS.complet} alt="RIVA" height={size}
                style={{ height: size, width: 'auto' }} draggable="false"/>;
  }
  return (
    <div className="flex items-center gap-2.5">
      <img src={LOGOS.arche} alt={sansTexte ? 'RIVA' : ''}
           style={{ height: size, width: 'auto' }} className="shrink-0" draggable="false"/>
      {!sansTexte && (
        <img src={LOGOS.mot} alt="RIVA"
             style={{ height: Math.round(size * 0.5), width: 'auto' }} draggable="false"/>
      )}
    </div>
  );
}

// ====== HEADER ======
// `compact` : le client est à table, il vient pour commander. On lui enlève
// la navigation du site (histoire, accès, commander) : il n'a rien à visiter.
function Header({ cartCount, onCartOpen, onNav, view, setView, adminUnlocked, onLogoClick, startLongPress, cancelLongPress, compact }) {
  const [mobileOpen, setMobileOpen] = useState(false);
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 30);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  const links = [
    { id: 'menu', label: 'Menu' },
    { id: 'commander', label: 'Commander' },
    { id: 'histoire', label: 'L\'histoire' },
    { id: 'visite', label: 'Nous trouver' },
  ];
  return (
    <header className={`fixed top-0 left-0 right-0 z-50 transition-all ${scrolled ? 'glass' : ''}`}>
      <div className="max-w-[1400px] mx-auto px-5 md:px-8 py-3 flex items-center justify-between gap-4">
        <a href="#top"
           onClick={(e) => {
             // Si l'appui long s'est déclenché, on ignore le clic
             const blocked = onLogoClick && onLogoClick(e);
             if (blocked === false) return;
             e.preventDefault();
             onNav('top');
             setView('site');
           }}
           onMouseDown={() => startLongPress && startLongPress()}
           onMouseUp={() => cancelLongPress && cancelLongPress()}
           onMouseLeave={() => cancelLongPress && cancelLongPress()}
           onTouchStart={() => startLongPress && startLongPress()}
           onTouchEnd={() => cancelLongPress && cancelLongPress()}
           onTouchCancel={() => cancelLongPress && cancelLongPress()}
           onContextMenu={(e) => e.preventDefault()}
           className="flex items-center select-none"
           style={{ WebkitUserSelect: 'none', userSelect: 'none' }}>
          <Logo size={50}/>
        </a>
        <nav className={`items-center gap-1 ${compact ? 'hidden' : 'hidden md:flex'}`}>
          {links.map(l => (
            <a key={l.id} href={`#${l.id}`} onClick={(e) => {e.preventDefault(); onNav(l.id); setView('site');}}
               className="px-3.5 py-2 text-sm font-medium tracking-wide hover:text-[var(--vert)] transition-colors uppercase">
              {l.label}
            </a>
          ))}
        </nav>
        <div className="flex items-center gap-2">
          {adminUnlocked && (
            <button onClick={() => setView(view === 'admin' ? 'site' : 'admin')}
                    className="hidden md:inline-flex btn btn-ghost !py-2 !px-3 !text-xs"
                    title="Vue patron / admin">
              <Icon.Settings className="w-4 h-4"/>
              {view === 'admin' ? 'Site' : 'Admin'}
            </button>
          )}
          <button onClick={onCartOpen}
                  className="relative btn btn-primary !py-2.5 !px-4 !text-xs">
            <Icon.Bag className="w-4 h-4"/>
            <span className="hidden sm:inline">Panier</span>
            {cartCount > 0 && (
              <span className="absolute -top-1.5 -right-1.5 min-w-[20px] h-5 px-1 bg-[var(--rouge)] text-white rounded-full text-[11px] font-bold flex items-center justify-center">
                {cartCount}
              </span>
            )}
          </button>
          <button onClick={() => setMobileOpen(!mobileOpen)}
                  className={`p-2 text-[var(--cream)] ${compact ? 'hidden' : 'md:hidden'}`}>
            {mobileOpen ? <Icon.Close className="w-6 h-6"/> : <Icon.Menu className="w-6 h-6"/>}
          </button>
        </div>
      </div>
      {mobileOpen && !compact && (
        <div className="md:hidden glass border-t border-[var(--line)]">
          <div className="px-5 py-4 flex flex-col gap-1">
            {links.map(l => (
              <a key={l.id} href={`#${l.id}`}
                 onClick={(e) => {e.preventDefault(); onNav(l.id); setMobileOpen(false); setView('site');}}
                 className="py-2.5 text-base font-medium uppercase">{l.label}</a>
            ))}
            {adminUnlocked && (
              <button onClick={() => {setView(view === 'admin' ? 'site' : 'admin'); setMobileOpen(false);}}
                      className="py-2.5 text-base font-medium uppercase text-left flex items-center gap-2 text-[var(--vert)]">
                <Icon.Settings className="w-4 h-4"/>{view === 'admin' ? 'Retour au site' : 'Vue patron'}
              </button>
            )}
          </div>
        </div>
      )}
    </header>
  );
}

// ====== HERO ======
function Hero({ onScrollToMenu, openPhone, table }) {
  const [status, setStatus] = useState({ open: false, label: '' });
  const { menu: effectiveMenu, featuredId } = getEffectiveMenu();
  // Plat mis en avant : celui choisi dans le tableau de bord, sinon le
  // Rivanuozzo — Imad veut un PANUOZZO en vitrine, pas une pizza.
  const platVedette = useMemo(() => {
    const all = Object.values(effectiveMenu).flatMap(c => c.items);
    if (featuredId) {
      const found = all.find(it => it.id === featuredId);
      if (found) return found;
    }
    const panuozzos = all.filter(it => String(it.catId || '').startsWith('panuozzo'));
    return panuozzos.find(it => it.name === 'Rivanuozzo') || panuozzos[0]
        || effectiveMenu.signature?.items?.[0] || all[0];
  }, [featuredId, effectiveMenu]);
  // Nombre réel de plats à la carte, recompté à chaque chargement
  const nbPlats = useMemo(
    () => Object.values(effectiveMenu).reduce((s, c) => s + c.items.length, 0),
    [effectiveMenu]
  );
  const heroQuote = getHeroQuote();
  const textes = getHeroTextes();
  useEffect(() => {
    setStatus(isOpenNow());
    const t = setInterval(() => setStatus(isOpenNow()), 60000);
    return () => clearInterval(t);
  }, []);
  return (
    <section id="top" className="feuillage feuillage-fort relative min-h-[100svh] flex items-center pt-24 pb-12 overflow-hidden">
      <div className="absolute inset-0">
        <div className="absolute inset-0 bg-[var(--bg)]"/>
        <div className="absolute inset-0 opacity-90"
             style={{
               background: 'radial-gradient(ellipse at 65% 45%, rgba(140,198,63,0.15), transparent 55%), radial-gradient(ellipse at 18% 82%, rgba(201,165,78,0.10), transparent 55%), radial-gradient(ellipse at 88% 88%, rgba(184,85,54,0.07), transparent 45%)'
             }}/>
        <div className="noise"/>
      </div>

      <div className="relative max-w-[1400px] mx-auto px-5 md:px-8 w-full grid lg:grid-cols-12 gap-8 items-center">
        <div className="lg:col-span-7 z-10">
          <div className="flex items-center gap-3 mb-6 flex-wrap">
            <span className="pill">
              <span className={`w-2 h-2 rounded-full ${status.open ? 'bg-[var(--jade)] pulse-dot' : 'bg-[var(--rouge)]'}`}/>
              {status.label}
            </span>
            {textes.pastille1.trim() && <span className="pill new">{textes.pastille1}</span>}
            {textes.pastille2.trim() && <span className="pill">{textes.pastille2}</span>}
          </div>
          <h1 className="font-display text-[clamp(3.5rem,11vw,9rem)] leading-[0.85] text-[var(--cream)]">
            {textes.titre1}<br/>
            {textes.titre2.trim() && <><span className="text-[var(--vert)]">{textes.titre2}</span><br/></>}
            {textes.signature.trim() && (
              <span className="italic font-hand text-[var(--rouge-2)] text-[0.6em] block mt-2 -rotate-2 normal-case tracking-normal">{textes.signature}</span>
            )}
          </h1>
          <p className="mt-7 text-[var(--cream-2)] text-lg max-w-xl leading-relaxed">
            {textes.texte}{' '}
            {textes.texteFort.trim() && <span className="text-[var(--vert)] font-semibold">{textes.texteFort}</span>}
          </p>
          <div className="mt-9 flex flex-wrap items-center gap-3">
            <button onClick={onScrollToMenu} className="btn btn-primary !text-base !py-4 !px-7">
              {table ? `Commander pour la table ${table}` : 'Commander en ligne'}
              <Icon.ArrowRight className="w-5 h-5"/>
            </button>
            {SHOP.phone && (
              <button onClick={openPhone} className="btn btn-ghost !text-base !py-4 !px-7">
                <Icon.Phone className="w-4 h-4"/>
                Appeler pour commander
              </button>
            )}
          </div>
        </div>

        <div className="lg:col-span-5 relative z-10 hidden lg:block">
          <div className="relative">
            <div className="absolute -inset-6 bg-gradient-to-tr from-[var(--vert)]/30 to-[var(--rouge)]/20 rounded-full blur-3xl"/>
            <PlatVisuel item={platVedette} className="relative w-full aspect-square rounded-3xl overflow-hidden"/>
            <div className="absolute -top-6 -right-4 starburst float text-[0.8rem]">
              <div>
                <div>LA</div>
                <div className="text-[1.4rem] -mt-1">STAR</div>
              </div>
            </div>
            {/* Voile sombre en bas de la photo, sinon le nom du plat en blanc
                se perd sur une image claire. */}
            <div className="absolute inset-x-0 bottom-0 h-2/5 z-[2] rounded-b-3xl bg-gradient-to-t from-black/70 via-black/25 to-transparent pointer-events-none"/>
            <div className="absolute bottom-4 left-4 right-4 z-[3]">
              <div className="font-hand text-[var(--vert-vif)] text-xl leading-none drop-shadow">{platVedette?.catLabel}</div>
              <div className="font-display text-3xl text-white drop-shadow">{platVedette?.name}</div>
            </div>
            {/* Le petit mot manuscrit. Le patron peut le couper depuis le
                tableau de bord : alors rien, pas même une étiquette vide. */}
            {heroQuote.actif !== false && (heroQuote.line1 || '').trim() && (
              <div className="absolute -bottom-16 -left-8 rotate-[-6deg]" style={{ filter: 'drop-shadow(0 18px 30px rgba(0,0,0,0.22))' }}>
                {/* SVG sticker — forme organique avec bord déchiré et petite étoile */}
                <svg viewBox="0 0 260 200" className="absolute inset-0 w-full h-full" preserveAspectRatio="none" style={{ zIndex: 0 }}>
                  <defs>
                    <linearGradient id="stickerGrad" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="#FAF1DD"/>
                      <stop offset="100%" stopColor="#F0E4C5"/>
                    </linearGradient>
                  </defs>
                  {/* Forme blob/sticker stylisée */}
                  <path d="M20 22 Q24 8 42 10 L88 5 Q108 3 130 8 L186 4 Q210 5 222 18 Q252 30 248 60 L252 110 Q258 138 240 156 L238 178 Q230 198 208 192 L150 196 Q120 200 96 193 L40 197 Q14 196 10 172 L6 130 Q-2 102 8 80 L10 50 Q12 30 20 22 Z"
                        fill="url(#stickerGrad)"/>
                </svg>

                {/* Petite étoile décorative rouge */}
                <svg viewBox="0 0 40 40" className="absolute -top-3 -right-2 w-12 h-12 text-[var(--rouge)] rotate-[15deg]" fill="currentColor" style={{ zIndex: 2, filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.18))' }}>
                  <path d="M20 2 L24 14 L37 14 L26.5 22 L30.5 35 L20 27 L9.5 35 L13.5 22 L3 14 L16 14 Z"/>
                </svg>

                {/* Contenu */}
                <div className="relative px-7 py-6 w-[260px]" style={{ zIndex: 1 }}>
                  <div className="font-hand text-[var(--rouge)] text-[1.7rem] leading-[1.05] whitespace-pre-wrap text-[var(--cream)]">
                    <span className="text-[var(--rouge)]">"</span>
                    <span className="text-[#2a2118]">{heroQuote.line1}</span>
                    <span className="text-[var(--rouge)]">"</span>
                  </div>
                  {heroQuote.author && (
                    <div className="mt-3 inline-flex items-center gap-1.5 font-hand text-[1rem] text-[var(--rouge)] tracking-wide rotate-[-1deg]">
                      <span className="w-6 h-px bg-[var(--rouge)]"/>
                      {heroQuote.author}
                    </div>
                  )}
                </div>
              </div>
            )}
          </div>
        </div>
      </div>

      <div className="hero-vignette absolute bottom-0 left-0 right-0 h-32 pointer-events-none"/>
    </section>
  );
}

// ====== PHONE POPUP ======
function PhonePopup({ open, onClose }) {
  const [copied, setCopied] = useState(false);
  const [status, setStatusP] = useState({ open: false, label: '' });
  const [nextOpen, setNextOpen] = useState('');
  useEffect(() => {
    if (open) {
      setCopied(false);
      const s = isOpenNow();
      setStatusP(s);
      setNextOpen(s.open ? '' : computeNextOpening());
    }
  }, [open]);
  if (!open) return null;
  const copy = async () => {
    try {
      await navigator.clipboard.writeText(SHOP.phone);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (e) {}
  };
  return (
    <div className="fixed inset-0 z-[200] voile-fonce backdrop-blur-sm flex items-center justify-center p-5" onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()}
           className="bg-[var(--bg-2)] border border-[var(--line)] rounded-3xl p-7 max-w-[440px] w-full text-center relative">
        <button onClick={onClose} aria-label="Fermer"
                className="absolute top-3 right-3 w-9 h-9 rounded-full bg-[var(--bg)] flex items-center justify-center hover:bg-[var(--bg-3)]">
          <Icon.Close className="w-4 h-4"/>
        </button>

        {/* Numéro en gros — pas cliquable pour éviter Skype/FaceTime sur desktop */}
        <div className="text-[10px] uppercase tracking-wider text-[var(--muted)] font-bold mb-3 mt-1">Numéro du restaurant</div>
        <div className="font-display text-[clamp(2.5rem,9vw,3.8rem)] text-[var(--cream)] tracking-wide leading-none select-all"
             onClick={copy}
             style={{ cursor: 'pointer' }}
             title="Cliquer pour copier">
          {SHOP.phone}
        </div>

        {/* Statut ouvert / fermé */}
        <div className="mt-6">
          {status.open ? (
            <div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-[var(--jade)]/15 text-[var(--jade)] border border-[var(--jade)]/30 text-sm font-bold">
              <span className="w-2 h-2 rounded-full bg-[var(--jade)] pulse-dot"/>
              Ouvert · appelle quand tu veux
            </div>
          ) : (
            <div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-[var(--rouge)]/15 text-[var(--rouge-2)] border border-[var(--rouge)]/30 text-sm font-bold">
              <span className="w-2 h-2 rounded-full bg-[var(--rouge)]"/>
              Fermé maintenant
            </div>
          )}
          {!status.open && nextOpen && (
            <div className="text-sm text-[var(--cream-2)] mt-3">
              Ouvre <strong className="text-[var(--vert)]">{nextOpen}</strong>
            </div>
          )}
          {!status.open && (
            <div className="text-xs text-[var(--muted)] mt-2 max-w-xs mx-auto">
              Personne ne répondra. Tu peux quand même commander en ligne 👇
            </div>
          )}
        </div>

        {/* Actions */}
        <div className="mt-6 flex flex-col sm:flex-row gap-2">
          <button onClick={copy} className="btn btn-ghost !py-3 flex-1">
            {copied ? <><Icon.Check className="w-4 h-4 text-[var(--jade)]"/> Copié !</> : <><Icon.Copy className="w-4 h-4"/> Copier le numéro</>}
          </button>
          {!status.open && (
            <button onClick={() => { onClose(); document.getElementById('menu')?.scrollIntoView({behavior:'smooth'}); }}
                    className="btn btn-primary !py-3 flex-1">
              Commander en ligne
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

// Calcule la prochaine ouverture (ex: "demain à 11h30", "vendredi à 18h30")
function computeNextOpening() {
  const now = new Date();
  const dayNames = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
  const mins = now.getHours() * 60 + now.getMinutes();
  const todayIdx = (now.getDay() + 6) % 7; // 0 = lundi

  for (let offset = 0; offset < 8; offset++) {
    const idx = (todayIdx + offset) % 7;
    const day = SHOP.hours[idx];
    if (day.closed) continue;
    // Parse slots
    const slots = day.slots.split('/').map(s => {
      const [from, to] = s.trim().split('–').map(t => {
        const [hh, mm] = t.trim().replace('h', ':').split(':');
        return parseInt(hh) * 60 + parseInt(mm || 0);
      });
      return { from, to };
    });
    for (const slot of slots) {
      if (offset === 0 && slot.from <= mins) continue; // déjà passé aujourd'hui
      const h = Math.floor(slot.from / 60);
      const m = slot.from % 60;
      const timeStr = `${h}h${String(m).padStart(2,'0')}`;
      if (offset === 0) return `aujourd'hui à ${timeStr}`;
      if (offset === 1) return `demain à ${timeStr}`;
      const dayName = dayNames[(now.getDay() + offset) % 7];
      return `${dayName} à ${timeStr}`;
    }
  }
  return '';
}

function Stat({ n, sub }) {
  return (
    <div>
      <div className="font-display text-3xl md:text-4xl text-[var(--vert)]">{n}</div>
      <div className="text-[11px] uppercase tracking-wider text-[var(--muted)] mt-1">{sub}</div>
    </div>
  );
}

// ====== TICKER ======
function Ticker() {
  const items = ['Pâte napolitaine', '★', '100% Halal', '★', 'Panuozzo sur mesure', '★', 'Pâtes à la meule', '★', 'Soufflés Riva', '★', 'Commande à table par QR', '★'];
  return (
    <div className="bg-[var(--vert)] text-[var(--bg)] py-4 overflow-hidden border-y-2 border-[var(--bg)]">
      <div className="ticker">
        {[...items, ...items, ...items].map((t, i) => (
          <span key={i} className="marquee-text font-display tracking-wide">{t}</span>
        ))}
      </div>
    </div>
  );
}

// ====== HOW IT WORKS ======
// Un simple bandeau : trois pas, une ligne chacun. Le client a compris avant
// d'avoir fini de lire — une explication qui prend un écran entier, personne
// ne la lit et elle repousse la carte plus bas.
function HowItWorks() {
  const steps = [
    { n: '1', title: 'Vous composez', desc: 'Sur votre téléphone, à votre rythme.' },
    { n: '2', title: 'Ça tombe en caisse', desc: 'Le ticket sort en cuisine dans la seconde.' },
    { n: '3', title: 'Vous mangez', desc: 'Servi à table, ou prêt à l’heure choisie.' },
  ];
  return (
    <section className="py-10 md:py-12 bg-[var(--bg)] border-y border-[var(--line)]">
      <div className="max-w-[1400px] mx-auto px-5 md:px-8 grid gap-6 md:grid-cols-3 md:gap-10">
        {steps.map((s, i) => (
          <div key={i} className="flex gap-4 items-baseline">
            <span className="font-display text-3xl text-[var(--vert)] leading-none shrink-0">{s.n}</span>
            <div>
              <h3 className="font-display text-xl text-[var(--cream)] leading-tight">{s.title}</h3>
              <p className="text-[var(--muted)] text-sm mt-0.5">{s.desc}</p>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ====== SIGNATURE FEATURE ======
function SignatureFeature({ addToCart }) {
  const { menu: effectiveMenu } = getEffectiveMenu();
  const featured = (effectiveMenu.signature?.items || []).slice(0, 3);
  if (featured.length === 0) return null;
  return (
    <section className="feuillage feuillage-bd py-20 md:py-28 bg-[var(--bg-2)] relative overflow-hidden">
      <div className="absolute inset-0 noise"/>
      <div className="relative max-w-[1400px] mx-auto px-5 md:px-8">
        <div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-12">
          <div>
            <div className="kicker mb-4">Les Signatures</div>
            <h2 className="font-display text-5xl md:text-7xl text-[var(--cream)]">
              Les trois<br/>qu'on <span className="inline-block bg-[var(--vert)] text-[var(--bg)] px-3 py-0.5 -rotate-2">refuse</span> de retirer de la carte.
            </h2>
          </div>
          <a href="#menu" onClick={(e) => {e.preventDefault(); document.getElementById('menu')?.scrollIntoView({behavior: 'smooth'});}} className="btn btn-ghost shrink-0">
            Voir toute la carte <Icon.ArrowRight className="w-4 h-4"/>
          </a>
        </div>

        <div className="grid md:grid-cols-3 gap-5">
          {featured.map((item, i) => (
            <article key={item.id} className="menu-card group">
              <PlatVisuel item={item} className="menu-card-img">
                <span className="sticker">N°{i+1}</span>
                <div className="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent"/>
                <div className="absolute bottom-3 left-4 right-4">
                  <div className="font-hand text-[var(--vert-vif)] text-xl -mb-1">{item.tagline || item.catLabel}</div>
                  <h3 className="font-display text-3xl text-white">{item.name}</h3>
                </div>
              </PlatVisuel>
              <div className="p-5 flex-1 flex flex-col">
                <p className="text-sm text-[var(--cream-2)] leading-relaxed flex-1">{item.desc}</p>
                <div className="flex items-center justify-between mt-5 pt-4 border-t border-[var(--line)]">
                  <span className="font-display text-3xl text-[var(--vert)]">{item.price.toFixed(2)}€</span>
                  {item.rupture ? (
                    <span className="btn btn-ghost !py-2 !px-4 !text-xs opacity-70 cursor-not-allowed">En rupture</span>
                  ) : (
                    <button onClick={() => addToCart(item)} className="btn btn-primary !py-2 !px-4 !text-xs">
                      <Icon.Plus className="w-4 h-4"/> Ajouter
                    </button>
                  )}
                </div>
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// ====== FULL MENU ======
function FullMenu({ addToCart, compact }) {
  const [activeCat, setActiveCat] = useState('signature');
  const { menu: effectiveMenu } = getEffectiveMenu();
  const cats = Object.values(effectiveMenu);
  const current = cats.find(c => c.id === activeCat) || cats[0];

  return (
    <section id="menu" className={`feuillage feuillage-hg bg-[var(--bg)] ${compact ? 'pt-24 pb-8 md:pt-28 md:pb-10' : 'py-20 md:py-28'}`}>
      <div className="max-w-[1400px] mx-auto px-5 md:px-8">
        {compact ? (
          <div className="mb-6">
            <h2 className="font-display text-3xl md:text-4xl text-[var(--cream)]">La carte</h2>
            <p className="text-[var(--muted)] text-sm mt-1">
              Ajoutez ce que vous voulez, puis envoyez en cuisine. Une allergie ? Dites-le dans la note, on adapte.
            </p>
          </div>
        ) : (
        <div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-10">
          <div>
            <div className="kicker mb-4">La Carte</div>
            <h2 className="font-display text-5xl md:text-7xl text-[var(--cream)]">Toute la carte, <span className="text-[var(--vert)]">en un coup d'œil.</span></h2>
          </div>
          <div className="text-[var(--muted)] text-sm max-w-sm">
            Tout est préparé à la commande. 100% halal. Une allergie ? Indiquez-le dans la note de commande, on adapte.
          </div>
        </div>
        )}

        {/* Onglets des catégories — la carte est longue, ils défilent sur le côté */}
        <div className="mb-8 pb-3 border-b border-[var(--line)] sticky top-[68px] z-20 bg-[var(--bg)]/95 backdrop-blur -mx-5 md:-mx-8 px-5 md:px-8 pt-2">
          <div className="flex flex-nowrap gap-1.5 md:gap-2 overflow-x-auto no-scrollbar">
            {cats.map(c => (
              <button key={c.id} onClick={() => setActiveCat(c.id)}
                className={`shrink-0 px-3.5 md:px-5 py-2 md:py-2.5 rounded-full whitespace-nowrap font-display text-[15px] md:text-lg tracking-wide transition-all
                  ${activeCat === c.id
                    ? 'bg-[var(--vert)] text-[var(--bg)]'
                    : 'bg-transparent text-[var(--muted)] hover:text-[var(--cream)]'}`}>
                {c.label}
                <span className={`ml-1.5 text-[10px] font-bold ${activeCat === c.id ? 'text-[var(--bg)]/70' : 'text-[var(--muted)]/60'}`}>{c.items.length}</span>
              </button>
            ))}
          </div>
        </div>

        {/* Only the active category */}
        <div key={current.id} style={{ animation: 'menuFadeIn 0.3s ease' }}>
          <div className="flex items-baseline gap-4 mb-6">
            <h3 className="font-display text-4xl md:text-5xl text-[var(--cream)]">{current.label}</h3>
            <span className="font-hand text-[var(--vert)] text-2xl">{current.sub}</span>
          </div>
          <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
            {current.items.map(item => (
              <MenuCard key={item.id} item={item} addToCart={addToCart}/>
            ))}
          </div>
        </div>

        <style>{`
          @keyframes menuFadeIn {
            from { opacity: 0; transform: translateY(8px); }
            to { opacity: 1; transform: translateY(0); }
          }
        `}</style>
      </div>
    </section>
  );
}

function MenuCard({ item, addToCart }) {
  // Un plat « à composer » a des choix obligatoires (viande, accompagnement…) :
  // on le signale pour que le client sache qu'un écran de choix va s'ouvrir.
  const aComposer = !!(item.options && item.options.length);
  return (
    <article className="menu-card">
      <PlatVisuel item={item} className="menu-card-img relative">
        {/* En rupture : la photo est assombrie, l'étiquette reste rouge vif en haut à gauche */}
        {item.rupture && <div className="absolute inset-0 z-[5] bg-black/55"/>}
        {item.rupture && (
          <span className="absolute top-3 left-3 z-10 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider shadow-lg"
                style={{ background: '#d32f2f', color: '#fff' }}>
            En rupture
          </span>
        )}
        {item.badges?.includes('signature') && <span className="sticker">Signature</span>}
        {item.badges?.includes('hot') && <span className="pill hot absolute top-3 right-3"><Icon.Flame className="w-3 h-3"/> Épicé</span>}
        {item.badges?.includes('new') && <span className="pill new absolute top-3 right-3">Nouveau</span>}
        {item.badges?.includes('veg') && <span className="pill veg absolute top-3 right-3">Végé</span>}
      </PlatVisuel>
      <div className="p-4 flex-1 flex flex-col">
        <div className="flex items-baseline justify-between gap-2">
          <h4 className="font-display text-2xl text-[var(--cream)]">{item.name}</h4>
          <span className="font-display text-2xl text-[var(--vert)] shrink-0">{item.price.toFixed(2)}€</span>
        </div>
        {item.tagline && <div className="font-hand text-[var(--rouge-2)] text-lg leading-tight -mt-1">{item.tagline}</div>}
        <p className="text-sm text-[var(--cream-2)]/80 mt-2 leading-relaxed flex-1">{item.desc}</p>
        <div className="flex items-center justify-between gap-2 mt-3 pt-3 border-t border-[var(--line)]">
          {item.rupture
            ? <span className="text-[10px] uppercase tracking-wider text-[var(--rouge-2)] font-bold">Revient bientôt</span>
            : aComposer
            ? <span className="text-[10px] uppercase tracking-wider text-[var(--vert)] font-bold">À composer</span>
            : <span/>}
          {item.rupture ? (
            <span className="btn btn-ghost !py-2 !px-4 !text-xs shrink-0 cursor-not-allowed">En rupture</span>
          ) : (
            <button onClick={() => addToCart(item)} className="btn btn-primary !py-2 !px-4 !text-xs shrink-0">
              <Icon.Plus className="w-4 h-4"/> {aComposer ? 'Composer' : 'Ajouter'}
            </button>
          )}
        </div>
      </div>
    </article>
  );
}

Object.assign(window, { Icon, Logo, PlatVisuel, Header, Hero, PhonePopup, Stat, Ticker, HowItWorks, SignatureFeature, FullMenu, MenuCard });
