/* Siste's main app */

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

const C = window.SITE_CONTENT;
const IMG = window.SITE_IMAGES;

// ---- Icons (inline SVG) ----
const Icon = {
  Search: () => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="square">
      <circle cx="10.5" cy="10.5" r="6.5" /><line x1="15.5" y1="15.5" x2="20" y2="20" />
    </svg>
  ),
  ArrowRight: ({ size = 18 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="square">
      <line x1="3" y1="12" x2="20" y2="12" /><polyline points="14 6 20 12 14 18" />
    </svg>
  ),
  ArrowLeft: ({ size = 18 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="square">
      <line x1="21" y1="12" x2="4" y2="12" /><polyline points="10 6 4 12 10 18" />
    </svg>
  ),
  Lock: () => (
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1" strokeLinecap="square">
      <rect x="5" y="11" width="14" height="10" /><path d="M8 11V7a4 4 0 0 1 8 0v4" />
    </svg>
  ),
  Plus: () => (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.2"><line x1="12" y1="4" x2="12" y2="20"/><line x1="4" y1="12" x2="20" y2="12"/></svg>
  ),
};

// ---- Reveal hook ----
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("is-in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12 });
    els.forEach(el => {
      // Quello che e' GIA' in vista si mostra subito. Saltando a una sezione dal
      // menu, l'osservatore non scatta finche' non si muove qualcosa: si arrivava
      // sul Catalogo e sotto il titolo restava bianco finche' non muovevi il dito
      // (Stefano 25/08/2026). Stesso difetto che c'era nella collezione.
      const r = el.getBoundingClientRect();
      if (r.top < window.innerHeight && r.bottom > 0) el.classList.add("is-in");
      else io.observe(el);
    });
    return () => io.disconnect();
  });
}

// ---- TopBar ----
function TopBar({ lang, setLang, sections, t }) {
  const [solid, setSolid] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    const onScroll = () => setSolid(window.scrollY > 80);
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);
  const go = (id) => () => {
    setMenuOpen(false);
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: "smooth" });
  };
  return (
    <>
      <header className={`topbar ${solid || menuOpen ? "is-solid" : ""}`} data-screen-label="Top Bar">
        <a href="#" className="logo" onClick={(e) => { e.preventDefault(); setMenuOpen(false); window.scrollTo({ top: 0, behavior: "smooth" }); }}>
          <img src="assets/logo-more.png" alt="More by Siste's" />
        </a>
        <nav className="topbar__nav">
          <a onClick={go("maison")}>{t.nav.house}</a>
          <a onClick={go("campaign")}>{t.nav.collections}</a>
          <a onClick={go("lookbook")}>{t.nav.lookbook}</a>
          <a onClick={go("b2b")}>{t.nav.b2b}</a>
          <a onClick={go("contact")}>{t.nav.contact}</a>
        </nav>
        <div className="topbar__util">
          <div className="lang-toggle">
            <button onClick={() => setLang("it")} className={lang === "it" ? "is-on" : ""}>IT</button>
            <span className="lang-toggle__sep">/</span>
            <button onClick={() => setLang("en")} className={lang === "en" ? "is-on" : ""}>EN</button>
          </div>
          <button
            className={`topbar__burger ${menuOpen ? "is-open" : ""}`}
            onClick={() => setMenuOpen(v => !v)}
            aria-label={menuOpen ? "Close menu" : "Open menu"}
            aria-expanded={menuOpen}
          >
            <span></span>
            <span></span>
          </button>
        </div>
      </header>
      <div className={`mobile-menu ${menuOpen ? "is-open" : ""}`} aria-hidden={!menuOpen}>
        <div className="mobile-menu__inner">
          <nav className="mobile-menu__nav">
            <a onClick={go("maison")}><span>01</span>{t.nav.house}</a>
            <a onClick={go("campaign")}><span>02</span>{t.nav.collections}</a>
            <a onClick={go("lookbook")}><span>03</span>{t.nav.lookbook}</a>
            <a onClick={go("b2b")}><span>04</span>{t.nav.b2b}</a>
            <a onClick={go("contact")}><span>05</span>{t.nav.contact}</a>
          </nav>
          <div className="mobile-menu__foot">
            <div className="mobile-menu__lang">
              <button onClick={() => setLang("it")} className={lang === "it" ? "is-on" : ""}>Italiano</button>
              <button onClick={() => setLang("en")} className={lang === "en" ? "is-on" : ""}>English</button>
            </div>
            <div className="mobile-menu__meta">
              <span>More by Siste's</span>
              <span>Made in Italy · Since 1991</span>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

// ---- Hero ----
function Hero({ t, autoplay }) {
  const [i, setI] = useState(0);
  // In apertura girano solo le foto scelte (heroRotation); IMG.hero resta la campagna intera.
  const slides = (IMG.heroRotation && IMG.heroRotation.length) ? IMG.heroRotation : IMG.hero;
  const videos = IMG.heroVideos || [];
  const total = videos.length > 0 ? videos.length : slides.length;
  const videoRefs = useRef([]);

  useEffect(() => {
    if (!autoplay) return;
    if (videos.length > 0) return;
    const id = setInterval(() => setI(v => (v + 1) % total), 5400);
    return () => clearInterval(id);
  }, [autoplay, total, videos.length]);

  useEffect(() => {
    if (videos.length === 0) return;
    videoRefs.current.forEach((v, idx) => {
      if (!v) return;
      if (idx === i) { try { v.currentTime = 0; v.play().catch(()=>{}); } catch(e){} }
      else { try { v.pause(); } catch(e){} }
    });
  }, [i, videos.length]);

  const slide = slides[i % slides.length];

  return (
    <section className={`hero ${videos.length > 0 ? 'hero--video' : ''}`} id="home" data-screen-label="01 Hero">
      {videos.length > 0 ? (
        videos.map((vsrc, idx) => (
          <div key={idx} className={`hero__layer ${idx === i ? "is-active" : ""}`}>
            <video
              ref={el => videoRefs.current[idx] = el}
              className={`hero__video hero__video--${idx + 1}`}
              src={vsrc}
              muted
              playsInline
              preload={idx === 0 ? "auto" : "metadata"}
              autoPlay={idx === 0}
              onEnded={() => setI((idx + 1) % total)}
            />
          </div>
        ))
      ) : (
        slides.map((s, idx) => (
          <div key={idx} className={`hero__layer ${idx === i ? "is-active" : ""}`}>
            <div className="hero__img" key={idx + "-" + i} style={{ backgroundImage: `url("${s.src}")`, backgroundPosition: s.focus || "center top" }} />
          </div>
        ))
      )}
      <div className="hero__inner">
        <div className="hero__copy">
          <div className="hero__eyebrow">{t.hero.eyebrow}</div>
          <h1 className="hero__title">
            {t.hero.title.map((line, idx) => (
              <span key={idx}><span style={{ animationDelay: `${idx * 180}ms` }}>{line}</span></span>
            ))}
          </h1>
          <p className="hero__sub">{t.hero.sub}</p>
          <div className="hero__ctas">
            <button className="btn btn--filled" onClick={() => { const el = document.getElementById("campaign"); if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: "smooth" }); }}>
              <span className="btn__label">{t.hero.cta}</span>
              <span className="btn__arrow"><Icon.ArrowRight size={14} /></span>
            </button>
            <button className="btn btn--ghost" onClick={() => { const el = document.getElementById("lookbook"); if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: "smooth" }); }}>
              <span className="btn__label">{t.hero.ctaSecondary}</span>
            </button>
          </div>
        </div>
        <div className="hero__foot">
          <div className="hero__dots">
            {slides.map((_, idx) => (
              <button
                key={idx}
                className={`hero__dot ${idx === i ? "is-on" : ""}`}
                onClick={() => setI(idx)}
                aria-label={`Go to slide ${idx + 1}`}
              />
            ))}
          </div>
          <div className="hero__nav">
            <button onClick={() => setI((i - 1 + total) % total)} aria-label="prev"><Icon.ArrowLeft /></button>
            <button onClick={() => setI((i + 1) % total)} aria-label="next"><Icon.ArrowRight /></button>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- Campaign Nicola Maggio (grid editorial AI26) ----
function CampaignNM({ t }) {
  const photos = IMG.campaignNM || [];
  // Le foto di campagna si aprono come sul sito Sistes: click -> lightbox a tutta
  // altezza, frecce per scorrere, Esc per chiudere (Stefano 25/08/2026).
  const [active, setActive] = React.useState(null);
  const [visibile, setVisibile] = React.useState(0);
  const scrollRef = React.useRef(null);
  // Aperta una foto, si scorrono TUTTE in verticale, una sotto l'altra, come su
  // Instagram: si parte da quella toccata (Stefano 25/08/2026). Prima erano frecce
  // avanti/indietro, che sul telefono non e' il gesto naturale.
  React.useEffect(() => {
    if (active === null) return;
    setVisibile(active);
    const box = scrollRef.current;
    if (box) {
      const target = box.querySelector(`[data-idx="${active}"]`);
      if (target) box.scrollTop = target.offsetTop;
    }
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") setActive(null); };
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [active]);
  // Contatore che segue lo scorrimento
  React.useEffect(() => {
    const box = scrollRef.current;
    if (active === null || !box) return;
    const onScroll = () => {
      // Quella "in cima" alla schermata, non quella a meta': le foto sono
      // orizzontali e ne stanno due e mezza per schermo, quindi col punto di
      // mezzo il contatore segnava sempre la foto dopo.
      const y = box.scrollTop;
      let best = 0, dist = Infinity;
      box.querySelectorAll("[data-idx]").forEach((el) => {
        const d = Math.abs(el.offsetTop - y);
        if (d < dist) { dist = d; best = Number(el.dataset.idx); }
      });
      setVisibile(best);
    };
    box.addEventListener("scroll", onScroll, { passive: true });
    return () => box.removeEventListener("scroll", onScroll);
  }, [active]);
  if (!photos.length || !t.campaign) return null;
  return (
    <section className="section campaign-nm" id="campaign" data-screen-label="03 Campaign">
      <div className="section__head reveal">
        <div>
          <div className="eyebrow">{t.campaign.eyebrow}</div>
          <h2 className="section__title">{t.campaign.title}</h2>
        </div>
        <p className="body-lede">{t.campaign.sub}</p>
      </div>
      {/* Niente "reveal" qui: e' il CONTENITORE a portarlo, quindi finche'
          l'animazione non scattava restava invisibile TUTTA la griglia, non le
          singole foto. Saltando qui dal menu si vedeva solo il titolo e sotto
          il bianco (Stefano 25/08/2026, due segnalazioni). Le foto della
          campagna si mostrano e basta: e' la sezione principale del sito, non
          puo' dipendere da un effetto. */}
      {/* Righe "giustificate": le foto di una riga hanno tutte la stessa altezza e
          la riga finisce esatta al bordo. Ogni foto occupa una larghezza
          proporzionale alla propria forma, quindi non si taglia niente e non
          restano buchi. E' il modo di avere l'impaginazione movimentata che
          piace a Stefano e Simone senza i due difetti di prima (25/08/2026). */}
      <div className="campaign-nm__grid">
        {(() => {
          // Il movimento nasce dal CONTRASTO fra righe: una foto sola a tutta
          // larghezza (grande, d'impatto) accanto a righe da tre (piccole).
          // Con righe tutte da 2-3 le foto vengono tutte uguali e non si
          // distingue dall'altra versione (Stefano 25/08/2026).
          // Righe da 1 o da 2, mai da 3: con tre foto affiancate sul telefono
          // diventano francobolli, e per farne stare due sole serviva una
          // larghezza minima che rompeva la giustificazione (le foto tornavano
          // a tagliarsi). Cosi' il contrasto grande/piccolo resta e i conti
          // tornano su tutti gli schermi (Stefano 25/08/2026).
          const perRiga = [1, 2, 2, 1, 2, 2, 2];
          const righe = []; let i = 0, k = 0;
          while (i < photos.length) {
            const n = perRiga[k % perRiga.length];
            righe.push(photos.slice(i, i + n));
            i += n; k++;
          }
          let base = 0;
          return righe.map((riga, ri) => {
            const partenza = base; base += riga.length;
            return (
              <div className="campaign-nm__riga" key={ri}>
                {riga.map((src, j) => {
                  const idx = partenza + j;
                  return (
                    <figure className="campaign-nm__cell" key={idx}
                            onClick={() => setActive(idx)} style={{ cursor: "zoom-in", flexGrow: 1.33 }}>
                      <img src={src} alt={`Campagna AI26 — ${idx + 1}`} loading="lazy"
                           onLoad={(e) => {
                             const im = e.target;
                             if (im.naturalWidth && im.naturalHeight) {
                               const r = im.naturalWidth / im.naturalHeight;
                               const fig = im.closest("figure");
                               fig.style.flexGrow = String(r);
                               // La foto piu' alta che larga sul telefono sta da sola a
                               // tutta riga: affiancata a una orizzontale sballerebbe
                               // l'altezza della coppia (Stefano 25/08/2026).
                               if (r < 1) fig.classList.add("is-verticale");
                             }
                           }} />
                    </figure>
                  );
                })}
              </div>
            );
          });
        })()}
      </div>
      {active !== null && (
        <div className="camp-viewer" onClick={() => setActive(null)}>
          <button className="camp-viewer__close" onClick={() => setActive(null)} aria-label="Chiudi">×</button>
          <div className="camp-viewer__scroll" ref={scrollRef} onClick={(e) => e.stopPropagation()}>
            {photos.map((src, i) => (
              <figure className="camp-viewer__slide" key={i} data-idx={i}>
                <img src={src} alt={`Campagna AI26 — ${i + 1}`} />
              </figure>
            ))}
          </div>
          <div className="camp-viewer__count">{visibile + 1} / {photos.length}</div>
        </div>
      )}
    </section>
  );
}

// ---- Marquee ----
function Marquee() {
  const phrase = (
    <>
      <span>Made in Italy</span><span className="dot">✦</span>
      <span>Carpi, 1986</span><span className="dot">✦</span>
      <span>Spring Summer 2026</span><span className="dot">✦</span>
      <span>Phi Phi</span><span className="dot">✦</span>
    </>
  );
  return (
    <div className="marquee" aria-hidden="true">
      <div className="marquee__track">{phrase}{phrase}{phrase}{phrase}</div>
    </div>
  );
}

// ---- Maison / Intro ----
function Maison({ t }) {
  return (
    <section className="section" id="maison" data-screen-label="02 Maison">
      <div className="intro">
        <div className="intro__visual reveal">
          <img src={IMG.intro} alt="" />
        </div>
        <div className="intro__copy">
          <div className="eyebrow reveal">{t.intro.eyebrow}</div>
          <h2 className="h-section intro__title reveal">{t.intro.title}</h2>
          <p className="body-lede reveal">{t.intro.body}</p>
          <div className="intro__stats reveal">
            {[t.intro.stat1, t.intro.stat2, t.intro.stat3].map(([n, l], idx) => (
              <div className="intro__stat" key={idx}>
                <strong>{n}</strong><span>{l}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- Collections ----
function Collections({ t }) {
  const goTo = (id) => () => {
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: "smooth" });
  };
  // Click su qualsiasi card -> scroll al Lookbook (Nona ha 1 sola collezione)
  const onCardClick = () => () => goTo("lookbook")();
  return (
    <section className="section section--warm" id="collections" data-screen-label="03 Collections" style={{ maxWidth: "none", padding: 0, scrollMarginTop: "60px" }}>
      <div style={{ maxWidth: "var(--max)", margin: "0 auto", padding: "clamp(64px, 7vw, 100px) var(--gutter) clamp(80px, 10vw, 140px)" }}>
        <div className="section__head">
          <div className="eyebrow reveal">{t.collections.eyebrow}</div>
          <h2 className="h-section reveal">{t.collections.title}</h2>
        </div>
        <div className="collections">
          {t.collections.items.map((item, i) => (
            <article className="coll-card reveal" key={i} style={{ transitionDelay: `${i * 100}ms`, cursor: "pointer" }} onClick={onCardClick(i)}>
              <div className="coll-card__media">
                <img src={IMG.collectionTiles[i]} alt={item.name} />
                <div className="coll-card__season">{item.season}</div>
              </div>
              <div className="coll-card__row">
                <h3 className="coll-card__name">{item.name}</h3>
                <span className="coll-card__arrow">— Esplora →</span>
              </div>
              <p className="coll-card__desc">{item.desc}</p>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---- Gold Lookbook Modal ----
function GoldLookbookModal() {
  const [open, setOpen] = React.useState(false);
  const [active, setActive] = React.useState(null);
  const photos = (IMG.gold && IMG.gold.lookbook) || [];

  React.useEffect(() => {
    const onOpen = () => { setOpen(true); document.body.style.overflow = "hidden"; };
    window.addEventListener("open-gold-lookbook", onOpen);
    return () => window.removeEventListener("open-gold-lookbook", onOpen);
  }, []);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape") {
        if (active !== null) setActive(null);
        else { setOpen(false); document.body.style.overflow = ""; }
      } else if (active !== null && e.key === "ArrowRight") {
        setActive((active + 1) % photos.length);
      } else if (active !== null && e.key === "ArrowLeft") {
        setActive((active - 1 + photos.length) % photos.length);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, active, photos.length]);

  if (!open) return null;
  const close = () => { setOpen(false); setActive(null); document.body.style.overflow = ""; };

  return (
    <div className="gold-lb-modal" onClick={close}>
      <header className="gold-lb-modal__head" onClick={(e) => e.stopPropagation()}>
        <div className="gold-lb-modal__title">
          <div className="gold-lb-modal__eyebrow">Capsule — FW 2026</div>
          <h2>Siste's Gold</h2>
        </div>
        <button className="gold-lb-modal__close" onClick={close} aria-label="Chiudi">×</button>
      </header>
      <div className="gold-lb-modal__grid" onClick={(e) => e.stopPropagation()}>
        {photos.map((src, i) => (
          <figure className="gold-lb-modal__cell" key={i} onClick={() => setActive(i)}>
            <img src={src} alt={`Gold look ${i + 1}`} loading="lazy" />
          </figure>
        ))}
      </div>
      {active !== null && (
        <div className="gold-lb-modal__lightbox" onClick={() => setActive(null)}>
          <button className="gold-lb-modal__lb-prev" onClick={(e) => { e.stopPropagation(); setActive((active - 1 + photos.length) % photos.length); }} aria-label="Precedente">‹</button>
          <img src={photos[active]} alt="" onClick={(e) => e.stopPropagation()} />
          <button className="gold-lb-modal__lb-next" onClick={(e) => { e.stopPropagation(); setActive((active + 1) % photos.length); }} aria-label="Successivo">›</button>
          <div className="gold-lb-modal__lb-count">{active + 1} / {photos.length}</div>
        </div>
      )}
    </div>
  );
}

// ---- Gold ----
function Gold({ t }) {
  const g = IMG.gold;
  return (
    <section className="gold" id="gold" data-screen-label="04 Gold">
      <div className="gold__visual reveal">
        <img className="gold__hero-img" src={g.hero} alt="Siste's Gold campaign" />
        <div className="gold__hero-grain"></div>
      </div>
      <div className="gold__copy">
        <div className="gold__head">
          <div className="eyebrow gold__eyebrow reveal">{t.gold.eyebrow}</div>
          <div className="gold__location reveal">{t.gold.location}</div>
        </div>
        <img className="gold__logo reveal" src={g.logo} alt="Siste's Gold" />
        <p className="gold__body reveal">{t.gold.body}</p>
        <div className="gold__gallery reveal">
          {g.gallery.map((it, idx) => (
            <figure className="gold__gal-item" key={idx} style={{ animationDelay: `${idx * 80}ms` }}>
              <img src={it.src} alt={it.caption} />
              <figcaption>{it.caption}</figcaption>
            </figure>
          ))}
        </div>
        <button className="btn gold__cta reveal" onClick={() => window.dispatchEvent(new Event('open-gold-lookbook'))}>
          <span className="btn__label">{t.gold.cta}</span>
          <span className="btn__arrow"><Icon.ArrowRight size={14} /></span>
        </button>
      </div>
    </section>
  );
}

// ---- Lookbook ----
function Lookbook({ t }) {
  const [active, setActive] = React.useState(null);
  const [page, setPage] = React.useState(0);
  const sectionRef = React.useRef(null);
  // Solo articoli con scontornato _F disponibile (hover swap funzionante)
  const HAS_F = new Set([
    "14M0100T40_14.0190", "14M0101T40_14M.0186", "14M0103T92_14.0190", "14M0104T70_14M.0186",
    "14M0105J70_14.0190", "14M0106T61_14.0190", "14M0200T40_14M.0186", "14M0201T40_14.0190",
    "14M0203T92_14M.0105", "14M0204T49_14M.0209", "14M0206T49_14.0457", "14M0207T49_14.0457",
    "14M0208T70_14M.0105", "14M0210T75_14M.0118", "14M0211T75_14M.0200", "14M0212T75_14M.0200",
    "14M0213T75_14.0121", "14M0214T61_14.0121", "14M0215T61_14M.0180", "14M0216T61_14M.0180",
    "14M0217T61_14M.0180", "14M0220T87_14.0100", "14M0221T87_14.0100", "14M0222T87_14M.0187",
    "14M0223T87_14M.0187", "14M0224T87_14M.0182", "14M0225T87_14M.0182", "14M0255T92_14.0190",
    "14M0270T49_14.0457", "14M0271T49_14.0457", "14M0272T49_14.0457", "14M0273T49_14.0457",
    "14M0274T49_14.0457", "14M0295T61_14M.0180", "14M0296T70_14M.0186", "14M0301T49_14M.0201",
    "14M0302T49_14M.0201", "14M0303T70_14.0121", "14M0304T70_14.0121", "14M0305J70_14.0190",
    "14M0307J61_14M.0188", "14M0308J61_14M.0188", "14M0310J61_14M.0188", "14M0311J89_14.0121",
    "14M0314J89_14M.0142", "14M0317J89_14M.0186", "14M0318J50_14M.0186", "14M0319T50_14.0121",
    "14M0327J50_14M.0186", "14M0350T92_14.0121", "14M0352T92_14M.0188", "14M0353T92_14M.0188",
    "14M0400M70_14.0190", "14M0401M70_14.0190", "14M0407M89_14.0100", "14M0408M89_14.0121",
    "14M0409M89_14.0100", "14M0413M19_14.0457", "14M0420M19_14M.0118", "14M0422M19_14M.0204",
    "14M0424M41_14M.0105", "14M0425M41_14M.0105", "14M0426M41_14M.0105", "14M0428M41_14M.0127",
    "14M0430M41_14M.0118", "14M0432M33_14M.0187", "14M0434M33_14M.0187", "14M0436M33_14M.0178",
    "14M0439M33_14M.0127", "14M0440M33_14M.0127", "14M0442M33_14M.0142", "14M0443M33_14M.0142",
    "14M0465M33_14M.0182", "14M0466M33_14M.0182", "14M0489M19_14M.0118", "14M0500T40_14.0190",
    "14M0501T70_14M.0186", "14M0502T70_14M.0105", "14M0540T49_14.0457", "14M0600T40_14M.0186",
    "14M0601T40_14M.0186", "14M0602T40_14M.0180", "14M0603T40_14M.0186", "14M0604T40_14M.0180",
    "14M0606T40_14M.0186", "14M0608T92_14.0121", "14M0609M92_14.0121", "14M0610T92_14M.0188",
    "14M0611T92_14.0190", "14M0613T70_14M.0188", "14M0614T70_14M.0188", "14M0615T70_14M.0188",
    "14M0616T70_14M.0188", "14M0618T70_14.0121", "14M0619T70_14.0190", "14M0620T70_14M.0186",
    "14M0621J70_14.0190", "14M0622T70_14M.0105", "14M0624T75_14M.0186", "14M0626T75_14M.0118",
    "14M0628T61_14M.0180", "14M0629T87_14.0190", "14M0631T76_14M.0178", "14M0632T76_14M.0187",
    "14M0633T76_14M.0118", "14M0634T76_14.0129", "14M0635T76_14.0129", "14M0636T76_14M.0186",
    "14M0637T76_14M.0188", "14M0639T76_14M.0180", "14M0640T76_14M.0178", "14M0641T76_14M.0188",
    "14M0642M33_14M.0178", "14M0697T61_14M.0118", "14M0700T40_14M.0186", "14M0701T40_14M.0186",
    "14M0702T40_14M.0180", "14M0703T40_14M.0186", "14M0704T92_14M.0105", "14M0705T49_14M.0178",
    "14M0706T49_14M.0201", "14M0708T70_14M.0188", "14M0711T75_14M.0186", "14M0712T75_14.0190",
    "14M0713T75_14M.0118", "14M0714T75_14M.0180", "14M0715T75_14M.0188", "14M0716T61_14M.0118",
    "14M0717M61_14M.0105", "14M0718T75_14M.0118", "14M0720T87_14.0190", "14M0723T76_14M.0178",
    "14M0725M19_14M.0300", "14M0727M19_14.0121", "14M0729M33_14M.0187", "14M0730M33_14M.0142",
    "14M0800T49_14M.0178", "14M0801T70_14M.0186", "14M0802T75_14M.0118", "14M0803T75_14.0190",
    "14M0804T75_14.0121", "14M0820T49_14.0457", "14M0900T40_14M.0186", "14M0903T92_14M.0180",
    "14M0904T70_14.0457", "14M0905T70_14.0457", "14M0906T75_14M.0118", "14M0907T87_14M.0118",
    "14M0908T49_14M.0142", "14M0909T87_14M.0178", "14M0910T87_14M.0186", "14M0911T87_14M.0188",
    "14M0913T87_14M.0182", "14M0914T87_14.0121", "14M0916T49_14.0457", "14M0918T55_14M.0127",
    "14M0919T55_14M.0186", "14M0930T55_14M.0213", "14M0983T49_14M.0178", "14M0993T49_14M.0178"
  ]);
  const studio = (IMG.lookbook || []).filter(it => {
    const m = it.src.match(/([^/]+)_A\.(jpg|jpeg)$/i);
    return m && HAS_F.has(m[1]);
  });
  // Solo i capi, niente foto di campagna in mezzo. Prima ogni pagina infilava due
  // scatti in esterna fra i prodotti: spezzavano la lettura della collezione e non
  // piacevano (Simone e Milena via Stefano, 25/08/2026). Le foto di campagna hanno
  // gia' la loro sezione, li' si vedono tutte e si aprono in grande.
  const PER_PAGE = 12;
  const totalPages = Math.max(1, Math.ceil(studio.length / PER_PAGE));
  const start = page * PER_PAGE;
  const pageStudio = studio.slice(start, start + PER_PAGE);
  const items = pageStudio.map(x => ({ ...x, tag: "tall" }));
  const total = items.length;

  const goToPage = (p) => {
    setPage(p);
    setActive(null);
    if (sectionRef.current) sectionRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  // Cambiando pagina le celle nuove restavano trasparenti e non tornavano piu':
  // l'animazione "compari mentre scorri" non le prendeva, e nemmeno scorrendo
  // si vedevano. Sul telefono di Simone la collezione appariva mezza vuota
  // (video del 25/08/2026: pagina 14, torno alla 13, meta' griglia bianca).
  // Cambiare pagina e' una scelta di chi guarda: le foto devono esserci subito,
  // senza aspettare nessuna animazione.
  React.useEffect(() => {
    const box = sectionRef.current;
    if (!box) return;
    box.querySelectorAll(".reveal").forEach((el) => el.classList.add("is-in"));
  }, [page]);

  React.useEffect(() => {
    if (active === null) return;
    const onKey = (e) => {
      if (e.key === "Escape") setActive(null);
      else if (e.key === "ArrowRight") setActive((active + 1) % studio.length);
      else if (e.key === "ArrowLeft") setActive((active - 1 + studio.length) % studio.length);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [active, total]);

  return (
    <section ref={sectionRef} className="lookbook" id="lookbook" data-screen-label="05 Lookbook">
      <div className="lookbook__head">
        <div className="eyebrow reveal">{t.lookbook.eyebrow}</div>
        <div className="reveal">
          <h2 className="h-section" style={{ marginBottom: 20 }}>{t.lookbook.title}</h2>
          <p className="body-lede">{t.lookbook.sub}</p>
        </div>
      </div>
      <div className="lb-grid">
        {items.map((it, i) => {
          // Studio shot _A.jpg -> hover mostra scontornato _F.jpg (stesso articolo)
          const srcHover = /_A\.(jpg|jpeg)$/i.test(it.src)
            ? it.src.replace(/_A\.(jpg|jpeg|JPG|JPEG)$/, "_F.jpg")
            : null;
          return (
            <figure
              className={`lb-grid__cell lb-grid__cell--${it.tag} reveal`}
              key={i}
              onClick={() => setActive(start + i)}
              style={{ transitionDelay: `${(i % 4) * 60}ms` }}
            >
              <img className="lb-grid__cell-main" src={it.src} alt={it.title || ""} loading="lazy" />
              {srcHover && <img className="lb-grid__cell-hover" src={srcHover} alt="" loading="lazy" onError={(e) => e.currentTarget.style.display = "none"} />}
              <figcaption>{it.code || it.title}</figcaption>
            </figure>
          );
        })}
      </div>
      {totalPages > 1 && (
        <nav className="lb-pagination" aria-label="Paginazione lookbook">
          {Array.from({ length: totalPages }).map((_, i) => (
            <button
              key={i}
              className={`lb-pagination__btn ${i === page ? "is-active" : ""}`}
              onClick={() => goToPage(i)}
              aria-current={i === page ? "page" : undefined}
            >
              {String(i + 1).padStart(2, "0")}
            </button>
          ))}
        </nav>
      )}
      {active !== null && (
        <div className="lb-lightbox" onClick={() => setActive(null)}>
          <button className="lb-lightbox__btn lb-lightbox__btn--prev" onClick={(e) => { e.stopPropagation(); setActive((active - 1 + studio.length) % studio.length); }} aria-label="Precedente">‹</button>
          <img src={studio[active].src} alt="" onClick={(e) => e.stopPropagation()} />
          <button className="lb-lightbox__btn lb-lightbox__btn--next" onClick={(e) => { e.stopPropagation(); setActive((active + 1) % studio.length); }} aria-label="Successivo">›</button>
          <button className="lb-lightbox__close" onClick={() => setActive(null)} aria-label="Chiudi">×</button>
          <div className="lb-lightbox__count">{active + 1} / {studio.length}</div>
        </div>
      )}
    </section>
  );
}

// ---- B2B ----
function B2B({ t }) {
  return (
    <section className="b2b" id="b2b" data-screen-label="06 B2B">
      <div className="b2b__head">
        <div className="eyebrow reveal">{t.b2b.eyebrow}</div>
        <h2 className="h-section reveal">{t.b2b.title}</h2>
        {t.b2b.body ? <p className="body-lede reveal">{t.b2b.body}</p> : null}
      </div>
      <div className="b2b__cards reveal">
        {t.b2b.portals.map((p, i) => (
          <a className="b2b-card" href={p.url} target="_blank" rel="noopener" key={i}>
            <div className="b2b-card__img">
              <img src={p.img} alt={p.label} />
            </div>
            <div className="b2b-card__overlay">
              <div className="b2b-card__top">
                <span className="b2b-card__tag">{p.tag}</span>
              </div>
              <div className="b2b-card__bottom">
                <div className="b2b-card__label">{p.label}</div>
                <div className="b2b-card__row">
                  <span className="b2b-card__host">↗ {p.host}</span>
                  <span className="b2b-card__cta">{t.b2b.cta} <Icon.ArrowRight size={14} /></span>
                </div>
              </div>
            </div>
          </a>
        ))}
      </div>
      <div className="b2b__foot reveal">
        <span className="b2b__note">{t.b2b.note} <a href="#contact">{t.b2b.noteCta}</a></span>
      </div>
    </section>
  );
}

// ---- Contact form ----
function ContactForm({ t }) {
  // Generate a random 5-letter captcha once per mount
  const [captcha] = React.useState(() => {
    const chars = "ABCDEFGHKMNPQRSTUVWXYZ23456789";
    let s = "";
    for (let i = 0; i < 5; i++) s += chars[Math.floor(Math.random() * chars.length)];
    return s;
  });
  const [form, setForm] = React.useState({ name: "", email: "", message: "", code: "", privacy: false, website: "" });
  const [status, setStatus] = React.useState(null); // null | "sending" | "sent" | "error"
  const wrapRef = React.useRef(null);
  const set = (k) => (e) => setForm({ ...form, [k]: e.target.type === "checkbox" ? e.target.checked : e.target.value });
  React.useEffect(() => {
    if (status === "sent" && wrapRef.current) {
      wrapRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }, [status]);
  const submit = async (e) => {
    e.preventDefault();
    if (form.code.trim().toUpperCase() !== captcha) { setStatus("error"); return; }
    setStatus("sending");
    try {
      const r = await fetch("https://dashboard.sistes.it/api/site-contact?brand=more", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: form.name,
          email: form.email,
          message: form.message,
          website: form.website,
        }),
      });
      const j = await r.json();
      setStatus(j && j.ok ? "sent" : "error");
    } catch (err) {
      setStatus("error");
    }
  };
  if (status === "sent") {
    return (
      <div ref={wrapRef} className="contact-form contact-form--sent reveal" style={{ textAlign: "center", padding: "48px 32px", border: "1px solid rgba(182, 145, 98, 0.3)", borderRadius: "8px", background: "rgba(182, 145, 98, 0.05)" }}>
        <div className="contact-form__check" style={{ fontSize: "48px", color: "var(--gold)", marginBottom: "16px", lineHeight: 1 }}>✓</div>
        <h3 style={{ fontFamily: "var(--f-serif)", fontSize: "28px", fontWeight: 300, fontStyle: "italic", margin: "0 0 12px", color: "var(--ink)" }}>Messaggio inviato</h3>
        <p className="body-lede" style={{ margin: 0 }}>{t.contact.form.sent}</p>
      </div>
    );
  }
  return (
    <form ref={wrapRef} className="contact-form reveal" onSubmit={submit} noValidate>
      <p className="contact-form__intro">{t.contact.form.intro}</p>
      {/* honeypot anti-bot: invisibile agli umani, riempito dai bot → server scarta */}
      <input type="text" name="website" tabIndex={-1} autoComplete="off"
             value={form.website} onChange={set("website")}
             style={{ position: "absolute", left: "-9999px", opacity: 0, height: 0, width: 0 }}
             aria-hidden="true" />
      <div className="contact-form__row">
        <label className="field">
          <span className="field__label">{t.contact.form.name} <em>*</em></span>
          <input type="text" required value={form.name} onChange={set("name")} />
        </label>
        <label className="field">
          <span className="field__label">{t.contact.form.email} <em>*</em></span>
          <input type="email" required value={form.email} onChange={set("email")} />
        </label>
      </div>
      <label className="field">
        <span className="field__label">{t.contact.form.message} <em>*</em></span>
        <textarea required rows="5" value={form.message} onChange={set("message")}></textarea>
      </label>
      <div className="contact-form__captcha">
        <label className="field field--captcha">
          <span className="field__label">{t.contact.form.captchaLabel} <em>*</em></span>
          <input type="text" required value={form.code} onChange={set("code")} maxLength={5} autoComplete="off" />
        </label>
        <div className="captcha-display" aria-label={`Code: ${captcha}`}>
          {captcha.split("").map((c, i) => (
            <span key={i} style={{ transform: `rotate(${(i % 2 === 0 ? -1 : 1) * (3 + i * 2)}deg)` }}>{c}</span>
          ))}
        </div>
      </div>
      <label className="field field--check">
        <input type="checkbox" required checked={form.privacy} onChange={set("privacy")} />
        <span>{t.contact.form.privacy}</span>
      </label>
      {status === "error" && <div className="contact-form__error">{t.contact.form.error}</div>}
      <button type="submit" className="btn btn--filled contact-form__submit" disabled={status === "sending"}>
        <span className="btn__label">{status === "sending" ? "Invio in corso…" : t.contact.form.submit}</span>
        <span className="btn__arrow"><Icon.ArrowRight size={14} /></span>
      </button>
    </form>
  );
}

// ---- Instagram ----
function Instagram({ t }) {
  // Carica lo script Elfsight una volta sola
  React.useEffect(() => {
    if (document.querySelector('script[src="https://elfsightcdn.com/platform.js"]')) return;
    const s = document.createElement("script");
    s.src = "https://elfsightcdn.com/platform.js";
    s.async = true;
    document.body.appendChild(s);
  }, []);
  return (
    <section className="section section--warm" id="instagram" data-screen-label="07 Instagram" style={{ maxWidth: "none", padding: 0 }}>
      <div style={{ maxWidth: "var(--max)", margin: "0 auto", padding: "clamp(40px, 5vw, 72px) var(--gutter) clamp(56px, 7vw, 96px)" }}>
        <div className="ig__head reveal">
          <div className="eyebrow">{t.instagram.eyebrow}</div>
          <h2 className="h-section">{t.instagram.title}</h2>
          <p className="body-lede">{t.instagram.sub}</p>
        </div>
        <div className="ig__bar reveal">
          <div className="ig__profile">
            <div className="ig__avatar">
              <span>M</span>
            </div>
            <div className="ig__id">
              <strong>More by Siste's</strong>
              <span>{t.instagram.handle}</span>
            </div>
          </div>
          <a className="ig__cta" href="https://www.instagram.com/morebysistes/" target="_blank" rel="noopener">
            {t.instagram.cta} <Icon.ArrowRight size={14} />
          </a>
        </div>
        {/* Elfsight Instagram Feed widget */}
        <div className="elfsight-app-c00a45ef-1258-47e3-8148-9a48f309db53 reveal"></div>
      </div>
    </section>
  );
}

// ---- Contact ----
function Contact({ t }) {
  return (
    <section className="section" id="contact" data-screen-label="07 Contact">
      <div className="contact">
        <div className="contact__visual reveal">
          <img src={IMG.contact} alt="" />
        </div>
        <div className="contact__copy">
          <div className="eyebrow reveal">{t.contact.eyebrow}</div>
          <h2 className="h-section reveal">{t.contact.title}</h2>
          <p className="body-lede reveal">{t.contact.sub}</p>
          <div className="contact__blocks reveal">
            {t.contact.blocks.map((b, i) => (
              <div className="contact__block" key={i}>
                <div className="contact__label">{b.label}</div>
                <div className="contact__lines">
                  {b.lines.map((l, j) => {
                    const lower = String(l).toLowerCase();
                    if (lower.includes("@") && /\S+@\S+\.\S+/.test(lower)) {
                      return <a key={j} href={`mailto:${l}`} style={{ textDecoration: "underline", textDecorationColor: "rgba(182,145,98,0.4)", textUnderlineOffset: "3px" }}>{l}</a>;
                    }
                    if (/^\+?[\d\s().\-/]{6,}$/.test(String(l).trim())) {
                      return <a key={j} href={`tel:${String(l).replace(/[^+\d]/g, "")}`} style={{ textDecoration: "underline", textDecorationColor: "rgba(182,145,98,0.4)", textUnderlineOffset: "3px" }}>{l}</a>;
                    }
                    return <span key={j}>{l}</span>;
                  })}
                </div>
              </div>
            ))}
          </div>
          <ContactForm t={t} />
          <div className="contact__legal reveal">
            <div className="contact__legal-co">{t.contact.legalCompany}</div>
            <div className="contact__legal-lines">
              {t.contact.legalLines.map((l, i) => <span key={i}>{l}</span>)}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- Footer ----
function Footer({ t }) {
  return (
    <footer className="footer" data-screen-label="08 Footer">
      <div className="footer__grid">
        <div className="footer__brand">
          <div className="logo logo--footer">
            <img src="assets/logo-more.png" alt="More by Siste's" />
          </div>
          <div className="footer__tagline">{t.footer.tagline}</div>
        </div>
        <div className="footer__col">
          <h4>{t.footer.cols.client[0]}</h4>
          <ul>{t.footer.cols.client.slice(1).map((l, i) => {
            const lower = l.toLowerCase();
            const href = lower.includes("contact") || lower.includes("contatt") ? "#contact"
                       : lower.includes("b2b") ? "#b2b"
                       : "#";
            return <li key={i}><a href={href}>{l}</a></li>;
          })}</ul>
        </div>
        <div className="footer__col">
          <h4>{t.footer.cols.legal[0]}</h4>
          <ul>{t.footer.cols.legal.slice(1).map((l, i) => {
            const lower = l.toLowerCase();
            const href = lower.startsWith("privacy") ? "privacy.html"
                       : lower.startsWith("cookie") ? "cookies.html"
                       : "#";
            return <li key={i}><a href={href}>{l}</a></li>;
          })}</ul>
        </div>
      </div>
      <div className="footer__bottom">
        <span>{t.footer.legal}</span>
        <div className="footer__social">
          <a href="https://www.instagram.com/sistesmoda/" target="_blank" rel="noopener">Instagram</a>
          <a href="https://www.facebook.com/sistesmoda/" target="_blank" rel="noopener">Facebook</a>
        </div>
      </div>
    </footer>
  );
}

// ---- Tweaks ----
function Tweaks({ tweaks, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection title="Tema">
        <TweakRadio
          label="Palette"
          value={tweaks.theme}
          options={[
            { value: "warm", label: "Warm" },
            { value: "stone", label: "Stone" },
            { value: "dark", label: "Dark" },
          ]}
          onChange={(v) => setTweak("theme", v)}
        />
        <TweakRadio
          label="Tipografia titoli"
          value={tweaks.font}
          options={[
            { value: "mixed", label: "Mista" },
            { value: "serif", label: "Serif" },
            { value: "display", label: "Sans" },
          ]}
          onChange={(v) => setTweak("font", v)}
        />
      </TweakSection>
      <TweakSection title="Hero">
        <TweakToggle
          label="Slideshow automatico"
          checked={tweaks.autoplay}
          onChange={(v) => setTweak("autoplay", v)}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

// ---- Root ----
function App() {
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "theme": "warm",
    "font": "mixed",
    "autoplay": true,
    "lang": "it"
  }/*EDITMODE-END*/;

  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLang] = useState(tweaks.lang || "it");
  useEffect(() => { setTweak("lang", lang); }, [lang]);

  useEffect(() => {
    document.body.className = `theme-${tweaks.theme} font-${tweaks.font}`;
  }, [tweaks.theme, tweaks.font]);

  useReveal();
  const t = C[lang];

  return (
    <>
      <TopBar lang={lang} setLang={setLang} t={t} />
      <Hero t={t} autoplay={tweaks.autoplay} />
      <Maison t={t} />
      <CampaignNM t={t} />
      <Collections t={t} />
      <Lookbook t={t} />
      <B2B t={t} />
      <Instagram t={t} />
      <Contact t={t} />
      <Footer t={t} />
      <Tweaks tweaks={tweaks} setTweak={setTweak} />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
