// Caffè Italia · screens (Home, Category, Product, Story)
const { useState: _useState, useEffect: _useEffect, useMemo: _useMemo } = React;

// ─── HOME ─────────────────────────────────────────────────────────────────────
function HomeScreen({ navigate, onAdd }) {
  return (
    <main>
      <Hero navigate={navigate}/>
      <FeaturedProducts navigate={navigate} onAdd={onAdd}/>
      <MorenoStory navigate={navigate}/>
      <ProSection navigate={navigate}/>
      <StoryTeaser navigate={navigate}/>
    </main>
  );
}

// ─── Côté pro · Ho.Re.Ca., bureaux, vending ──────────────────────────────────
function ProSection({ navigate }){
  const cards = [
    {
      icon: "☕",
      title: { fr: "Bars & restaurants", it: "Bar & ristoranti" },
      body:  { fr: "Café en grain 1 kg, machines pro, gamme bar Moreno.",
               it: "Caffè in grani 1 kg, macchine pro, gamma bar Moreno." },
    },
    {
      icon: "🏢",
      title: { fr: "Bureaux & vending", it: "Uffici & vending" },
      body:  { fr: "Capsules en gros, miscela vending dédiée, contrats récurrents.",
               it: "Capsule all'ingrosso, miscela vending dedicata, contratti ricorrenti." },
    },
    {
      icon: "📦",
      title: { fr: "Revente & boutiques", it: "Rivendita & boutique" },
      body:  { fr: "Tarifs dégressifs, livraison palette, marque Moreno.",
               it: "Tariffe scaglionate, consegna pallet, brand Moreno." },
    },
  ];
  return (
    <section style={{
      background:"#0e0d0c",color:"#f4ede0",position:"relative",overflow:"hidden",
      borderTop:"1px solid rgba(244,237,224,.08)",
      borderBottom:"1px solid rgba(244,237,224,.08)",
    }}>
      {/* Decorative gold band */}
      <div aria-hidden="true" style={{
        position:"absolute",left:0,right:0,top:0,height:3,
        background:"linear-gradient(90deg, transparent 0%, #caa451 30%, #caa451 70%, transparent 100%)",
      }}/>
      <div className="wrap" style={{padding:"72px 32px"}}>
        <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:24,flexWrap:"wrap",marginBottom:32}}>
          <div>
            <div className="eyebrow" style={{color:"#caa451"}}>
              {window.__LANG__==="it" ? "Per i professionisti" : "Pour les professionnels"}
            </div>
            <h2 className="display" style={{fontSize:"clamp(40px,5.5vw,84px)",margin:"6px 0 0",lineHeight:.95,color:"#f4ede0"}}>
              {window.__LANG__==="it" ? <>Lato<br/><span style={{color:"#caa451"}}>pro.</span></> : <>Côté<br/><span style={{color:"#caa451"}}>pro.</span></>}
            </h2>
          </div>
          <p className="serif" style={{
            fontSize:"clamp(18px,1.6vw,22px)",lineHeight:1.5,color:"#f4ede0",opacity:.78,maxWidth:520,margin:0,
          }}>
            {window.__LANG__==="it"
              ? <>Bar, ristoranti, uffici, distributori automatici, rivendita : abbiamo una gamma e una tariffa dedicate alla tua attività.</>
              : <>Bars, restaurants, bureaux, distributeurs automatiques, revente : gamme et tarifs dédiés à votre activité.</>}
          </p>
        </div>

        <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:18}} className="pro-cards">
          {cards.map((c,i)=>(
            <div key={i} style={{
              padding:"28px 24px",
              background:"rgba(244,237,224,.04)",
              border:"1px solid rgba(244,237,224,.12)",
              borderRadius:6,
              transition:"border-color .2s ease, background .2s ease",
            }} className="pro-card">
              <div style={{fontSize:32,marginBottom:14}}>{c.icon}</div>
              <div style={{fontFamily:"var(--font-display)",fontSize:22,letterSpacing:".01em",color:"#f4ede0"}}>
                {pick(c.title)}
              </div>
              <p style={{fontSize:14,lineHeight:1.55,marginTop:10,color:"#f4ede0",opacity:.72}}>
                {pick(c.body)}
              </p>
            </div>
          ))}
        </div>

        <div style={{display:"flex",alignItems:"center",justifyContent:"center",gap:14,marginTop:36,flexWrap:"wrap"}}>
          <button onClick={()=>navigate({page:"page",slug:"pro"})} style={{
            display:"inline-flex",alignItems:"center",gap:10,
            background:"#caa451",color:"#0e0d0c",
            padding:"16px 26px",borderRadius:99,fontSize:14,fontWeight:700,letterSpacing:".04em",
            border:0,cursor:"pointer",
          }}>
            {window.__LANG__==="it" ? "Scopri l'offerta pro" : "Découvrir l'offre pro"} <IconArrow size={18}/>
          </button>
          <a href="mailto:caffeitalia75@gmail.com?subject=Demande%20pro%20Caffè%20Italia" style={{
            display:"inline-flex",alignItems:"center",gap:10,
            color:"#f4ede0",
            padding:"16px 22px",borderRadius:99,fontSize:13.5,fontWeight:600,letterSpacing:".04em",
            border:"1px solid rgba(244,237,224,.3)",textDecoration:"none",
          }}>
            {window.__LANG__==="it" ? "Contattare il commerciale" : "Contacter un commercial"}
          </a>
        </div>
      </div>

      <style>{`
        .pro-card:hover{border-color:rgba(202,164,81,.5) !important; background:rgba(202,164,81,.06) !important}
        @media (max-width:780px){.pro-cards{grid-template-columns:1fr !important}}
      `}</style>
    </section>
  );
}

// Section « Qui est Caffè Moreno » — bande pleine largeur, palette inversée
// (crème sur fond cream/rouge), vidéo 16:9 dominante, stats en gros chiffres,
// texte en colonnes type magazine. Volontairement différente du StoryTeaser
// pour casser la répétition « media-gauche / texte-droite ».
function MorenoStory({ navigate }){
  const stats = [
    { num: "1960",    label: { fr: "Année de fondation", it: "Anno di fondazione" } },
    { num: "60+",     label: { fr: "Pays distribués",    it: "Paesi distribuiti"  } },
    { num: "III",     label: { fr: "Générations",        it: "Generazioni"        } },
    { num: "100 %",   label: { fr: "Torréfié à Naples",  it: "Tostato a Napoli"   } },
  ];
  return (
    <section style={{background:"#f5ecdb",color:"#1a0f08",marginTop:80,position:"relative",overflow:"hidden"}}>
      {/* Decorative giant typography behind */}
      <div aria-hidden="true" style={{
        position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",
        fontFamily:"var(--font-display)",fontSize:"min(36vw,640px)",lineHeight:1,
        color:"rgba(192,32,44,.06)",pointerEvents:"none",whiteSpace:"nowrap",letterSpacing:"-.04em",
      }}>MORENO</div>

      <div className="wrap" style={{position:"relative",padding:"88px 32px"}}>
        {/* Top band: eyebrow + giant headline spanning full width */}
        <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:32,flexWrap:"wrap",marginBottom:36}}>
          <div>
            <div className="eyebrow" style={{color:"#c8202c"}}>{t("moreno.eyebrow")}</div>
            <h2 className="display" style={{fontSize:"clamp(56px,8vw,140px)",margin:"6px 0 0",lineHeight:.88,color:"#1a0f08"}}>
              {t("moreno.title_l1")}
            </h2>
            <p className="serif" style={{fontStyle:"italic",fontSize:"clamp(22px,2.4vw,36px)",margin:"6px 0 0",color:"#5a2d12"}}>
              {t("moreno.title_l2")}
            </p>
          </div>
          <span style={{
            display:"inline-flex",alignItems:"center",gap:8,fontFamily:"ui-monospace,Menlo,monospace",
            fontSize:11,letterSpacing:".22em",textTransform:"uppercase",
            padding:"8px 14px",background:"#1a0f08",color:"#f5ecdb",borderRadius:99,
          }}>● Napoli · IT</span>
        </div>

        {/* Stats band */}
        <div style={{
          display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:0,
          borderTop:"1px solid rgba(26,15,8,.18)",borderBottom:"1px solid rgba(26,15,8,.18)",
          marginBottom:48,
        }} className="moreno-stats">
          {stats.map((s,i)=>(
            <div key={i} style={{
              padding:"22px 18px",
              borderLeft: i>0 ? "1px solid rgba(26,15,8,.12)" : "none",
              display:"flex",flexDirection:"column",alignItems:"flex-start",gap:6,
            }}>
              <div className="display" style={{fontSize:"clamp(48px,5.5vw,84px)",lineHeight:.9,color:"#c8202c"}}>{s.num}</div>
              <div style={{fontSize:12,letterSpacing:".18em",textTransform:"uppercase",fontWeight:600,color:"#5a2d12"}}>{pick(s.label)}</div>
            </div>
          ))}
        </div>

        {/* Wide cinematic video + side caption */}
        <div className="moreno-video" style={{position:"relative",borderRadius:6,overflow:"hidden",background:"#1a0f08",aspectRatio:"21/9",boxShadow:"0 30px 80px rgba(26,15,8,.25)"}}>
          <video
            autoPlay
            muted
            loop
            playsInline
            controls
            preload="metadata"
            poster="videos/caffe-moreno-poster.jpg"
            style={{width:"100%",height:"100%",objectFit:"cover",display:"block"}}>
            <source src="videos/caffe-moreno.mp4" type="video/mp4"/>
          </video>
          <span style={{
            position:"absolute",left:22,top:22,pointerEvents:"none",
            background:"#c8202c",color:"#fff",padding:"7px 12px",borderRadius:99,
            fontSize:11,fontWeight:700,letterSpacing:".18em",textTransform:"uppercase",
          }}>● {window.__LANG__==="it" ? "Video del marchio" : "Vidéo de la marque"}</span>
          <span style={{
            position:"absolute",right:22,bottom:22,pointerEvents:"none",
            fontFamily:"ui-monospace,Menlo,monospace",fontSize:11,letterSpacing:".18em",
            color:"#f5ecdb",opacity:.85,
          }}>{t("moreno.video_caption")}</span>
        </div>

        {/* Body in 3-column magazine layout */}
        <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:36,marginTop:48}} className="moreno-cols">
          {[t("moreno.body1"), t("moreno.body2"), t("moreno.body3")].map((para,i)=>(
            <div key={i}>
              <div className="display" style={{fontSize:32,color:"#c8202c",lineHeight:.9}}>{String(i+1).padStart(2,"0")}</div>
              <p style={{fontSize:14.5,lineHeight:1.65,marginTop:10,color:"#1a0f08",opacity:.85}}>{para}</p>
            </div>
          ))}
        </div>

        <div style={{display:"flex",justifyContent:"center",marginTop:48}}>
          <button onClick={()=>navigate({page:"all"})} style={{
            display:"inline-flex",alignItems:"center",gap:10,
            background:"#1a0f08",color:"#f5ecdb",
            padding:"18px 28px",borderRadius:99,fontSize:14,fontWeight:700,letterSpacing:".04em",
            border:"0",cursor:"pointer",
          }}>
            {t("moreno.cta")} <IconArrow size={18}/>
          </button>
        </div>
      </div>

      <style>{`
        @media (max-width:900px){
          section .moreno-stats{grid-template-columns:repeat(2,1fr) !important}
          section .moreno-stats > div:nth-child(3){border-left:none !important;border-top:1px solid rgba(26,15,8,.12)}
          section .moreno-stats > div:nth-child(4){border-top:1px solid rgba(26,15,8,.12)}
          section .moreno-cols{grid-template-columns:1fr !important;gap:24px !important}
        }
        @media (max-width:720px){
          /* 21:9 video shrinks to a sliver on mobile · go back to 16:9 */
          section .moreno-cols ~ * + *{}
          .moreno-video{aspect-ratio:16/9 !important}
        }
      `}</style>
    </section>
  );
}

// Hero · magazine cover plein écran : photo Naples en fond, titre overlay en bas,
// un seul CTA primaire. Plus de double colonne, plus de mismatch produit/copie.
function Hero({ navigate }){
  return (
    <section style={{position:"relative",overflow:"hidden",background:"#0a0907",color:"#f4ede0",
      minHeight:"min(86vh, 820px)",display:"flex",flexDirection:"column",justifyContent:"flex-end"}}>

      {/* Full-bleed background photo · poster de la vidéo Caffè Moreno (rues de Naples) */}
      <img src="videos/caffe-moreno-poster.jpg" alt="" aria-hidden="true"
        style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",
          filter:"saturate(1.05) contrast(1.02)"}}/>

      {/* Voile en haut ET en bas pour la lisibilité du caption + du titre */}
      <div aria-hidden="true" style={{position:"absolute",inset:0,background:`
        linear-gradient(180deg,
          rgba(10,9,7,.78) 0%,
          rgba(10,9,7,.35) 14%,
          rgba(10,9,7,.15) 30%,
          rgba(10,9,7,.55) 65%,
          rgba(10,9,7,.92) 92%,
          rgba(10,9,7,.98) 100%)
      `}}/>

      {/* Top overlay · eyebrow gauche + petit caption droite */}
      <div className="wrap" style={{position:"relative",padding:"24px 32px 0",display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:24}}>
        <div className="eyebrow" style={{display:"flex",alignItems:"center",gap:10,color:"#f4ede0",opacity:.9}}>
          <span aria-hidden="true" style={{display:"inline-flex",width:30,height:8,borderRadius:1,overflow:"hidden"}}>
            <span style={{flex:1,background:"#1f8a5b"}}/>
            <span style={{flex:1,background:"#f4ede0"}}/>
            <span style={{flex:1,background:"#c8202c"}}/>
          </span>
          {t("hero.edition")}
        </div>
        <span style={{fontFamily:"ui-monospace,Menlo,monospace",fontSize:11,letterSpacing:".18em",opacity:.7,color:"#f4ede0"}}>
          {t("hero.poster_eyebrow")} · {t("hero.poster_est")}
        </span>
      </div>

      {/* Spacer pour pousser le titre vers le bas */}
      <div style={{flex:1}}/>

      {/* Bottom overlay · titre + lede + CTA + trust pills */}
      <div className="wrap" style={{position:"relative",padding:"0 32px 44px",color:"#f4ede0"}}>
        {/* Plafond mobile : "NAPOLETANO." (~4.9em) doit tenir dans 100vw − 64px de padding,
            sinon .display{overflow-wrap:anywhere} le coupe en "NAPOLETAN / O." */}
        <h1 className="display" style={{
          fontSize:"min(clamp(56px,9vw,160px), calc((100vw - 64px) / 5.5))",lineHeight:.9,margin:0,color:"#f4ede0",
          textShadow:"0 2px 24px rgba(0,0,0,.35)",
        }}>
          {t("hero.title1")}<br/>
          <span style={{color:"#dc2832"}}>{t("hero.title2")}</span> {t("hero.title3")}
        </h1>

        <div style={{display:"grid",gridTemplateColumns:"1.4fr auto",gap:32,alignItems:"end",marginTop:22}} className="hero-bottom">
          <p className="serif" style={{
            fontSize:"clamp(18px,1.7vw,24px)",lineHeight:1.45,margin:0,
            maxWidth:600,color:"#f4ede0",opacity:.92,
          }}>{t("hero.lede")}</p>
          <button onClick={()=>navigate({page:"category",cat:"grain"})} style={{
            display:"inline-flex",alignItems:"center",gap:10,whiteSpace:"nowrap",
            background:"#dc2832",color:"#fff",
            padding:"18px 28px",borderRadius:99,fontSize:14,fontWeight:700,letterSpacing:".04em",
            border:0,cursor:"pointer",boxShadow:"0 14px 40px rgba(220,40,50,.35)",
          }}>
            {t("hero.cta_coffee")} <IconArrow size={18}/>
          </button>
        </div>

        {/* Trust pills · directement sous le titre, dans le hero
            (les overrides CSS adaptent les bordures/sous-titres au fond sombre) */}
        <div className="hero-pills" style={{
          display:"flex",alignItems:"center",gap:36,flexWrap:"wrap",
          marginTop:28,paddingTop:22,borderTop:"1px solid rgba(244,237,224,.18)",
          fontSize:12.5,color:"#f4ede0",
        }}>
          <Pill icon={<IconTruck size={16}/>} t={t("hero.pill_delivery_t")} s={t("hero.pill_delivery_s")} />
          <Pill icon={<IconShield size={16}/>} t={t("hero.pill_pay_t")} s={t("hero.pill_pay_s")} />
          <Pill icon={<IconLeaf size={16}/>} t={t("hero.pill_roast_t")} s={t("hero.pill_roast_s")} />
        </div>
      </div>

      <style>{`
        @media (max-width:780px){
          section .hero-bottom{grid-template-columns:1fr !important; gap:18px !important}
        }
        @media (max-width:520px){
          /* Pills stack more compactly on small screens */
          section .hero-pills{gap:18px !important; padding-top:18px !important}
        }
        /* Scope pill colors to the dark hero so light-mode (--muted = dark)
           doesn't disappear on the photo */
        section .hero-pills > div > span:first-child{border-color:rgba(244,237,224,.32) !important}
        section .hero-pills > div > div > div:last-child{color:rgba(244,237,224,.65) !important}
      `}</style>
    </section>
  );
}

function Pill({icon,t,s}){
  return (
    <div style={{display:"inline-flex",alignItems:"center",gap:10,whiteSpace:"nowrap"}}>
      <span style={{flex:"0 0 auto",width:34,height:34,borderRadius:99,border:"1px solid var(--hairline-strong)",display:"inline-flex",alignItems:"center",justifyContent:"center"}}>{icon}</span>
      <div style={{lineHeight:1.2}}>
        <div style={{fontWeight:700}}>{t}</div>
        <div style={{color:"var(--muted)",fontSize:11.5}}>{s}</div>
      </div>
    </div>
  );
}

// Category strip · flat tiles
function CategoryStrip({ navigate }){
  return (
    <section className="wrap" style={{padding:"64px 32px 12px"}}>
      <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:24,marginBottom:32,flexWrap:"wrap"}}>
        <div>
          <div className="eyebrow">{t("cat.strip_eyebrow")}</div>
          <h2 className="display" style={{fontSize:"clamp(40px,5vw,72px)",margin:"6px 0 0",whiteSpace:"nowrap"}}>{t("cat.strip_title")}</h2>
        </div>
        <button onClick={()=>navigate({page:"all"})} className="btn btn-ghost">{t("cat.strip_cta")} <IconArrow size={16}/></button>
      </div>
      <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:14}} className="cat-grid">
        {window.CATEGORIES.map((c,i)=>{
          const isRed = i===0;
          const isLight = i===3;
          const bg = isRed ? "var(--rosso)" : isLight ? "#f4ede0" : "var(--paper-2)";
          const fg = isRed ? "#ffffff" : isLight ? "#0e0d0c" : "var(--ink)";
          return (
          <button key={c.id} onClick={()=>navigate({page:"category",cat:c.id})}
            className="cat-tile"
            style={{
              textAlign:"left",position:"relative",padding:20,minHeight:200,
              borderRadius:4,overflow:"hidden",
              background:bg,color:fg,
              transition:"transform .2s ease, box-shadow .2s ease",
            }}>
            <div style={{display:"flex",flexDirection:"column",height:"100%",justifyContent:"space-between",gap:12,minHeight:160}}>
              <div className="eyebrow" style={{opacity:.8,color:"inherit"}}>{String(i+1).padStart(2,"0")}</div>
              <div>
                <div className="serif" style={{fontStyle:"italic",fontSize:14,opacity:.75}}>{c.it}</div>
                <div className="display" style={{fontSize:24,marginTop:4}}>{pick(c.name)}</div>
                <div style={{fontSize:11.5,opacity:.7,marginTop:8}}>{window.listedProducts().filter(p=>p.category===c.id).length} {t("cat.refs")}</div>
              </div>
            </div>
          </button>
        );})}
      </div>
      <style>{`
        .cat-tile:hover{transform:translateY(-3px);box-shadow:0 12px 36px rgba(14,13,12,.12)}
        @media (max-width:1100px){.cat-grid{grid-template-columns:repeat(4,1fr) !important}}
        @media (max-width:680px){.cat-grid{grid-template-columns:repeat(2,1fr) !important}}
      `}</style>
    </section>
  );
}

// Featured products · editorial grid 4 across
function FeaturedProducts({ navigate, onAdd }){
  const picks = window.listedProducts().slice(0,6);
  return (
    <section className="wrap" style={{padding:"56px 32px"}}>
      <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:24,marginBottom:32,flexWrap:"wrap"}}>
        <div>
          <div className="eyebrow"><span style={{color:"var(--rosso)"}}>★</span> {t("feat.eyebrow")}</div>
          <h2 className="display" style={{fontSize:"clamp(40px,5vw,72px)",margin:"6px 0 0",whiteSpace:"nowrap"}}>{t("feat.title")}</h2>
        </div>
        <div style={{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"}}>
          {[t("feat.chip_all"),t("feat.chip_caps"),t("feat.chip_ese"),t("feat.chip_ground")].map((tx,i)=>(
            <span key={tx} className={"chip "+(i===0?"":"chip-outline")} style={i===0?{background:"var(--ink)",color:"var(--paper)"}:{}}>{tx}</span>
          ))}
        </div>
      </div>
      <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:32}} className="prod-grid">
        {picks.map(p => <ProductCard key={p.id} p={p} navigate={navigate} onAdd={onAdd}/>)}
      </div>
      <style>{`
        @media (max-width:1100px){.prod-grid{grid-template-columns:repeat(3,1fr) !important}}
        @media (max-width:780px){.prod-grid{grid-template-columns:repeat(2,1fr) !important}}
        @media (max-width:520px){.prod-grid{grid-template-columns:1fr !important}}
      `}</style>
    </section>
  );
}

// Big band manifesto
function ManifestoBand(){
  return (
    <section style={{background:"var(--ink)",color:"var(--paper)",position:"relative",marginTop:24}}>
      <div className="wrap" style={{padding:"96px 32px"}}>
        <div className="eyebrow" style={{color:"var(--crema)"}}>{t("manifesto.eyebrow")}</div>
        <p className="serif" style={{fontSize:"clamp(28px,3.4vw,52px)",lineHeight:1.25,marginTop:18,maxWidth:1100}}
           dangerouslySetInnerHTML={{__html: t("manifesto.text_html")}}/>
        <div style={{marginTop:30,fontSize:13,letterSpacing:".18em",textTransform:"uppercase",opacity:.7}}
             dangerouslySetInnerHTML={{__html: t("manifesto.author")}}/>
      </div>
    </section>
  );
}

// Editorial blocks
function DualEditorial({ navigate }){
  return (
    <section className="wrap" style={{padding:"96px 32px"}}>
      <div style={{display:"grid",gridTemplateColumns:"1.1fr 1fr",gap:48,alignItems:"center"}} className="edit-grid">
        <div style={{position:"relative",aspectRatio:"4/3",borderRadius:4,overflow:"hidden",background:"var(--paper-2)"}}>
          <img src="images/products/moreno-top-extra-espresso-1kg.jpg" alt="Moreno Top Espresso Extra"
            style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"contain",padding:"6%"}}/>
          <span style={{position:"absolute",left:18,top:18}} className="chip chip-rosso">{t("edit2.chip")}</span>
        </div>
        <div>
          <div className="eyebrow">{t("edit2.eyebrow")}</div>
          <h2 className="display" style={{fontSize:"clamp(40px,5vw,72px)",margin:"6px 0 0"}}
              dangerouslySetInnerHTML={{__html: t("edit2.title_html")}}/>
          <p style={{fontSize:16,lineHeight:1.6,color:"var(--muted)",marginTop:18,maxWidth:520}}>
            {t("edit2.body")}
          </p>
          <button onClick={()=>navigate({page:"category",cat:"grain"})} className="btn btn-primary btn-lg" style={{marginTop:24}}>
            {t("edit2.cta")} <IconArrow size={18}/>
          </button>
        </div>
      </div>

      <div style={{display:"grid",gridTemplateColumns:"1fr 1.1fr",gap:48,alignItems:"center",marginTop:80}} className="edit-grid">
        <div>
          <div className="eyebrow">{t("edit3.eyebrow")}</div>
          <h2 className="display" style={{fontSize:"clamp(40px,5vw,72px)",margin:"6px 0 0"}}
              dangerouslySetInnerHTML={{__html: t("edit3.title_html")}}/>
          <p style={{fontSize:16,lineHeight:1.6,color:"var(--muted)",marginTop:18,maxWidth:520}}>
            {t("edit3.body")}
          </p>
          <button onClick={()=>navigate({page:"category",cat:"capsules"})} className="btn btn-ghost btn-lg" style={{marginTop:24}}>
            {t("edit3.cta")} <IconArrow size={18}/>
          </button>
        </div>
        <div style={{position:"relative",aspectRatio:"4/3",borderRadius:4,overflow:"hidden",background:"var(--paper-2)",padding:"4%"}}>
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,width:"100%",height:"100%"}}>
            {["images/products/capsule-moreno-top-aromanespresso.jpg","images/products/moreno-aroma-top-capsule.png",
              "images/products/capsules-compatible-dolce-gusto.jpg","images/products/capsules-compatible-a-modo-mio.jpg"].map((src,i)=>(
              <div key={i} style={{background:"var(--paper)",borderRadius:3,display:"flex",alignItems:"center",justifyContent:"center",padding:8,overflow:"hidden"}}>
                <img src={src} alt="" style={{maxWidth:"100%",maxHeight:"100%",objectFit:"contain"}}/>
              </div>
            ))}
          </div>
          <span style={{position:"absolute",left:22,top:22}} className="chip">{t("edit3.chip")}</span>
        </div>
      </div>

      <style>{`
        @media (max-width:900px){.edit-grid{grid-template-columns:1fr !important; gap:24px !important}}
      `}</style>
    </section>
  );
}

// Subscription band
function PressStrip(){
  return null; // already in hero
}

// Story teaser → /story · poster vertical désaxé + texte centré pour casser
// le rythme « grille deux colonnes égales »
function StoryTeaser({ navigate }){
  return (
    <section className="wrap" style={{padding:"96px 32px"}}>
      <div style={{textAlign:"center",maxWidth:880,margin:"0 auto"}}>
        <div className="eyebrow">{window.__LANG__==="it" ? "La casa" : "La maison"}</div>
        <h2 className="display" style={{fontSize:"clamp(40px,8vw,140px)",margin:"10px 0 0",lineHeight:.86,wordBreak:"break-word"}}>
          {window.__LANG__==="it"
            ? <>Due italiani,<br/><span style={{color:"var(--rosso)"}}>un caffè</span>,<br/><span className="serif" style={{textTransform:"none",fontSize:"55%"}}>dal 2013.</span></>
            : <>Deux Italiens,<br/><span style={{color:"var(--rosso)"}}>un café</span>,<br/><span className="serif" style={{textTransform:"none",fontSize:"55%"}}>depuis 2013.</span></>}
        </h2>
        <p className="serif" style={{fontSize:"clamp(18px,1.6vw,22px)",lineHeight:1.5,color:"var(--ink)",opacity:.78,marginTop:22,maxWidth:640,marginLeft:"auto",marginRight:"auto"}}>
          {window.__LANG__==="it"
            ? <>Due ex ristoratori italiani, appassionati di caffè, importano da Montreuil il caffè che si fa la fila al bancone dei bar di Napoli. Senza intermediari.</>
            : <>Deux ex-restaurateurs italiens, passionnés de café, importent depuis Montreuil le café qui fait la queue au comptoir des bars de Naples. Sans intermédiaire.</>}
        </p>

        {/* Decorative dotted divider with red espresso "tick" */}
        <div aria-hidden="true" style={{display:"flex",alignItems:"center",justifyContent:"center",gap:14,margin:"30px auto 0"}}>
          <span style={{flex:"0 1 120px",height:1,background:"var(--hairline-strong)"}}/>
          <span style={{width:8,height:8,borderRadius:99,background:"var(--rosso)"}}/>
          <span style={{flex:"0 1 120px",height:1,background:"var(--hairline-strong)"}}/>
        </div>

        <button onClick={()=>navigate({page:"story"})} className="btn btn-ghost btn-lg" style={{marginTop:24}}>
          {window.__LANG__==="it" ? "La nostra storia" : "Notre histoire"} <IconArrow size={18}/>
        </button>
      </div>
    </section>
  );
}

function InstaGrid(){
  return (
    <section className="wrap" style={{padding:"32px 32px 80px"}}>
      <div style={{display:"flex",alignItems:"baseline",justifyContent:"space-between",marginBottom:18}}>
        <div>
          <div className="eyebrow">{t("insta.eyebrow")}</div>
          <h2 className="display" style={{fontSize:"clamp(32px,4vw,56px)",margin:"6px 0 0"}}>{t("insta.title_l1")}<br/><span className="serif" style={{textTransform:"none",fontSize:"60%"}}>{t("insta.title_l2")}</span></h2>
        </div>
        <a href="https://www.instagram.com/napoli_caffe_paris" target="_blank" rel="noopener noreferrer" className="btn btn-ghost">{t("insta.cta")} <IconArrow size={16}/></a>
      </div>
      <div style={{display:"grid",gridTemplateColumns:"repeat(6,1fr)",gap:8}} className="insta-grid">
        {[
          "images/products/moreno-top-extra-espresso-1kg.jpg",
          "images/products/cafe-moreno-moulu.png",
          "images/products/capsule-moreno-top-aromanespresso.jpg",
          "images/products/moreno-aroma-top-capsule.png",
          "images/products/tasse.png",
          "images/products/black-truffle-sauce-5-500gr.jpg",
        ].map((src,i)=>(
          <div key={i} style={{background:"var(--paper-2)",aspectRatio:"1",borderRadius:4,overflow:"hidden",position:"relative",display:"flex",alignItems:"center",justifyContent:"center",padding:"10%"}}>
            <img src={src} alt="" loading="lazy" style={{maxWidth:"100%",maxHeight:"100%",objectFit:"contain"}}/>
          </div>
        ))}
      </div>
      <style>{`
        @media (max-width:1000px){.insta-grid{grid-template-columns:repeat(3,1fr) !important}}
      `}</style>
    </section>
  );
}

// ─── CATEGORY ─────────────────────────────────────────────────────────────────
// Une famille regroupe plusieurs catégories (voir FAMILIES dans
// components.jsx). L'écran est le même : seul l'ensemble des produits change,
// donc les filtres intensité/prix et le tri servent aussi bien aux deux.
function CategoryScreen({ cat, family, navigate, onAdd }){
  const fam = family ? (window.FAMILIES || []).find(f => f.key === family) : null;
  const ids = fam
    ? fam.cats
    : [(window.CATEGORIES.find(c=>c.id===cat) || window.CATEGORIES[0]).id];

  // Objet d'affichage : une vraie catégorie, ou une famille qui s'y substitue.
  const category = fam
    ? { id: fam.key, name: fam.label, it: pick(fam.label) }
    : (window.CATEGORIES.find(c=>c.id===cat) || window.CATEGORIES[0]);

  // Products in this category — what we filter against
  const catItems = window.listedProducts().filter(p => ids.includes(p.category));

  // Real bounds derived from the category (no hardcoded magic numbers)
  // Unique intensity levels present in this category, sorted ascending.
  const availableIntensities = Array.from(new Set(
    catItems.map(p => p.intensity).filter(x => x != null)
  )).sort((a,b)=>a-b);
  const hasIntensity = availableIntensities.length > 0;
  const prices = catItems.map(p => p.price);
  const minP = prices.length ? Math.floor(Math.min(...prices)) : 0;
  const maxP = prices.length ? Math.ceil( Math.max(...prices)) : 100;

  const [sort,setSort] = _useState("popular");
  const [view,setView] = _useState(4);   // aligné sur « Tout voir »
  // Selected intensity levels (multi-select). Empty = no filter (show all).
  const [intSel,setIntSel]      = _useState([]);
  const [priceMax,setPriceMax]  = _useState(maxP);
  // Reset filter state when navigating to a different category
  _useEffect(()=>{ setIntSel([]); setPriceMax(maxP); }, [cat, family]);

  // Apply filters
  let items = catItems;
  if (intSel.length > 0) {
    items = items.filter(p => p.intensity == null || intSel.includes(p.intensity));
  }
  items = items.filter(p => p.price <= priceMax);
  if(sort==="price-asc")  items = [...items].sort((a,b)=>a.price-b.price);
  if(sort==="price-desc") items = [...items].sort((a,b)=>b.price-a.price);

  const intDirty = intSel.length > 0;
  const priceDirty = priceMax !== maxP;
  const anyDirty = intDirty || priceDirty;
  const resetAll = () => { setIntSel([]); setPriceMax(maxP); };
  const toggleInt = (n) => setIntSel(prev => prev.includes(n) ? prev.filter(x=>x!==n) : [...prev, n].sort((a,b)=>a-b));

  return (
    <main>
      {/* Breadcrumb */}
      <div className="wrap" style={{padding:"22px 32px 4px",fontSize:12,color:"var(--muted)",display:"flex",gap:8,alignItems:"center"}}>
        <a onClick={()=>navigate({page:"home"})} style={{cursor:"pointer"}}>{t("cat.crumb_home")}</a>
        <span>/</span>
        <a onClick={()=>navigate({page:"home"})} style={{cursor:"pointer"}}>{t("cat.crumb_shop")}</a>
        <span>/</span>
        <span style={{color:"var(--ink)",fontWeight:600}}>{pick(category.name)}</span>
      </div>

      {/* Hero band — compact, products-first */}
      <section className="wrap" style={{padding:"10px 32px 18px"}}>
        <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:24,paddingBottom:14,borderBottom:"1px solid var(--hairline)",flexWrap:"wrap"}}>
          <div>
            <div className="eyebrow" style={{color:"var(--rosso)"}}>{category.it}</div>
            <h1 className="display" style={{fontSize:"clamp(32px,4vw,56px)",margin:"12px 0 0",lineHeight:1.05}}>{pick(category.name)}</h1>
            <p style={{fontSize:13.5,color:"var(--muted)",marginTop:8,maxWidth:640,lineHeight:1.5}}>
              {pick(categoryBlurbs[category.id]) || (fam ? pick(fam.blurb || "") : "")}
            </p>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:14,fontSize:12.5,color:"var(--muted)"}}>
            <span><b style={{color:"var(--ink)"}}>{items.length}</b> {window.__LANG__==="it"?"prodotti":"produits"}</span>
            <span style={{width:1,height:14,background:"var(--hairline-strong)"}}/>
            <span>{t("cat.origin")}</span>
          </div>
        </div>
      </section>

      {/* Grid + toolbar (filters sidebar commented out below for now) */}
      <section className="wrap" style={{padding:"0 32px 80px"}}>
        {/* Toolbar */}
        <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"6px 0 22px",borderBottom:"1px solid var(--hairline)",marginBottom:24,flexWrap:"wrap",gap:12}}>
          <div style={{display:"flex",gap:8,flexWrap:"wrap",alignItems:"center"}}>
            <span style={{fontSize:12.5,color:"var(--muted)"}}>
              <b style={{color:"var(--ink)"}}>{items.length}</b>
              {" "}
              {window.__LANG__==="it" ? (items.length>1?"prodotti":"prodotto") : (items.length>1?"produits":"produit")}
            </span>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:14}}>
            <label style={{fontSize:12.5,display:"flex",alignItems:"center",gap:8}}>
              {t("cat.sort")}
              <select value={sort} onChange={(e)=>setSort(e.target.value)} style={{background:"transparent",border:"1px solid var(--hairline-strong)",borderRadius:99,padding:"6px 12px",fontFamily:"inherit",fontSize:12.5,color:"var(--ink)"}}>
                <option value="popular">{t("cat.sort_popular")}</option>
                <option value="price-asc">{t("cat.sort_asc")}</option>
                <option value="price-desc">{t("cat.sort_desc")}</option>
              </select>
            </label>
            <div className="cat-view-toggle" style={{display:"inline-flex",border:"1px solid var(--hairline-strong)",borderRadius:99,overflow:"hidden"}}>
              {[2,3,4].map(n=>(
                <button key={n} onClick={()=>setView(n)} style={{padding:"6px 10px",fontSize:12,fontWeight:700,background:view===n?"var(--ink)":"transparent",color:view===n?"var(--paper)":"var(--ink)"}}>
                  {n}↔
                </button>
              ))}
            </div>
          </div>
        </div>

        <div className="prod-grid" style={{display:"grid",gridTemplateColumns:`repeat(${view},1fr)`,gap:20}}>
          {items.map(p => <ProductCard key={p.id} p={p} navigate={navigate} onAdd={onAdd}/>)}
        </div>

        {/*
          ─── Filters sidebar (intensity + price) ─────────────────────────────
          Disabled for now — with at most 6 items per category, the filters
          add visual noise without much UX value. Uncomment the block below
          (and wrap the toolbar + grid back in a `240px 1fr` grid with an
          <aside>) to re-enable. The state (intSel, priceMax, intDirty,
          priceDirty, anyDirty, resetAll, toggleInt) and the helper
          components (IntensityPicker, RangeSlider, FilterGroup) are still
          defined and ready to use.

          <aside style={{position:"sticky",top:96,alignSelf:"start"}}>
            {hasIntensity && (
              <FilterGroup label={t("cat.filter_intensity")} custom={
                <IntensityPicker levels={availableIntensities} selected={intSel} onToggle={toggleInt}/>
              }/>
            )}
            <FilterGroup label={t("cat.filter_price")} custom={
              <RangeSlider min={minP} max={maxP} value={[minP, priceMax]} onChange={([_,hi])=>setPriceMax(hi)} suffix=" €" lockMin/>
            }/>
            {anyDirty && (
              <button onClick={resetAll} style={{
                marginTop:18,fontSize:12.5,textDecoration:"underline",color:"var(--muted)",cursor:"pointer",
              }}>{t("cat.clear")}</button>
            )}
          </aside>

          Toolbar chips for active filters (paste back inside the toolbar
          chip row when re-enabling):
            {intDirty && (
              <span className="chip chip-outline" onClick={()=>setIntSel([])} style={{cursor:"pointer"}}>
                {t("cat.filter_intensity")} {intSel.join(", ")}/10 ×
              </span>
            )}
            {priceDirty && (
              <span className="chip chip-outline" onClick={()=>setPriceMax(maxP)} style={{cursor:"pointer"}}>
                ≤ {priceMax} € ×
              </span>
            )}

          Empty state replacement for the grid:
            {items.length > 0 ? (...grid...) : (
              <div style={{padding:"64px 0",textAlign:"center",color:"var(--muted)"}}>
                <p style={{fontSize:15}}>
                  {window.__LANG__==="it" ? "Nessun prodotto corrisponde a questi filtri." : "Aucun produit ne correspond à ces filtres."}
                </p>
                <button onClick={resetAll} className="btn btn-ghost" style={{marginTop:14}}>{t("cat.clear")}</button>
              </div>
            )}
        */}
      </section>
    </main>
  );
}

const categoryBlurbs = {
  grain:    { fr: "Notre sélection de cafés en grain Moreno et Electus, torréfiés lentement à Naples. Pour Moka, expresso bar ou machine à grain.",
              it: "La nostra selezione di caffè in grani Moreno ed Electus, tostati lentamente a Napoli. Per Moka, espresso bar o macchina a grani." },
  moulu:    { fr: "Cafés moulus Moreno, conditionnés pour Moka. Sous vide pour préserver l'arôme jusqu'à l'ouverture du paquet.",
              it: "Caffè macinati Moreno, confezionati per Moka. Sottovuoto per preservare l'aroma fino all'apertura della confezione." },
  capsules: { fr: "Compatibles Nespresso®, A Modo Mio®, Dolce Gusto® et dosettes ESE 44 mm compostables. Le bar italien dans toutes les machines.",
              it: "Compatibili Nespresso®, A Modo Mio®, Dolce Gusto® e cialde ESE 44 mm compostabili. Il bar italiano in tutte le macchine." },
  machines: { fr: "Machines à dosettes ESE 44 mm et packs prêt à l'emploi. Pour faire le bon espresso à la maison.",
              it: "Macchine a cialde ESE 44 mm e pack pronti all'uso. Per fare il vero espresso a casa." },
  tasses:   { fr: "Tazzine espresso en porcelaine, vendues par service. La vaisselle du comptoir italien.",
              it: "Tazzine espresso in porcellana, vendute a servizio. Il vasellame del bancone italiano." },
  epicerie: { fr: "Specialità italiennes sélectionnées : sauces gourmet, truffe noire.",
              it: "Specialità italiane selezionate: salse gourmet, tartufo nero." },
};

function FilterGroup({label,current,onChange,options,custom}){
  return (
    <div style={{padding:"22px 0",borderBottom:"1px solid var(--hairline)"}}>
      <div className="eyebrow" style={{marginBottom:14}}>{label}</div>
      {options ? (
        <div style={{display:"flex",flexDirection:"column",gap:8}}>
          {options.map(o=>(
            <label key={o.v} style={{display:"flex",alignItems:"center",gap:10,fontSize:14,cursor:"pointer"}}>
              <input type="radio" name={label} checked={current===o.v} onChange={()=>onChange(o.v)}/>
              {o.l}
            </label>
          ))}
        </div>
      ) : custom}
    </div>
  );
}

// IntensityPicker — chips multi-select avec barre de 10 segments par niveau,
// même langage visuel que la fiche produit. Compact, responsive, vrai filtre.
function IntensityPicker({ levels, selected, onToggle }){
  return (
    <div role="group" aria-label="Intensité" style={{display:"flex",flexDirection:"column",gap:6}}>
      {levels.map(n => {
        const on = selected.includes(n);
        return (
          <button
            key={n}
            type="button"
            onClick={()=>onToggle(n)}
            aria-pressed={on}
            style={{
              display:"flex",alignItems:"center",gap:10,
              padding:"7px 10px",borderRadius:6,
              background: on ? "var(--paper-3)" : "transparent",
              border: "1px solid " + (on ? "var(--ink)" : "var(--hairline)"),
              cursor:"pointer",textAlign:"left",
              transition:"background .15s ease, border-color .15s ease",
            }}
          >
            <span style={{display:"inline-flex",gap:2,flex:1}} aria-hidden="true">
              {Array.from({length:10}).map((_,i)=>(
                <span key={i} style={{
                  flex:1,height:14,borderRadius:1,
                  background: i<n ? (on?"var(--rosso)":"var(--ink)") : "var(--hairline)",
                  transition:"background .15s ease",
                }}/>
              ))}
            </span>
            <span style={{fontSize:11,fontWeight:700,color: on?"var(--ink)":"var(--muted)",minWidth:32,textAlign:"right"}}>
              {n}/10
            </span>
          </button>
        );
      })}
    </div>
  );
}

// Range slider — two native <input type="range"> stacked, so it's accessible
// (keyboard + screen reader) and the values are real. `lockMin` keeps the low
// bound stuck (useful for "max price" with a fixed floor).
function RangeSlider({ min, max, value, onChange, suffix="", lockMin=false }){
  const [lo, hi] = value;
  const setLo = (v) => onChange([Math.min(Number(v), hi), hi]);
  const setHi = (v) => onChange([lo, Math.max(Number(v), lo)]);
  if (min === max) {
    return <div style={{fontSize:12.5,color:"var(--muted)"}}>{min}{suffix}</div>;
  }
  return (
    <div>
      <div style={{display:"flex",justifyContent:"space-between",fontSize:12,color:"var(--muted)"}}>
        <span>{min}{suffix}</span><span>{max}{suffix}</span>
      </div>
      <div style={{position:"relative",height:28,marginTop:4}}>
        {/* Track */}
        <div style={{position:"absolute",left:0,right:0,top:13,height:3,background:"var(--paper-3)",borderRadius:99}}/>
        {/* Active range */}
        <div style={{
          position:"absolute",top:13,height:3,background:"var(--ink)",borderRadius:99,
          left:`${((lo-min)/(max-min))*100}%`,right:`${(1-(hi-min)/(max-min))*100}%`,
        }}/>
        {/* Low thumb */}
        {!lockMin && (
          <input type="range" min={min} max={max} value={lo} onChange={(e)=>setLo(e.target.value)}
            aria-label={`min ${suffix}`}
            style={{position:"absolute",inset:0,width:"100%",margin:0,appearance:"none",background:"transparent",pointerEvents:"none"}}
            className="rs-thumb"/>
        )}
        {/* High thumb */}
        <input type="range" min={min} max={max} value={hi} onChange={(e)=>setHi(e.target.value)}
          aria-label={`max ${suffix}`}
          style={{position:"absolute",inset:0,width:"100%",margin:0,appearance:"none",background:"transparent",pointerEvents:"none"}}
          className="rs-thumb"/>
      </div>
      <div style={{fontSize:12.5,marginTop:6,fontWeight:600}}>
        {lockMin ? `≤ ${hi}${suffix}` : `${lo}${suffix} · ${hi}${suffix}`}
      </div>
      <style>{`
        .rs-thumb::-webkit-slider-thumb{appearance:none;width:16px;height:16px;background:var(--paper);border:2px solid var(--ink);border-radius:99px;pointer-events:auto;cursor:pointer;margin-top:0}
        .rs-thumb::-moz-range-thumb{width:14px;height:14px;background:var(--paper);border:2px solid var(--ink);border-radius:99px;pointer-events:auto;cursor:pointer}
        .rs-thumb::-webkit-slider-runnable-track{background:transparent;height:28px}
        .rs-thumb::-moz-range-track{background:transparent;height:28px}
        .rs-thumb:focus-visible::-webkit-slider-thumb{outline:2px solid var(--rosso);outline-offset:2px}
      `}</style>
    </div>
  );
}

// ─── PRODUCT DETAIL ───────────────────────────────────────────────────────────
function ProductScreen({ id, navigate, onAdd }){
  const base = window.PRODUCTS.find(x=>x.id===id) || window.PRODUCTS[0];
  // Les SKU d'un même `variantGroup` sont le même produit en plusieurs
  // formats : on les propose dans le sélecteur FORMAT sans changer d'URL.
  const group = window.variantsOf(base);
  const [selId,setSelId] = _useState(base.id);
  _useEffect(()=>{ setSelId(base.id); }, [base.id]);
  const p = group.find(x=>x.id===selId) || base;

  const [qty,setQty] = _useState(1);
  const [tab,setTab] = _useState("description");

  // Une seule photo → pas de carrousel. `image` est la photo principale,
  // `images` (optionnel, back-office) les suivantes ; les doublons sautent.
  const images = [...new Set([p.image, ...(Array.isArray(p.images) ? p.images : [])].filter(Boolean))];
  const [imgIdx,setImgIdx] = _useState(0);
  _useEffect(()=>{ setImgIdx(0); }, [p.id]);
  const activeImg = images[Math.min(imgIdx, images.length-1)];

  // Les avis sont partagés par tout le groupe de variantes.
  const reviews = useReviews(group.map(x=>x.id));

  return (
    <main>
      <div className="wrap" style={{padding:"22px 32px 8px",fontSize:12,color:"var(--muted)",display:"flex",gap:8,alignItems:"center",flexWrap:"wrap",minWidth:0}}>
        <a onClick={()=>navigate({page:"home"})} style={{cursor:"pointer"}}>{t("cat.crumb_home")}</a>
        <span>/</span>
        <a onClick={()=>navigate({page:"category",cat:p.category})} style={{cursor:"pointer"}}>{pick((window.CATEGORIES.find(c=>c.id===p.category)||{name:""}).name)}</a>
        <span>/</span>
        <span style={{color:"var(--ink)",fontWeight:600,minWidth:0,wordBreak:"break-word"}}>{pick(p.name)}</span>
      </div>

      <section className="wrap" style={{padding:"18px 32px 64px"}}>
        <div style={{display:"grid",gridTemplateColumns:"1.05fr 1fr",gap:48,alignItems:"start"}} className="prod-grid-detail">
          {/* Gallery · la colonne de miniatures n'apparaît qu'à partir de 2 photos */}
          <div style={{display:"grid",gridTemplateColumns: images.length > 1 ? "88px 1fr" : "1fr",gap:14}} className={"gallery" + (images.length > 1 ? "" : " gallery-single")}>
            {images.length > 1 && (
              <div style={{display:"flex",flexDirection:"column",gap:10}}>
                {images.map((src,i)=>(
                  <button key={src+i} onClick={()=>setImgIdx(i)} aria-label={`Photo ${i+1}`} style={{
                    aspectRatio:"1",borderRadius:3,padding:6,
                    background:"var(--paper-2)",
                    border: i===imgIdx ? "2px solid var(--ink)" : "2px solid var(--hairline)",
                    display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",
                  }}>
                    <img src={src} alt="" aria-hidden="true"
                      style={{maxWidth:"100%",maxHeight:"100%",objectFit:"contain",opacity: i===imgIdx?1:.7}}/>
                  </button>
                ))}
              </div>
            )}
            <div style={{position:"relative",aspectRatio:"4/5",borderRadius:4,overflow:"hidden",background:"var(--paper-2)"}}>
              {activeImg ? (
                <div style={{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",padding:"6%",
                  background:`radial-gradient(circle at 50% 35%, ${p.palette[2]}33 0%, var(--paper-2) 70%)`}}>
                  <img src={activeImg} alt={pick(p.name)}
                    style={{maxWidth:"100%",maxHeight:"100%",objectFit:"contain",filter:"drop-shadow(0 18px 40px rgba(0,0,0,.3))"}}/>
                </div>
              ) : (
                <div style={{position:"absolute",inset:0,background:`linear-gradient(180deg, ${p.palette[0]} 0 60%, ${p.palette[2]} 60% 100%)`}}>
                  <ProductBottle p={p}/>
                </div>
              )}
              <div className="grain" style={{position:"absolute",inset:0}}/>
              {p.badge && <span className="chip chip-rosso" style={{position:"absolute",top:18,left:18}}>{pick(p.badge)}</span>}
            </div>
          </div>

          {/* Info */}
          <div>
            <div className="eyebrow" style={{color:"var(--rosso)"}}>{pick((window.CATEGORIES.find(c=>c.id===p.category)||{name:""}).name)} · Italia</div>
            <h1 className="display" style={{fontSize:"clamp(28px,5vw,72px)",margin:"12px 0 0",lineHeight:1,overflowWrap:"anywhere",hyphens:"auto"}}>{pick(p.name)}</h1>
            <p className="serif" style={{fontSize:22,marginTop:10,color:"var(--ink)"}}>{pick(p.sub)}</p>

            {/* Note · uniquement s'il existe de vrais avis */}
            {reviews.count > 0 && (
              <button onClick={()=>{ setTab("reviews"); }} style={{display:"flex",alignItems:"center",gap:14,marginTop:18,cursor:"pointer"}}>
                <Stars value={reviews.avg}/>
                <span style={{fontSize:13,color:"var(--muted)",textDecoration:"underline"}}>
                  {reviews.avg.toFixed(1).replace(".",",")} / 5 · {reviews.count} {window.__LANG__==="it"?"recensioni":"avis"}
                </span>
              </button>
            )}

            <div style={{display:"flex",alignItems:"baseline",gap:14,marginTop:22,flexWrap:"wrap"}}>
              <span className="display" style={{fontSize:"clamp(36px,4vw,54px)",letterSpacing:".01em",color:"var(--ink)",whiteSpace:"nowrap"}}>{p.price.toFixed(2).replace(".",",")} €</span>
              <span style={{fontSize:13,color:"var(--muted)",whiteSpace:"nowrap"}}>{t("prod.tax")}</span>
            </div>

            {/* Tasting card */}
            {p.intensity && (
              <div style={{marginTop:24,padding:"18px 20px",background:"var(--paper-2)",borderRadius:4}}>
                <div className="eyebrow">{t("prod.aroma")}</div>
                <div style={{display:"flex",alignItems:"center",gap:14,marginTop:8}}>
                  <span className="serif" style={{fontSize:20,fontStyle:"italic"}}>{pick(p.tasting)}</span>
                </div>
                <div style={{display:"flex",alignItems:"center",gap:14,marginTop:14,flexWrap:"wrap"}}>
                  <span style={{fontSize:12,color:"var(--muted)",minWidth:80}}>{t("cat.filter_intensity")}</span>
                  <span style={{display:"inline-flex",gap:3,flex:"1 1 auto",minWidth:0}}>
                    {Array.from({length:10}).map((_,i)=>(
                      <span key={i} style={{flex:"1 1 0",maxWidth:18,height:18,background:i<p.intensity?"var(--ink)":"var(--hairline)",borderRadius:1}}/>
                    ))}
                  </span>
                  <span style={{fontSize:13,fontWeight:700}}>{p.intensity}/10</span>
                </div>
              </div>
            )}

            {/* Format · un bouton par variante, chacune avec son prix */}
            <div style={{marginTop:22}}>
              <div className="eyebrow" style={{marginBottom:10}}>{t("prod.format")}</div>
              <div style={{display:"flex",gap:8,flexWrap:"wrap"}}>
                {group.map(v=>{
                  const on = v.id === p.id;
                  return (
                    <button key={v.id} onClick={()=>setSelId(v.id)} aria-pressed={on} style={{
                      padding:"10px 16px",borderRadius:4,fontWeight:600,fontSize:13.5,textAlign:"left",
                      background: on ? "var(--ink)" : "transparent",
                      color:      on ? "var(--paper)" : "var(--ink)",
                      border:"1px solid "+(on ? "var(--ink)" : "var(--hairline-strong)"),
                    }}>
                      {window.fmtWeight(v)}
                      {group.length > 1 && (
                        <span style={{display:"block",fontSize:12,fontWeight:500,opacity:.72,marginTop:2}}>
                          {v.price.toFixed(2).replace(".",",")} €
                        </span>
                      )}
                    </button>
                  );
                })}
              </div>
            </div>

            {/* Add to cart */}
            <div style={{display:"flex",gap:10,marginTop:22,flexWrap:"wrap"}} className="pdp-buy">
              <Stepper value={qty} onChange={setQty}/>
              <button onClick={()=>onAdd(p,qty)} className="btn btn-rosso btn-lg" style={{flex:"1 1 200px",minWidth:0}}>
                {t("prod.add_cart")} · {(p.price*qty).toFixed(2).replace(".",",")} €
              </button>
              <button aria-label="♥" className="pdp-fav" style={{flex:"0 0 auto",width:56,height:56,border:"1px solid var(--hairline-strong)",borderRadius:99,display:"inline-flex",alignItems:"center",justifyContent:"center"}}><IconHeart size={22}/></button>
            </div>

            {/* Trust list */}
            <div style={{marginTop:22,display:"flex",flexDirection:"column",gap:8,fontSize:13.5}}>
              {[t("prod.benefits_delivery"), t("prod.benefits_import"), t("prod.benefits_return")].map((line,i)=>(
                <div key={i} style={{display:"flex",gap:10}}>
                  <span style={{color:"var(--rosso)"}}>✦</span>{line}
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Tabs */}
        <div style={{marginTop:72,borderTop:"1px solid var(--hairline)",borderBottom:"1px solid var(--hairline)"}}>
          <div style={{display:"flex",gap:32,overflowX:"auto"}} className="tab-bar">
            {[
              ["description",t("prod.tab_desc")],
              ["recipe",t("prod.tab_recipe")],
              ["specs",t("prod.tab_specs")],
              ["reviews",`${t("prod.tab_reviews")}${reviews.count ? ` (${reviews.count})` : ""}`],
            ].map(([k,l])=>(
              <button key={k} onClick={()=>setTab(k)} style={{
                padding:"18px 0",fontSize:13.5,fontWeight:600,letterSpacing:".02em",whiteSpace:"nowrap",
                color:tab===k?"var(--ink)":"var(--muted)",
                borderBottom:"2px solid "+(tab===k?"var(--rosso)":"transparent"),
                marginBottom:-1,
              }}>{l}</button>
            ))}
          </div>
        </div>

        <div style={{padding:"30px 0",display:"grid",gridTemplateColumns:"1.4fr 1fr",gap:32}} className="tab-grid">
          {tab==="description" && (
            <>
              <div style={{fontSize:16,lineHeight:1.65,maxWidth:680}}>
                <p><strong>{pick(p.name)}</strong> · {pick(p.sub)}.</p>
                {p.tasting && <p className="serif" style={{fontStyle:"italic",fontSize:18,marginTop:8}}>{pick(p.tasting)}</p>}
              </div>
              <div style={{padding:24,background:"var(--paper-2)",borderRadius:4}}>
                <div className="eyebrow">{window.__LANG__==="it"?"Buono a sapersi":"Bon à savoir"}</div>
                <ul style={{listStyle:"none",padding:0,margin:"12px 0 0",display:"flex",flexDirection:"column",gap:8,fontSize:14}}>
                  <li>· {t("prod.format")} : <strong>{window.fmtWeight(p)}</strong></li>
                  <li>· {t("cat.filter_intensity")} : {p.intensity ? p.intensity + "/10" : "−"}</li>
                  {p.tasting && <li>· {t("prod.aroma")} : {pick(p.tasting)}</li>}
                </ul>
              </div>
            </>
          )}
          {tab==="recipe" && (
            <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:18,gridColumn:"1 / -1"}} className="recipe-grid">
              {(window.__LANG__==="it" ? [
                ["01","Riempire","Acqua fredda fino alla valvola della Moka · né più, né meno."],
                ["02","Livellare","Macinatura media, a filo del filtro, senza pressare."],
                ["03","Fuoco dolce","Avvitare, fuoco medio-basso. Spegnere quando il gorgoglio si attenua."],
              ] : [
                ["01","Remplir","Eau froide jusqu’à la valve de la Moka · ni plus, ni moins."],
                ["02","Tasser légèrement","Mouture moyenne, à ras du filtre, sans presser fort."],
                ["03","Feu doux","Vissez, feu moyen-doux. Coupez quand le gargouillis s’atténue."],
              ]).map(s=>(
                <div key={s[0]} style={{padding:24,background:"var(--paper-2)",borderRadius:4}}>
                  <div className="display" style={{fontSize:48,color:"var(--rosso)"}}>{s[0]}</div>
                  <div style={{fontWeight:700,marginTop:6,fontSize:18}}>{s[1]}</div>
                  <div style={{fontSize:14,color:"var(--muted)",marginTop:6,lineHeight:1.5}}>{s[2]}</div>
                </div>
              ))}
            </div>
          )}
          {tab==="specs" && (
            <div style={{gridColumn:"1 / -1",overflowX:"auto"}}>
              <table style={{width:"100%",borderCollapse:"collapse"}}>
                <tbody>
                  {[
                    [t("cat.filter_type"),       pick((window.CATEGORIES.find(c=>c.id===p.category)||{name:""}).name)],
                    [t("prod.format"),           window.fmtWeight(p)],
                    [t("cat.filter_intensity"),  p.intensity?p.intensity+"/10":"−"],
                    [t("prod.aroma"),            p.tasting ? pick(p.tasting) : "−"],
                  ].map((row,i)=>(
                    <tr key={i} style={{borderBottom:"1px solid var(--hairline)"}}>
                      <td style={{padding:"14px 0",fontSize:13.5,color:"var(--muted)",width:240}}>{row[0]}</td>
                      <td style={{padding:"14px 0",fontSize:14,fontWeight:600}}>{row[1]}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
          {tab==="reviews" && (
            <ReviewsPanel productId={p.id} groupIds={group.map(x=>x.id)} reviews={reviews} navigate={navigate}/>
          )}
        </div>

        {/* You might also like */}
        <div style={{marginTop:32}}>
          <h3 className="display" style={{fontSize:36,marginTop:6}}>{t("prod.crosssell")}</h3>
          <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:24,marginTop:18}} className="prod-grid">
            {window.listedProducts().filter(x=>x.variantGroup ? x.variantGroup!==p.variantGroup : x.id!==p.id).slice(0,4).map(p2 => (
              <ProductCard key={p2.id} p={p2} navigate={navigate} onAdd={onAdd}/>
            ))}
          </div>
        </div>
      </section>

      <style>{`
        @media (max-width:900px){
          main .prod-grid-detail{grid-template-columns:1fr !important}
          /* Grid items need min-width:0 to let children (H1 etc.) wrap */
          main .prod-grid-detail > div{min-width:0}
          /* Thumbnails: stack horizontally above main image, max 64px each */
          main .gallery:not(.gallery-single){grid-template-columns:1fr !important}
          main .gallery:not(.gallery-single) > div:first-child{
            display:flex !important; flex-direction:row !important;
            gap:8px !important; order:2; margin-top:10px;
          }
          main .gallery:not(.gallery-single) > div:first-child > button{
            flex:1 1 0; aspect-ratio:1; min-width:0;
          }
          main .gallery:not(.gallery-single) > div:last-child{order:1}
          main .tab-grid{grid-template-columns:1fr !important}
        }
        /* Les 3 étapes de la recette Moka : 3 colonnes tiennent mal sous 900px */
        @media (max-width:900px){ main .recipe-grid{grid-template-columns:1fr 1fr !important} }
        @media (max-width:620px){ main .recipe-grid{grid-template-columns:1fr !important} }
        @media (max-width:460px){
          /* Quantité + favori sur une ligne, le bouton principal passe dessous
             plutôt que de laisser le cœur seul sur sa propre ligne. */
          main .pdp-buy{gap:8px !important}
          main .pdp-buy > .btn-lg{order:3; flex:1 1 100% !important}
        }
        main .tab-bar{scrollbar-width:none}
        main .tab-bar::-webkit-scrollbar{display:none}
      `}</style>
    </main>
  );
}

// ─── STORY / ABOUT ────────────────────────────────────────────────────────────
function StoryScreen({ navigate }){
  return (
    <main>
      <section className="wrap" style={{padding:"56px 32px 24px"}}>
        <div className="eyebrow">{t("story.eyebrow")}</div>
        <h1 className="display" style={{fontSize:"clamp(44px,11vw,200px)",margin:"6px 0 0",lineHeight:.86,wordBreak:"break-word"}}
            dangerouslySetInnerHTML={{__html: t("story.title_html")}}/>
      </section>
      <section className="wrap" style={{padding:"32px 32px"}}>
        <div style={{display:"grid",gridTemplateColumns:"1.1fr 1fr",gap:48,alignItems:"center"}} className="edit-grid">
          <div style={{position:"relative",aspectRatio:"4/5",borderRadius:4,overflow:"hidden",background:"var(--paper-2)",padding:"6%"}}>
            <img src="images/products/moreno-top-extra-espresso-1kg.jpg" alt=""
              style={{width:"100%",height:"100%",objectFit:"contain",filter:"drop-shadow(0 18px 40px rgba(0,0,0,.25))"}}/>
          </div>
          <div>
            <p className="serif" style={{fontSize:24,lineHeight:1.4}}>{t("story.body1")}</p>
            <p style={{fontSize:16,lineHeight:1.6,color:"var(--muted)",marginTop:14}}>{t("story.body2")}</p>
            <button onClick={()=>navigate({page:"category",cat:"grain"})} className="btn btn-primary btn-lg" style={{marginTop:24}}>
              {t("story.cta")} <IconArrow size={18}/>
            </button>
          </div>
        </div>
      </section>

      <section className="wrap" style={{padding:"72px 32px"}}>
        <div className="eyebrow">{window.__LANG__==="it"?"Cronologia":"Chronologie"}</div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:18,marginTop:18}} className="timeline">
          {(window.__LANG__==="it" ? [
            ["2013","Fondazione","Due italiani ex ristoratori fondano Caffè Italia, distribuzione di caffè napoletano in Francia."],
            ["—",   "Catalogo",  "Moreno, capsule compatibili, cialde ESE, macchine, tazzine e specialità italiane."],
            ["—",   "Sede",      "Magazzino e logistica a Montreuil, alle porte di Parigi."],
            ["2026","Boutique",  "Vendita online · spedizione in tutta la Francia."],
          ] : [
            ["2013","Fondation","Deux Italiens ex-restaurateurs fondent Caffè Italia, distribution de café napolitain en France."],
            ["—",   "Catalogue","Moreno, capsules compatibles, dosettes ESE, machines, tazzine et épicerie italienne."],
            ["—",   "Siège",    "Entrepôt et logistique à Montreuil, en banlieue parisienne."],
            ["2026","Boutique", "Vente en ligne · livraison partout en France."],
          ]).map(([y,title,desc])=>(
            <div key={title} style={{padding:24,background:"var(--paper-2)",borderRadius:4,borderTop:"3px solid var(--rosso)"}}>
              <div className="display" style={{fontSize:44,color:"var(--ink)"}}>{y}</div>
              <div style={{fontWeight:700,marginTop:8,fontSize:17}}>{title}</div>
              <div style={{fontSize:13.5,color:"var(--muted)",marginTop:6,lineHeight:1.5}} dangerouslySetInnerHTML={{__html:desc}}/>
            </div>
          ))}
        </div>
        <style>{`
          @media (max-width:900px){.timeline{grid-template-columns:repeat(2,1fr) !important}}
          @media (max-width:560px){.timeline{grid-template-columns:1fr !important}}
        `}</style>
      </section>
    </main>
  );
}

// ─── SHOP ALL ────────────────────────────────────────────────────────────────
// Catalogue complet sur une page, groupé par catégorie.
function ShopAllScreen({ navigate, onAdd }){
  const products = window.listedProducts();
  return (
    <main>
      <div className="wrap" style={{padding:"22px 32px 4px",fontSize:12,color:"var(--muted)",display:"flex",gap:8,alignItems:"center"}}>
        <a onClick={()=>navigate({page:"home"})} style={{cursor:"pointer"}}>{t("cat.crumb_home")}</a>
        <span>/</span>
        <span style={{color:"var(--ink)",fontWeight:600}}>{t("all.title")}</span>
      </div>

      <section className="wrap" style={{padding:"10px 32px 18px"}}>
        <div style={{display:"flex",alignItems:"flex-end",justifyContent:"space-between",gap:24,paddingBottom:14,borderBottom:"1px solid var(--hairline)",flexWrap:"wrap"}}>
          <div>
            <div className="eyebrow" style={{color:"var(--rosso)"}}>{t("all.eyebrow")}</div>
            <h1 className="display" style={{fontSize:"clamp(32px,4vw,56px)",margin:"12px 0 0",lineHeight:1.05}}>{t("all.title")}</h1>
            <p style={{fontSize:13.5,color:"var(--muted)",marginTop:8,maxWidth:560}}>{t("all.body", products.length)}</p>
          </div>
          <div style={{display:"flex",alignItems:"center",gap:14,fontSize:12.5,color:"var(--muted)"}}>
            <span><b style={{color:"var(--ink)"}}>{products.length}</b> {window.__LANG__==="it"?"prodotti":"produits"}</span>
            <span style={{width:1,height:14,background:"var(--hairline-strong)"}}/>
            <span><b style={{color:"var(--ink)"}}>{window.CATEGORIES.length}</b> {window.__LANG__==="it"?"categorie":"catégories"}</span>
          </div>
        </div>

        {/* Quick anchor jump — supplier-friendly */}
        <div style={{display:"flex",alignItems:"center",gap:8,marginTop:14,flexWrap:"wrap",fontSize:12}}>
          <span style={{color:"var(--muted)",letterSpacing:".14em",textTransform:"uppercase",fontWeight:600,fontSize:11}}>
            {window.__LANG__==="it"?"Vai a:":"Aller à :"}
          </span>
          {window.CATEGORIES.map(cat => (
            <a key={cat.id} href={`#cat-${cat.id}`} style={{
              padding:"4px 10px",borderRadius:99,border:"1px solid var(--hairline-strong)",
              fontWeight:600,fontSize:11.5,color:"var(--ink)",
            }}>{pick(cat.name)}</a>
          ))}
        </div>
      </section>

      <section className="wrap" style={{padding:"0 32px 80px"}}>
        {window.CATEGORIES.map(cat => {
          const items = products.filter(p => p.category === cat.id);
          if (items.length === 0) return null;
          return (
            <div key={cat.id} id={`cat-${cat.id}`} style={{marginTop:32,scrollMarginTop:90}}>
              <div style={{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:18,paddingBottom:10,borderBottom:"1px solid var(--hairline)",marginBottom:18,flexWrap:"wrap"}}>
                <div style={{display:"flex",alignItems:"baseline",gap:14,flexWrap:"wrap"}}>
                  <h2 className="display" style={{fontSize:"clamp(20px,2vw,28px)",margin:0,lineHeight:1}}>{pick(cat.name)}</h2>
                  <span className="serif" style={{fontStyle:"italic",fontSize:14,color:"var(--rosso)"}}>{cat.it}</span>
                  <span style={{fontSize:12,color:"var(--muted)"}}>· {items.length}</span>
                </div>
                <button onClick={()=>navigate({page:"category",cat:cat.id})} className="btn btn-ghost btn-sm">
                  {t("cat.strip_cta")} <IconArrow size={14}/>
                </button>
              </div>
              <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:20}} className="prod-grid">
                {items.map(p => <ProductCard key={p.id} p={p} navigate={navigate} onAdd={onAdd}/>)}
              </div>
            </div>
          );
        })}
        <style>{`
          @media (max-width:1100px){main .prod-grid{grid-template-columns:repeat(3,1fr) !important}}
          @media (max-width:780px){main .prod-grid{grid-template-columns:repeat(2,1fr) !important}}
          @media (max-width:520px){main .prod-grid{grid-template-columns:1fr !important}}
          @media (max-width:900px){main .cat-hero{grid-template-columns:1fr !important}}
        `}</style>
      </section>
    </main>
  );
}

// ─── INFO PAGES ──────────────────────────────────────────────────────────────
// Pages texte : Contact, Livraison, Retours, FAQ, Mentions légales, CGV,
// Confidentialité. Le contenu décrit la boutique telle qu'elle tourne
// aujourd'hui : site hébergé par Vercel, comptes et catalogue chez
// Supabase, paiements chez Stripe.

const COMPANY = {
  name:    "CAFFE ITALIA",
  address: "6-8 Place Colette Lepage, 93100 Montreuil, France",
  email:   "caffeitalia75@gmail.com",
  siret:   "790 500 912 00023",
  tva:     "FR91790500912",
  instagram: "https://www.instagram.com/napoli_caffe_paris",
  founded: "2013",
};

// Helper rendu : DescList, FAQItem, ExternalLink
function DescList({ items }){
  return (
    <dl style={{display:"grid",gridTemplateColumns:"180px 1fr",gap:"10px 24px",margin:"18px 0",fontSize:14.5,lineHeight:1.5}} className="page-dl">
      {items.map((it,i)=>(
        <React.Fragment key={i}>
          <dt style={{color:"var(--muted)",fontSize:12.5,letterSpacing:".06em",textTransform:"uppercase",fontWeight:600,paddingTop:2}}>{it.k}</dt>
          <dd style={{margin:0}}>{it.v}</dd>
        </React.Fragment>
      ))}
      <style>{`@media(max-width:680px){.page-dl{grid-template-columns:1fr !important;gap:2px 0 !important}.page-dl dd{margin-bottom:12px !important}}`}</style>
    </dl>
  );
}
function FAQItem({ q, a }){
  const [open, setOpen] = _useState(false);
  return (
    <div style={{borderBottom:"1px solid var(--hairline)"}}>
      <button onClick={()=>setOpen(!open)} aria-expanded={open} style={{
        width:"100%",textAlign:"left",padding:"18px 0",display:"flex",justifyContent:"space-between",
        gap:16,alignItems:"center",fontSize:15.5,fontWeight:600,cursor:"pointer",
      }}>
        <span>{q}</span>
        <span style={{flex:"0 0 auto",fontFamily:"var(--font-display)",fontSize:22,color:"var(--rosso)",lineHeight:1,transform:open?"rotate(45deg)":"rotate(0)",transition:"transform .2s ease"}}>+</span>
      </button>
      {open && <div style={{paddingBottom:18,fontSize:14.5,lineHeight:1.6,color:"var(--ink)",opacity:.85,maxWidth:760}}>{a}</div>}
    </div>
  );
}
function ExtLink({ href, children }){
  return <a href={href} target="_blank" rel="noopener noreferrer" style={{color:"var(--rosso)",textDecoration:"underline"}}>{children}</a>;
}

// Page registry — clé = slug d'URL
const PAGES_CONTENT = {
  contact: {
    title:    { fr: "Contact",         it: "Contatti" },
    eyebrow:  { fr: "Service client",  it: "Servizio clienti" },
    render: () => (
      <>
        <p>
          {window.__LANG__==="it"
            ? <>Per una domanda su un ordine, una richiesta professionale (Ho.Re.Ca., vending, monodose) o per organizzare una degustazione, scrivici · ti rispondiamo entro 48 ore lavorative.</>
            : <>Pour une question sur une commande, une demande pro (Ho.Re.Ca., vending, monodose) ou organiser une dégustation, écrivez-nous · nous répondons sous 48 h ouvrées.</>}
        </p>
        <DescList items={[
          { k: window.__LANG__==="it"?"Email":"Email",      v: <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)",fontWeight:600}}>{COMPANY.email}</a> },
          { k: window.__LANG__==="it"?"Indirizzo":"Adresse", v: COMPANY.address },
          { k: "Instagram",                                  v: <ExtLink href={COMPANY.instagram}>@napoli_caffe_paris</ExtLink> },
        ]}/>
        <p style={{fontSize:13,color:"var(--muted)",marginTop:24}}>
          {window.__LANG__==="it"
            ? <>Per ordini esistenti, indica il numero d'ordine nel messaggio.</>
            : <>Pour les commandes existantes, indiquez votre numéro de commande dans le message.</>}
        </p>
      </>
    ),
  },

  livraison: {
    title:   { fr: "Livraison",         it: "Spedizione" },
    eyebrow: { fr: "Modes d'expédition", it: "Modalità di spedizione" },
    render: () => (
      <>
        <p>
          {window.__LANG__==="it"
            ? <>Spediamo da Montreuil con corriere standard. <b>Spedizione gratuita oltre 50 €</b> in Francia metropolitana.</>
            : <>Nous expédions depuis Montreuil par transporteur standard. <b>Livraison offerte dès 50 €</b> en France métropolitaine.</>}
        </p>
        <DescList items={[
          { k: window.__LANG__==="it"?"Zona":"Zone",          v: window.__LANG__==="it" ? "Francia metropolitana, Corsica, UE su richiesta" : "France métropolitaine, Corse, UE sur demande" },
          { k: window.__LANG__==="it"?"Tempi":"Délais",       v: window.__LANG__==="it" ? "Spedito entro 24 ore lavorative · consegna 48-72 ore" : "Expédié sous 24 h ouvrées · livraison 48-72 h" },
          { k: window.__LANG__==="it"?"Costo":"Frais",        v: window.__LANG__==="it" ? "Gratuita oltre 50 € · 5,90 € sotto questa soglia" : "Offerte dès 50 € · 5,90 € en dessous" },
          { k: window.__LANG__==="it"?"Tracciamento":"Suivi", v: window.__LANG__==="it" ? "Numero di tracciamento via email all'invio" : "Numéro de suivi envoyé par email à l'expédition" },
        ]}/>
        <p style={{fontSize:13,color:"var(--muted)",marginTop:18}}>
          {window.__LANG__==="it"
            ? <>Per spedizioni B2B (palette, ordini ricorrenti), scrivere a <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>.</>
            : <>Pour les expéditions B2B (palette, commandes récurrentes), contactez <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>.</>}
        </p>
      </>
    ),
  },

  retours: {
    title:   { fr: "Retours & remboursements", it: "Resi e rimborsi" },
    eyebrow: { fr: "Politique de retour 15 jours", it: "Politica di reso 15 giorni" },
    render: () => (
      <>
        <DescList items={[
          { k: window.__LANG__==="it"?"Termine":"Délai",
            v: window.__LANG__==="it" ? "15 giorni dalla ricezione" : "15 jours après réception" },
          { k: window.__LANG__==="it"?"Condizioni":"Conditions",
            v: window.__LANG__==="it" ? "Articolo non aperto, imballaggio originale, prova d'acquisto" : "Article non ouvert, emballage d'origine, preuve d'achat" },
          { k: window.__LANG__==="it"?"Esclusi":"Exclus",
            v: window.__LANG__==="it" ? "Alimentari deperibili, prodotti personalizzati, articoli in promo, carte regalo" : "Périssables (alimentaires), produits personnalisés, articles en promo, cartes-cadeaux" },
          { k: "UE", v: window.__LANG__==="it" ? "14 giorni di diritto di recesso senza giustificazione" : "14 jours de rétractation sans justification" },
          { k: window.__LANG__==="it"?"Rimborso":"Remboursement",
            v: window.__LANG__==="it" ? "Entro 10 giorni lavorativi dopo ispezione" : "Sous 10 jours ouvrables après inspection" },
        ]}/>
        <p>
          {window.__LANG__==="it"
            ? <>Per avviare un reso, scrivere a <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>. L'etichetta di spedizione viene fornita dopo accettazione. Indirizzo di reso : {COMPANY.address}.</>
            : <>Pour ouvrir un retour, écrivez à <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>. L'étiquette d'expédition est fournie après acceptation. Adresse de retour : {COMPANY.address}.</>}
        </p>
      </>
    ),
  },

  faq: {
    title:   { fr: "Foire aux questions", it: "Domande frequenti" },
    eyebrow: { fr: "FAQ", it: "FAQ" },
    render: () => {
      const FAQS = window.__LANG__==="it" ? [
        { q: "Quali miscele Moreno scegliere?",
          a: <><b>Top Espresso</b> per l'intensità e la persistenza, <b>Gran Miscela</b> per un profilo più rotondo e cacao, <b>Aroma Top</b> per le capsule e le cialde. Tutte tostate lentamente a Napoli.</> },
        { q: "Come conservare il caffè dopo l'apertura?",
          a: "Trasferire in un contenitore ermetico, al riparo dalla luce, in un luogo asciutto. Non in frigorifero (umidità). Consumare entro 4 settimane per preservare l'aroma." },
        { q: "Le capsule sono riciclabili?",
          a: "Le nostre capsule alluminio Nespresso® sono riciclabili nei circuiti dedicati. Le cialde ESE 44 mm sono compostabili al 100 % (carta + caffè)." },
        { q: "Quale macinatura per la mia Moka?",
          a: "Macinatura media-fine. Tutto il nostro macinato 250 g è già pronto per Moka. Per il caffè in grani, macinare al momento o chiedere al rivenditore." },
        { q: "Spedite all'estero?",
          a: <>Sì, in tutta l'UE su richiesta. Scrivere a <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a> con paese e quantità per un preventivo.</> },
        { q: "Vendita Ho.Re.Ca. / vending?",
          a: <>Sì, condizioni dedicate per bar, ristoranti, uffici e distributori automatici. Contattateci a <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>.</> },
      ] : [
        { q: "Quel mélange Moreno choisir ?",
          a: <><b>Top Espresso</b> pour l'intensité et la persistance, <b>Gran Miscela</b> pour un profil plus rond et cacaoté, <b>Aroma Top</b> pour les capsules et les dosettes. Tous torréfiés lentement à Naples.</> },
        { q: "Comment conserver le café après ouverture ?",
          a: "Transférer dans un contenant hermétique, à l'abri de la lumière, dans un endroit sec. Pas au réfrigérateur (humidité). Consommer dans les 4 semaines pour préserver l'arôme." },
        { q: "Les capsules sont-elles recyclables ?",
          a: "Les capsules aluminium Nespresso® sont recyclables via les circuits dédiés. Les dosettes ESE 44 mm sont 100 % compostables (papier + café)." },
        { q: "Quelle mouture pour ma Moka ?",
          a: "Mouture moyenne-fine. Tout notre moulu 250 g est déjà prêt pour Moka. Pour le café en grain, moudre au moment ou demander au revendeur." },
        { q: "Livrez-vous à l'étranger ?",
          a: <>Oui, dans toute l'UE sur demande. Écrivez à <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a> avec pays et quantité pour un devis.</> },
        { q: "Vente Ho.Re.Ca. / vending ?",
          a: <>Oui, conditions dédiées pour bars, restaurants, bureaux et distributeurs. Contactez-nous à <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)"}}>{COMPANY.email}</a>.</> },
      ];
      return <div style={{maxWidth:760}}>{FAQS.map((f,i)=><FAQItem key={i} q={f.q} a={f.a}/>)}</div>;
    },
  },

  "mentions-legales": {
    title:   { fr: "Mentions légales", it: "Note legali" },
    eyebrow: { fr: "Informations légales", it: "Informazioni legali" },
    render: () => (
      <>
        <DescList items={[
          { k: window.__LANG__==="it"?"Ragione sociale":"Raison sociale", v: COMPANY.name },
          { k: window.__LANG__==="it"?"Sede legale":"Siège social",       v: COMPANY.address },
          { k: "SIRET",  v: COMPANY.siret },
          { k: "TVA",    v: COMPANY.tva },
          { k: window.__LANG__==="it"?"Anno di fondazione":"Année de création", v: COMPANY.founded },
          { k: "Email",  v: <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)",fontWeight:600}}>{COMPANY.email}</a> },
        ]}/>
        <h2 style={{fontSize:18,marginTop:32,fontFamily:"var(--font-display)",letterSpacing:".01em"}}>
          {window.__LANG__==="it"?"Hosting / Editore":"Hébergement / Éditeur"}
        </h2>
        <p style={{fontSize:14.5,lineHeight:1.6}}>
          {window.__LANG__==="it"
            ? <>Sito ospitato da Vercel Inc., 340 S Lemon Ave #4133, Walnut, CA 91789, Stati Uniti. Account clienti e catalogo su Supabase (Supabase Inc.). Pagamenti gestiti da Stripe Payments Europe Ltd., 1 Grand Canal Street Lower, Dublino, Irlanda. Direttore della pubblicazione: {COMPANY.name}.</>
            : <>Site hébergé par Vercel Inc., 340 S Lemon Ave #4133, Walnut, CA 91789, États-Unis. Comptes clients et catalogue chez Supabase (Supabase Inc.). Paiements opérés par Stripe Payments Europe Ltd., 1 Grand Canal Street Lower, Dublin, Irlande. Directeur de la publication : {COMPANY.name}.</>}
        </p>
      </>
    ),
  },

  cgv: {
    title:   { fr: "Conditions générales de vente", it: "Condizioni generali di vendita" },
    eyebrow: { fr: "CGV", it: "CGV" },
    render: () => <CgvContent/>,
  },

  confidentialite: {
    title:   { fr: "Politique de confidentialité", it: "Privacy policy" },
    eyebrow: { fr: "Confidentialité", it: "Riservatezza" },
    render: () => <PrivacyContent/>,
  },

  pro: {
    title:   { fr: "Côté pro", it: "Lato pro" },
    eyebrow: { fr: "B2B · Ho.Re.Ca. · Vending", it: "B2B · Ho.Re.Ca. · Vending" },
    render: () => <ProPageContent/>,
  },

  "commande-ok": {
    title:   { fr: "Merci pour votre commande", it: "Grazie per il tuo ordine" },
    eyebrow: { fr: "Paiement reçu",             it: "Pagamento ricevuto" },
    render: () => {
      const isIt = window.__LANG__ === "it";
      const sessionId = new URLSearchParams(window.location.hash.split("?")[1] || "").get("session_id");
      return (
        <div>
          <p style={{fontSize:16,lineHeight:1.6}}>
            {isIt
              ? <>Il tuo pagamento è stato ricevuto. Riceverai una conferma per email entro qualche minuto.</>
              : <>Votre paiement a bien été reçu. Vous recevrez une confirmation par email d'ici quelques minutes.</>}
          </p>
          {sessionId && (
            <p style={{fontSize:12,color:"var(--muted)",marginTop:18,fontFamily:"ui-monospace,Menlo,monospace"}}>
              Stripe session : {sessionId.slice(0,18)}…
            </p>
          )}
          <p style={{marginTop:24}}>
            <a href={`#/${isIt?"it":"fr"}/account`} className="btn btn-primary">
              {isIt ? "Vedi i miei ordini" : "Voir mes commandes"}
            </a>
          </p>
        </div>
      );
    },
  },
};

// Page /page/pro · formulaire de contact B2B (inspiré de caffemoreno.vercel.app/pro)
// Les soumissions sont enregistrées dans la table public.pro_requests (Supabase)
// et visibles dans l'admin.
function ProPageContent(){
  const isIt = window.__LANG__ === "it";
  const [form, setForm] = _useState({
    full_name:"", company:"", email:"", phone:"",
    volume:"", needs_machine:false, message:"",
  });
  const [submitting, setSubmitting] = _useState(false);
  const [done, setDone] = _useState(false);
  const [err, setErr]   = _useState(null);

  const set = (k, v) => setForm(prev => ({ ...prev, [k]: v }));

  const submit = async (e) => {
    e.preventDefault(); setErr(null); setSubmitting(true);
    if (!window.sb) {
      setErr(isIt ? "Servizio temporaneamente non disponibile." : "Service temporairement indisponible.");
      setSubmitting(false);
      return;
    }
    const payload = {
      full_name: form.full_name.trim(),
      company:   form.company.trim(),
      email:     form.email.trim(),
      phone:     form.phone.trim(),
      volume:    form.volume || null,
      needs_machine: !!form.needs_machine,
      message:   form.message.trim() || null,
      lang:      window.__LANG__ || "fr",
    };
    const { error } = await window.sb.from("pro_requests").insert(payload);
    setSubmitting(false);
    if (error) { setErr(error.message); return; }
    setDone(true);
  };

  if (done) {
    return (
      <div style={{padding:"32px 24px",background:"var(--paper-2)",borderRadius:8,borderLeft:"3px solid #caa451"}}>
        <div className="display" style={{fontSize:"clamp(28px,3vw,40px)",color:"#caa451",margin:0}}>
          {isIt ? "Grazie ✓" : "Merci ✓"}
        </div>
        <p style={{fontSize:15,lineHeight:1.6,marginTop:10}}>
          {isIt
            ? <>La tua richiesta è stata ricevuta. Un commerciale ti risponderà entro 24 ore lavorative all'indirizzo <b>{form.email}</b>.</>
            : <>Votre demande est reçue. Un commercial vous répondra sous 24 h ouvrées à l'adresse <b>{form.email}</b>.</>}
        </p>
      </div>
    );
  }

  const inp = {
    width:"100%",padding:"12px 14px",fontSize:14,fontFamily:"inherit",
    background:"var(--paper-2)",color:"var(--ink)",
    border:"1px solid var(--hairline-strong)",borderRadius:6,outline:"none",
    boxSizing:"border-box",
  };

  return (
    <form onSubmit={submit}>
      <p className="serif" style={{fontSize:"clamp(18px,1.6vw,22px)",lineHeight:1.5,color:"var(--ink)",marginTop:0,marginBottom:24}}>
        {isIt
          ? <>Ristoranti, hotel, uffici o caffè. Vi accompagniamo con offerte su misura, dal caffè in grani alla messa a disposizione di macchine professionali.</>
          : <>Restaurants, hôtels, bureaux ou cafés. Nous vous accompagnons avec des offres sur-mesure, du café en grain à la mise à disposition de machines professionnelles.</>}
      </p>

      <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14}} className="pro-form-2col">
        <label>
          <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
            {isIt ? "Nome e cognome *" : "Nom & prénom *"}
          </span>
          <input type="text" required value={form.full_name} onChange={(e)=>set("full_name",e.target.value)} autoComplete="name" style={inp}/>
        </label>
        <label>
          <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
            {isIt ? "Azienda *" : "Établissement *"}
          </span>
          <input type="text" required value={form.company} onChange={(e)=>set("company",e.target.value)} autoComplete="organization" style={inp}/>
        </label>
        <label>
          <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
            Email *
          </span>
          <input type="email" required value={form.email} onChange={(e)=>set("email",e.target.value)} autoComplete="email" style={inp}/>
        </label>
        <label>
          <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
            {isIt ? "Telefono *" : "Téléphone *"}
          </span>
          <input type="tel" required value={form.phone} onChange={(e)=>set("phone",e.target.value)} autoComplete="tel" style={inp}/>
        </label>
      </div>

      <label style={{display:"block",marginTop:14}}>
        <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
          {isIt ? "Volume stimato (kg / mese) *" : "Volume estimé (kg / mois) *"}
        </span>
        <select required value={form.volume} onChange={(e)=>set("volume",e.target.value)} style={{...inp,cursor:"pointer"}}>
          <option value="">{isIt ? "Seleziona…" : "Sélectionnez…"}</option>
          <option value="<10">&lt; 10 kg</option>
          <option value="10-30">10 · 30 kg</option>
          <option value="30-50">30 · 50 kg</option>
          <option value=">50">&gt; 50 kg</option>
        </select>
      </label>

      <label style={{display:"flex",alignItems:"center",gap:10,marginTop:18,fontSize:14,cursor:"pointer",padding:"12px 0"}}>
        <input type="checkbox" checked={form.needs_machine} onChange={(e)=>set("needs_machine",e.target.checked)} style={{width:18,height:18,accentColor:"#caa451"}}/>
        <span>
          {isIt
            ? "Desidero essere equipaggiato con una macchina professionale"
            : "Je souhaite être équipé d'une machine professionnelle"}
        </span>
      </label>

      <label style={{display:"block",marginTop:8}}>
        <span style={{display:"block",fontSize:11.5,letterSpacing:".12em",textTransform:"uppercase",fontWeight:600,color:"var(--muted)",marginBottom:6}}>
          {isIt ? "Messaggio (facoltativo)" : "Message (optionnel)"}
        </span>
        <textarea rows="4" value={form.message} onChange={(e)=>set("message",e.target.value)} style={{...inp,resize:"vertical",minHeight:100}}/>
      </label>

      {err && <div style={{marginTop:14,padding:"10px 12px",background:"rgba(220,40,50,.12)",border:"1px solid var(--rosso)",borderRadius:6,color:"var(--rosso)",fontSize:13}}>{err}</div>}

      <button type="submit" disabled={submitting} style={{
        marginTop:24,
        display:"inline-flex",alignItems:"center",gap:10,
        background:"#caa451",color:"#0e0d0c",
        padding:"16px 28px",borderRadius:99,fontSize:14,fontWeight:700,letterSpacing:".04em",
        border:0,cursor:"pointer",opacity:submitting?.6:1,
      }}>
        {submitting
          ? (isIt ? "Invio in corso…" : "Envoi…")
          : (isIt ? "Invia la mia richiesta" : "Envoyer ma demande")} <IconArrow size={18}/>
      </button>

      <p style={{fontSize:12,color:"var(--muted)",marginTop:18}}>
        {isIt
          ? <>Risposta sotto 24 ore lavorative. I tuoi dati sono trattati secondo la nostra <a onClick={()=>{/* navigate to privacy */}} style={{color:"var(--rosso)",cursor:"pointer"}}>politica di confidentialité</a>.</>
          : <>Réponse sous 24 h ouvrées. Vos données sont traitées selon notre politique de confidentialité.</>}
      </p>

      <style>{`@media(max-width:560px){.pro-form-2col{grid-template-columns:1fr !important}}`}</style>
    </form>
  );
}

// ─── Textes légaux ──────────────────────────────────────────────────────────
function LegalH2({ children }){
  return <h2 style={{fontSize:18,fontFamily:"var(--font-display)",letterSpacing:".01em",margin:"28px 0 10px",color:"var(--ink)"}}>{children}</h2>;
}
function LegalP({ children }){
  return <p style={{fontSize:14.5,lineHeight:1.65,margin:"0 0 12px",color:"var(--ink)",opacity:.9}}>{children}</p>;
}
function LegalUL({ children }){
  return <ul style={{fontSize:14.5,lineHeight:1.7,paddingLeft:18,margin:"4px 0 16px",color:"var(--ink)",opacity:.9}}>{children}</ul>;
}

function CgvContent(){
  return (
    <>
      <LegalH2>Article 1 · Objet</LegalH2>
      <LegalP>{`Les présentes conditions générales régissent les ventes de produits proposés sur le site CAFFE ITALIA.`}</LegalP>
      <LegalP>{`Toute commande implique l'acceptation pleine et entière des présentes conditions.`}</LegalP>

      <LegalH2>Article 2 · Produits</LegalH2>
      <LegalP>{`Les produits proposés (cafés, accessoires, etc.) sont décrits et présentés avec la plus grande exactitude possible.`}</LegalP>
      <LegalP>{`Les photos n'ont pas de valeur contractuelle.`}</LegalP>
      <LegalP>{`Les produits sont proposés dans la limite des stocks disponibles.`}</LegalP>

      <LegalH2>Article 3 · Prix</LegalH2>
      <LegalP>{`Les prix affichés sont en euros (€) toutes taxes comprises (TTC).`}</LegalP>
      <LegalP>{`Les frais de livraison s'ajoutent selon le mode choisi (voir « Politique de livraison »).`}</LegalP>
      <LegalP><b>{`Livraison gratuite en point relais à partir de 49 € d'achat.`}</b></LegalP>

      <LegalH2>Article 4 · Commande</LegalH2>
      <LegalP>{`Le client passe commande en ligne sur le site caffeitalia.`}</LegalP>
      <LegalP>{`Une confirmation de commande est envoyée par e-mail une fois le paiement validé.`}</LegalP>
      <LegalP>{`CAFFE ITALIA se réserve le droit de refuser toute commande en cas de litige antérieur ou de suspicion de fraude.`}</LegalP>

      <LegalH2>Article 5 · Paiement</LegalH2>
      <LegalP>{`Les paiements sont sécurisés via Stripe (carte bancaire, Apple Pay, Google Pay) ou tout autre prestataire agréé.`}</LegalP>
      <LegalP>{`Les données bancaires ne sont jamais conservées par CAFFE ITALIA.`}</LegalP>

      <LegalH2>Article 6 · Livraison</LegalH2>
      <LegalUL>
        <li>{`Livraison gratuite en point relais dès 49 € d'achat`}</li>
        <li>{`En dessous de ce montant, les frais dépendent du transporteur choisi`}</li>
        <li>{`Délai moyen : 2 à 5 jours ouvrés`}</li>
        <li>{`Livraison en France métropolitaine (autres zones sur demande)`}</li>
      </LegalUL>
      <LegalP>{`En cas de retard, CAFFE ITALIA ne peut être tenue responsable d'événements extérieurs (retards du transporteur, force majeure…).`}</LegalP>

      <LegalH2>Article 7 · Droit de rétractation</LegalH2>
      <LegalP>{`Conformément à la loi, le client dispose d'un délai de 14 jours à compter de la réception pour exercer son droit de rétractation.`}</LegalP>
      <LegalP>{`Les produits doivent être renvoyés non ouverts et dans leur emballage d'origine.`}</LegalP>
      <LegalP>{`Les frais de retour sont à la charge du client, sauf erreur ou défaut du vendeur.`}</LegalP>

      <LegalH2>Article 8 · Remboursement</LegalH2>
      <LegalP>{`Une fois le produit retourné et vérifié, le remboursement est effectué dans un délai de 7 à 14 jours ouvrés sur le moyen de paiement initial.`}</LegalP>
      <LegalP>{`Les produits ouverts, consommés ou personnalisés ne peuvent être remboursés.`}</LegalP>

      <LegalH2>Article 9 · Garanties</LegalH2>
      <LegalP>{`Les produits bénéficient de la garantie légale de conformité (articles L217-4 et suivants du Code de la consommation) et de la garantie contre les vices cachés (articles 1641 et suivants du Code civil).`}</LegalP>

      <LegalH2>Article 10 · Responsabilité</LegalH2>
      <LegalP>{`Le vendeur ne saurait être tenu responsable de tout dommage indirect ou d'un usage inapproprié du produit.`}</LegalP>
      <LegalP>{`En cas de litige, une solution amiable sera recherchée avant toute action judiciaire.`}</LegalP>

      <LegalH2>Article 11 · Droit applicable et juridiction</LegalH2>
      <LegalP>{`Les présentes conditions sont soumises au droit français.`}</LegalP>
      <LegalP>{`Tout litige sera porté devant les tribunaux compétents du siège social de CAFFE ITALIA.`}</LegalP>
    </>
  );
}

function PrivacyContent(){
  return (
    <>
      <p style={{fontSize:13,color:"var(--muted)",margin:"0 0 22px"}}>{`Dernière mise à jour : 10 avril 2026`}</p>

      <LegalP>{`CAFFE ITALIA exploite cette boutique et ce site web, y compris toutes les informations, le contenu, les fonctionnalités, les outils, les produits et les services connexes afin de vous fournir, en tant que client(e), une expérience d'achat personnalisée (ci-après les « Services »). CAFFE ITALIA exploite cette boutique avec l'aide de prestataires techniques (hébergement, base de données, paiement) qui nous permettent de vous fournir les Services. La présente Politique de confidentialité décrit la façon dont nous collectons, utilisons et divulguons vos informations personnelles lorsque vous accédez aux Services, les utilisez, effectuez un achat ou toute autre transaction, ou lorsque vous communiquez avec nous par tout autre moyen. En cas de contradiction entre nos Conditions de service et la présente Politique de confidentialité, la présente Politique de confidentialité prévaut en ce qui concerne la collecte, le traitement et la divulgation de vos informations personnelles.`}</LegalP>
      <LegalP>{`Veuillez lire attentivement la présente Politique de confidentialité. En accédant à nos Services et en les utilisant, vous reconnaissez avoir lu la présente Politique de confidentialité et comprendre les modalités de collecte, d'utilisation et de divulgation de vos informations qui sont décrites dans la présente Politique de confidentialité.`}</LegalP>

      <LegalH2>Les informations personnelles que nous collectons ou traitons</LegalH2>
      <LegalP>{`Lorsque nous utilisons le terme « informations personnelles », nous faisons référence aux informations qui permettent de vous identifier ou qui peuvent raisonnablement être reliées à vous ou à une autre personne. Les informations personnelles n'incluent pas les informations collectées anonymement ou rendues non identifiables, de sorte qu'elles ne permettent pas de vous identifier ni d'être raisonnablement reliées à vous. Nous pouvons collecter ou traiter les catégories suivantes d'informations personnelles, y compris les déductions tirées de ces informations personnelles, en fonction de votre manière d'interagir avec les Services, de votre lieu de résidence, et dans la mesure permise ou exigée par la législation applicable :`}</LegalP>
      <LegalUL>
        <li><b>Coordonnées</b>{` y compris votre nom, adresse, adresse de facturation, adresse de livraison, numéro de téléphone et adresse e-mail.`}</li>
        <li><b>Informations financières</b>{` y compris les numéros de carte de crédit, de carte de débit et de compte bancaire, les informations relatives aux cartes de paiement, les informations de compte bancaire, les détails de transaction, le moyen de paiement, la confirmation de paiement et les autres détails de paiement.`}</li>
        <li><b>Informations du compte</b>{` y compris votre nom d'utilisateur, votre mot de passe, vos questions de sécurité, vos préférences et vos paramètres.`}</li>
        <li><b>Informations de transaction</b>{` y compris les articles que vous consultez, placez dans votre panier, ajoutez à votre liste d'envies, achetez, retournez, échangez ou annulez, ainsi que vos transactions passées.`}</li>
        <li><b>Vos communications avec nous</b>{` y compris les informations que vous incluez dans vos communications avec nous, par exemple lorsque vous envoyez une enquête au service à la clientèle.`}</li>
        <li><b>Informations sur l'appareil</b>{` y compris les informations concernant votre appareil, votre navigateur ou votre connexion réseau, votre adresse IP et d'autres identifiants uniques.`}</li>
        <li><b>Informations d'utilisation</b>{` y compris les informations concernant votre interaction avec les Services, notamment comment et quand vous accédez aux Services ou interagissez avec eux.`}</li>
      </LegalUL>

      <LegalH2>Sources des informations personnelles</LegalH2>
      <LegalP>{`Nous pouvons collecter des informations personnelles à partir des sources suivantes :`}</LegalP>
      <LegalUL>
        <li><b>Directement auprès de vous</b>{` y compris lorsque vous créez un compte, accédez aux Services ou les utilisez, communiquez avec nous, ou nous fournissez de toute autre manière vos informations personnelles ;`}</li>
        <li><b>Automatiquement via les Services</b>{` y compris depuis votre appareil lorsque vous utilisez nos produits ou services ou accédez à nos sites web, et via l'utilisation de cookies et de technologies similaires ;`}</li>
        <li><b>Auprès de nos fournisseurs de services</b>{` y compris lorsque nous faisons appel à eux pour mettre en œuvre certaines technologies et lorsqu'ils collectent ou traitent vos informations personnelles en notre nom ;`}</li>
        <li>{`Auprès de nos partenaires ou d'autres tiers.`}</li>
      </LegalUL>

      <LegalH2>Comment nous utilisons vos informations personnelles</LegalH2>
      <LegalP>{`En fonction de la façon dont vous interagissez avec nous ou des Services que vous utilisez, nous pouvons utiliser vos informations personnelles aux fins suivantes :`}</LegalP>
      <LegalUL>
        <li><b>Fournir, adapter et améliorer les Services.</b>{` Nous utilisons vos informations personnelles pour vous fournir les Services, notamment afin d'exécuter notre contrat avec vous, de traiter vos paiements, de traiter vos commandes, de mémoriser vos préférences et les articles qui vous intéressent, de vous envoyer des notifications liées à votre compte, de traiter les achats, retours, échanges ou autres transactions, de créer, maintenir et gérer de toute autre façon votre compte, d'organiser les expéditions, de faciliter les éventuels retours et échanges, de vous permettre de publier des avis, et de créer une expérience d'achat personnalisée, par exemple en vous recommandant des produits en lien avec vos achats. Ceci peut inclure l'utilisation de vos informations personnelles afin d'adapter et d'améliorer les Services de manière plus pertinente.`}</li>
        <li><b>Marketing et publicité.</b>{` Nous utilisons vos informations personnelles à des fins de marketing et de promotion, par exemple pour vous envoyer des communications marketing, publicitaires et promotionnelles par e-mail, SMS ou courrier postal, et pour vous montrer des publicités en ligne concernant des produits ou des services sur les Services ou sur d'autres sites web, notamment en fonction des articles que vous avez précédemment achetés ou ajoutés à votre panier, ainsi que de vos autres activités sur les Services.`}</li>
        <li><b>Sécurité et prévention de la fraude.</b>{` Nous utilisons vos informations personnelles pour authentifier votre compte, offrir une expérience de paiement et d'achat sécurisée, détecter, enquêter ou intervenir en cas d'activité frauduleuse, illégale, dangereuse ou malveillante, protéger la sécurité publique et sécuriser nos services. Si vous choisissez d'utiliser les Services et de créer un compte, vous êtes responsable de la confidentialité des identifiants de votre compte. Nous vous recommandons vivement de ne pas partager votre nom d'utilisateur, votre mot de passe ou tout autre identifiant d'accès avec qui que ce soit.`}</li>
        <li><b>Communiquer avec vous.</b>{` Nous utilisons vos informations personnelles pour vous fournir un service à la clientèle, répondre à vos demandes, vous offrir des services efficaces et entretenir notre relation commerciale avec vous.`}</li>
        <li><b>Raisons légales.</b>{` Nous utilisons vos informations personnelles afin de nous conformer à la législation en vigueur ou de répondre à des procédures judiciaires valides, notamment aux demandes émanant des forces de l'ordre ou d'organismes gouvernementaux, pour enquêter ou participer à des procédures civiles de communication de preuves, à des litiges potentiels ou en cours, ou à d'autres procédures contentieuses, ainsi que pour faire respecter nos conditions ou politiques, ou enquêter sur d'éventuelles violations de celles-ci.`}</li>
      </LegalUL>

      <LegalH2>Comment nous divulguons les informations personnelles</LegalH2>
      <LegalP>{`Dans certaines circonstances, nous pouvons divulguer vos informations personnelles à des tiers pour des raisons légitimes, conformément à la présente Politique de confidentialité. Ces circonstances peuvent inclure :`}</LegalP>
      <LegalUL>
        <li>{`Avec nos prestataires et autres tiers qui fournissent des services en notre nom (par exemple hébergement du site, base de données, traitement des paiements, analyses de données, service à la clientèle, stockage cloud, préparation et expédition des commandes).`}</li>
        <li>{`Avec des partenaires commerciaux et marketing afin de vous fournir des services de marketing et de vous adresser des publicités. Nos partenaires commerciaux et marketing utiliseront vos informations conformément à leurs propres avis de confidentialité. En fonction de votre lieu de résidence, vous pouvez avoir le droit de nous demander de ne pas partager d'informations vous concernant dans le but de vous montrer des publicités et des contenus marketing ciblés, basés sur votre activité en ligne auprès de différents marchands et sites web.`}</li>
        <li>{`Lorsque vous nous donnez instruction, nous adressez une demande ou consentez par tout autre moyen à la divulgation de certaines informations à des tiers, par exemple pour vous expédier des produits ou via votre utilisation de widgets de réseaux sociaux ou d'intégrations de connexion.`}</li>
        <li>{`Avec nos affiliés ou plus généralement au sein de notre groupe de sociétés.`}</li>
        <li>{`Dans le cadre d'une transaction commerciale telle qu'une fusion ou un dépôt de bilan, pour nous conformer à toute obligation légale applicable (notamment en réponse à des citations à comparaître, mandats de perquisition ou demandes similaires), pour faire respecter les conditions de service ou politiques applicables, ainsi que pour protéger ou défendre les Services, nos droits et les droits de nos utilisateurs ou de tiers.`}</li>
      </LegalUL>

      <LegalH2>Nos prestataires techniques</LegalH2>
      <LegalP>{`Les Services s'appuient sur trois prestataires. Vercel Inc. héberge le site et traite les données techniques de connexion. Supabase Inc. héberge la base de données : compte client, adresse de livraison, historique de commandes et avis produits. Stripe Payments Europe Ltd. traite les paiements — vos données de carte bancaire ne transitent jamais par nos serveurs et ne sont jamais stockées par nous. Ces prestataires peuvent être situés dans un autre pays que celui où vous résidez ; les transferts hors Union européenne sont encadrés par les clauses contractuelles types de la Commission européenne. Chacun agit sur nos instructions et pour les seules finalités décrites dans la présente politique.`}</LegalP>

      <LegalH2>Sites web et liens de tiers</LegalH2>
      <LegalP>{`Les Services peuvent fournir des liens à des sites web ou autres plateformes en ligne exploitées par des tiers. Si vous suivez des liens menant vers des sites qui ne sont pas affiliés à nous ou que nous ne contrôlons pas, nous vous recommandons de consulter leurs politiques de confidentialité et de sécurité ainsi que leurs autres conditions générales d'utilisation. Nous ne garantissons pas et ne sommes pas responsables de la confidentialité ou de la sécurité de ces sites, y compris de l'exactitude, de l'exhaustivité ou de la fiabilité des informations qui se trouvent sur ces sites. Les informations que vous fournissez dans des espaces publics ou semi-publics, y compris les informations que vous partagez sur des plateformes de réseaux sociaux tierces, peuvent également être visibles par d'autres utilisateurs des Services et/ou par des utilisateurs de ces plateformes tierces sans restriction quant à leur utilisation par nous ou par un tiers. Le fait que nous incluions ces liens n'implique pas en soi une quelconque approbation du contenu de ces plateformes, ni de leurs propriétaires ou exploitants, sauf indication contraire figurant sur les Services.`}</LegalP>

      <LegalH2>Données des enfants</LegalH2>
      <LegalP>{`Les Services ne sont pas destinés à être utilisés par des enfants et nous ne collectons sciemment aucune information personnelle concernant des enfants n'ayant pas atteint l'âge de la majorité dans votre juridiction. Si vous êtes le parent ou le tuteur d'un enfant qui nous a fourni ses informations personnelles, vous pouvez nous contacter à l'aide des coordonnées indiquées ci-dessous pour demander leur suppression. À la date d'effet de la présente Politique de confidentialité, nous n'avons pas connaissance du fait que nous « partageons » ou « vendons » (au sens des définitions de ces termes prévues par la législation applicable) des informations personnelles concernant des personnes de moins de 16 ans.`}</LegalP>

      <LegalH2>Sécurité et conservation de vos informations</LegalH2>
      <LegalP>{`Veuillez noter qu'aucune mesure de sécurité n'est parfaite ou infaillible et que nous ne pouvons garantir une « sécurité parfaite ». De plus, toute information que vous nous envoyez peut ne pas être sécurisée lors de sa transmission. Nous vous recommandons de ne pas utiliser de canaux non sécurisés pour nous communiquer des informations sensibles ou confidentielles.`}</LegalP>
      <LegalP>{`La durée de conservation de vos informations personnelles dépend de différents facteurs, tels que la nécessité de conserver ces informations pour gérer votre compte, vous fournir les Services, respecter nos obligations légales, résoudre les litiges ou faire appliquer tout autre contrat ou politique applicable.`}</LegalP>

      <LegalH2>Vos droits et vos choix</LegalH2>
      <LegalP>{`En fonction de votre lieu de résidence, vous pouvez disposer de certains ou de l'ensemble des droits indiqués ci-dessous concernant vos informations personnelles. Cependant, ces droits ne sont pas absolus, peuvent s'appliquer uniquement dans certaines circonstances et, dans certains cas, nous pouvons refuser votre demande dans les limites autorisées par la loi.`}</LegalP>
      <LegalUL>
        <li><b>Droit d'accès / droit à l'information.</b>{` Vous pouvez avoir le droit de demander l'accès aux informations personnelles que nous détenons à votre sujet.`}</li>
        <li><b>Droit à l'effacement.</b>{` Vous pouvez avoir le droit de demander la suppression des informations personnelles que nous détenons à votre sujet.`}</li>
        <li><b>Droit de rectification.</b>{` Vous pouvez avoir le droit de demander la rectification des informations personnelles inexactes que nous détenons à votre sujet.`}</li>
        <li><b>Droit à la portabilité.</b>{` Vous pouvez avoir le droit de recevoir une copie des informations personnelles que nous détenons à votre sujet et de demander leur transfert à un tiers, dans certaines circonstances et avec certaines exceptions.`}</li>
        <li><b>Droit de s'opposer à la vente ou au partage à des fins de publicité ciblée.</b>{` En fonction de votre lieu de résidence, vous pouvez avoir le droit de vous opposer à la « vente » ou au « partage » de vos informations personnelles ou de vous opposer au traitement de vos informations personnelles à des fins considérées comme de la « publicité ciblée », telles que définies par les lois applicables relatives à la confidentialité. Veuillez noter que si vous accédez à notre site web avec le signal de préférence de refus Global Privacy Control activé, en fonction de votre lieu de résidence, nous considérerons automatiquement ceci comme une demande de refus pour l'appareil et le navigateur que vous utilisez. Pour en savoir plus, vous pouvez consulter `}<ExtLink href="https://globalprivacycontrol.org/">globalprivacycontrol.org</ExtLink>{`. À l'exception de Global Privacy Control, nous ne reconnaissons pas les autres signaux Interdire le suivi (« Do Not Track »).`}</li>
        <li><b>Gestion des préférences en matière de communication.</b>{` Nous pouvons vous envoyer des e-mails promotionnels. Vous pouvez à tout moment choisir de ne plus en recevoir en utilisant l'option de désabonnement incluse dans nos e-mails. Si vous vous désabonnez, nous pouvons toujours vous envoyer des e-mails non promotionnels, par exemple concernant votre compte ou des commandes que vous avez effectuées.`}</li>
      </LegalUL>
      <LegalP>{`Si vous résidez au Royaume-Uni ou dans l'Espace économique européen, et sous réserve des exceptions et limitations prévues par la législation locale, vous pouvez exercer les droits suivants en complément des droits énumérés ci-dessus :`}</LegalP>
      <LegalUL>
        <li><b>Opposition au traitement et limitation du traitement :</b>{` Vous pouvez avoir le droit de nous demander de cesser ou de restreindre le traitement de vos informations personnelles à certaines fins.`}</li>
        <li><b>Retrait du consentement :</b>{` Lorsque nous dépendons de votre consentement pour traiter vos informations personnelles, vous avez le droit de retirer ce consentement. Si vous retirez votre consentement, la légalité du traitement fondé sur votre consentement avant son retrait ne sera pas affectée.`}</li>
      </LegalUL>
      <LegalP>{`Vous pouvez exercer ces droits aux emplacements prévus à cet effet sur les Services ou en nous contactant aux coordonnées fournies ci-dessous.`}</LegalP>
      <LegalP>{`Nous ne vous pénaliserons pas pour avoir exercé un de ces droits. Nous devrons peut-être vérifier votre identité avant de pouvoir traiter vos demandes, dans les limites prévues ou autorisées par la législation applicable. Conformément à la législation applicable, vous pouvez désigner un mandataire autorisé pour demander à exercer vos droits en votre nom. Avant d'accepter ladite demande de la part d'un agent, nous exigerons que l'agent fournisse une preuve de l'autorisation que vous lui avez donnée pour agir en votre nom, et il se peut que nous vous demandions de vérifier directement votre identité auprès de nous. Nous répondrons à votre demande dans les délais prévus par la législation applicable.`}</LegalP>

      <LegalH2>Plaintes</LegalH2>
      <LegalP>{`Si vous souhaitez déposer une plainte concernant notre traitement de vos informations personnelles, veuillez nous contacter aux coordonnées indiquées ci-dessous. En fonction de votre lieu de résidence, vous pouvez avoir le droit de contester notre décision en nous contactant aux coordonnées indiquées ci-dessous, ou en déposant une plainte auprès de l'autorité de protection des données compétente de votre région.`}</LegalP>

      <LegalH2>Transferts internationaux</LegalH2>
      <LegalP>{`Veuillez noter que nous pouvons transférer, stocker et traiter vos informations personnelles en dehors du pays dans lequel vous résidez.`}</LegalP>
      <LegalP>{`Si nous transférons vos informations personnelles en dehors de l'Espace économique européen ou du Royaume-Uni, nous nous appuierons sur des mécanismes de transfert reconnus, tels que les clauses contractuelles types de la Commission européenne, ou le cas échéant sur tout contrat équivalent émis par l'autorité compétente du Royaume-Uni, sauf si le transfert de données est effectué vers un pays reconnu comme offrant un niveau de protection adéquat.`}</LegalP>

      <LegalH2>Modifications de la présente Politique de confidentialité</LegalH2>
      <LegalP>{`Nous pouvons mettre à jour cette Politique de confidentialité à tout moment, notamment pour refléter des modifications de nos pratiques ou pour d'autres raisons opérationnelles, juridiques ou réglementaires. Nous publierons la Politique de confidentialité révisée sur ce site web, mettrons à jour la date de « Dernière mise à jour » et fournirons un avis, conformément à la législation applicable.`}</LegalP>

      <LegalH2>Contact</LegalH2>
      <LegalP>{`Si vous avez des questions sur nos pratiques de confidentialité ou sur cette Politique de confidentialité, ou si vous souhaitez exercer un des droits dont vous disposez, vous pouvez nous envoyer un e-mail à l'adresse `}
        <a href={`mailto:${COMPANY.email}`} style={{color:"var(--ink)",fontWeight:600}}>{COMPANY.email}</a>{` ou nous contacter à l'adresse 6-8 Place Colette Lepage, Montreuil, 93100, FR. Aux fins de la législation applicable en matière de protection des données, nous sommes le responsable du traitement de vos informations personnelles.`}</LegalP>
    </>
  );
}

function InfoPage({ slug, navigate }){
  const def = PAGES_CONTENT[slug];
  if (!def) {
    return (
      <main className="wrap" style={{padding:"56px 32px 96px",minHeight:"50vh"}}>
        <h1 className="display" style={{fontSize:"clamp(40px,5vw,72px)"}}>404</h1>
        <p>{window.__LANG__==="it"?"Pagina non trovata.":"Page introuvable."}</p>
        <button onClick={()=>navigate({page:"home"})} className="btn btn-primary" style={{marginTop:18}}>
          {window.__LANG__==="it"?"Torna alla home":"Retour à l'accueil"} <IconArrow size={16}/>
        </button>
      </main>
    );
  }
  return (
    <main>
      <div className="wrap" style={{padding:"22px 32px 4px",fontSize:12,color:"var(--muted)",display:"flex",gap:8,alignItems:"center"}}>
        <a onClick={()=>navigate({page:"home"})} style={{cursor:"pointer"}}>{t("cat.crumb_home")}</a>
        <span>/</span>
        <span style={{color:"var(--ink)",fontWeight:600}}>{pick(def.title)}</span>
      </div>
      <section className="wrap" style={{padding:"18px 32px 64px",maxWidth:1080}}>
        <div className="eyebrow" style={{color:"var(--rosso)"}}>{pick(def.eyebrow)}</div>
        <h1 className="display" style={{fontSize:"clamp(40px,5vw,72px)",margin:"14px 0 24px",lineHeight:1.05}}>{pick(def.title)}</h1>
        <div style={{fontSize:15.5,lineHeight:1.6,maxWidth:760}}>
          {def.render()}
        </div>
      </section>
    </main>
  );
}

Object.assign(window, { HomeScreen, CategoryScreen, ProductScreen, StoryScreen, ShopAllScreen, InfoPage, ProductBottle: window.ProductBottle });
