// ============================================================
// Tribeca Lisboa — PRE-LAUNCH LANDING (standalone page)
// Independent of the main site chrome. Reuses i18n + Primitives
// (Logo, IconInstagram, TertiaryButton, Reveal) + RNewsletter.
// Bilingual EN/PT. No primary navigation.
// ============================================================
const { useState: useStateLP, useEffect: useEffectLP, useRef: useRefLP } = React;
const AB = 'uploads/about';

// IG_URL + openExt + LpLang/LpHeader/LpFooter are shared from LandingChrome.jsx

// reveal-on-scroll (window scroll) — toggles .ab-rev → .in
function useLpReveal(rootRef) {
  useEffectLP(() => {
    const root = rootRef.current; if (!root) return;
    const els = root.querySelectorAll('.ab-rev');
    if (window.PREFERS_REDUCED) { els.forEach(e => e.classList.add('in')); return; }
    const vh = () => window.innerHeight || document.documentElement.clientHeight;
    const check = () => els.forEach(el => { if (!el.classList.contains('in')) { const r = el.getBoundingClientRect(); if (r.top < vh() - 40 && r.bottom > 0) el.classList.add('in'); } });
    let frames = 0, raf, alive = true;
    const burst = () => { if (!alive) return; check(); if (frames++ < 16) raf = requestAnimationFrame(burst); };
    const onScroll = () => check();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    burst();
    const t1 = setTimeout(check, 300), t2 = setTimeout(check, 800);
    return () => { alive = false; cancelAnimationFrame(raf); clearTimeout(t1); clearTimeout(t2); window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); };
  }, []);
}

// ---- Header (logo + lang + Instagram + SIC, no nav) → LandingChrome.jsx ---

// ---- Hero (homepage hero design: video + bottom-left badge/H1/sub) ---
function LpHero() {
  const lang = React.useContext(LangContext);
  return (
    <section className="r-hero" id="top">
      <video className="r-hero-img" autoPlay muted loop playsInline poster={R(`${AB}/ny-aerial.jpg`)}>
        <source src={R(`${AB}/tribeca.mp4`)} type="video/mp4" />
      </video>
      <div className="r-hero-grad"></div>
      <div className="r-hero-body">
        <div className="r-wrap r-hero-inner">
          <Reveal className="r-hero-col" delay={160} y={20}>
            <a className="oa-chip" href="#open-air"
              onClick={(e) => { e.preventDefault();
                const el = document.getElementById('open-air'); if (!el) return;
                const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
                const hdr = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--hdr-h')) || 82;
                window.scrollTo({ top: window.scrollY + el.getBoundingClientRect().top - hdr, behavior: reduce ? 'auto' : 'smooth' });
              }}
              aria-label="Tribeca Open Air, powered by Toyota">
              <span className="oa-chip-kicker">Stories Under the Sky</span>
              <span className="oa-chip-l1">
                <span className="oa-chip-title">Tribeca Open Air</span>
                <span className="oa-chip-arrow" aria-hidden="true">↗</span>
              </span>
              <span className="oa-chip-l2">· powered by
                <span className="oa-chip-toyota"><img src={R('uploads/crop/Toyota.svg')} alt="Toyota" /></span>
              </span>
            </a>
            <span className="r-hero-badge">{tt(lang, '9–13 DEC 2026', '9–13 DEZ 2026')}</span>
            <h1 className="r-hero-h1">{tt(lang, 'Tribeca Lisboa is back', 'O Tribeca Lisboa está de volta')}</h1>
            <p className="r-hero-sub lp-hero-sub">{tt(lang,
              'The future of culture lives in Lisbon, on Avenida da Liberdade, during the most magical time of the year.',
              'O futuro da cultura vive em Lisboa na Avenida da Liberdade durante a época mais mágica do ano.')}</p>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// ---- 00 — About hub -----------------------------------------
function LpAbout() {
  const lang = React.useContext(LangContext);
  const disc = lang === 'EN'
    ? ['Film', 'Music', 'Entertainment', 'Talent', 'Creativity']
    : ['Cinema', 'Música', 'Entretenimento', 'Talento', 'Criatividade'];
  return (
    <section className="ab-band r-band--black">
      <div className="r-wrap">
        <div className="ab-rev">
          <div className="ab-eyebrow" style={{ color: 'var(--pink)' }}><span className="n">{tt(lang, '00 — About · Tribeca Festival Lisboa', '00 — Sobre · Tribeca Festival Lisboa')}</span><span className="ln"></span></div>
          <h2 className="ab-h" style={{ maxWidth: '16ch' }}>{tt(lang, 'The European hub for storytelling', 'O hub europeu para o storytelling')}</h2>
          <div className="lp-disc">
            {disc.map((d, i) => (
              <React.Fragment key={d}>
                <span>{d}</span>{i < disc.length - 1 && <span className="dot">·</span>}
              </React.Fragment>
            ))}
          </div>
          <p className="ab-body" style={{ marginTop: 28 }}>{tt(lang,
            'Tribeca Festival Lisboa is much more than a festival. It is a year-round platform dedicated to contemporary storytelling. From film to podcasts, from music to television, creators, talent, and creativity come together in Lisbon through ideas and immersive formats that shape the culture of today and tomorrow.',
            'O Tribeca Festival Lisboa é muito mais que um festival. É uma plataforma que durante todo o ano se dedica ao storytelling contemporâneo. Do cinema aos podcasts, da música à televisão, criadores, talento e criatividade reúnem-se em Lisboa, com ideias e formatos imersivos que moldam a cultura hoje e do futuro.')}</p>
        </div>
      </div>
    </section>
  );
}

// ---- 01 — Origins (split, NY) -------------------------------
function LpOrigins() {
  const lang = React.useContext(LangContext);
  return (
    <section className="ab-band r-band--black">
      <div className="r-wrap">
        <div className="ab-split">
          <div className="ab-split-text ab-rev">
            <div className="ab-eyebrow" style={{ color: 'var(--pink)' }}><span className="n">{tt(lang, '01 — Origins', '01 — Origens')}</span><span className="ln"></span></div>
            <h2 className="ab-h">{tt(lang, 'From New York to the world', 'De Nova Iorque para o mundo')}</h2>
            <p className="ab-sub">{tt(lang, 'A cultural platform born from transformation', 'Uma plataforma cultural nascida da transformação')}</p>
            <p className="ab-body">{tt(lang,
              "Tribeca was founded in New York with a simple ambition: to bring people, culture, and creativity back to the heart of the city that never sleeps after September 11. What began as a film festival has become one of the world's most relevant cultural platforms, following the evolution of storytelling across film, music, technology, and entertainment for more than 25 years.",
              'O Tribeca foi fundado em Nova Iorque com uma ambição simples: trazer pessoas, cultura e criatividade ao coração da cidade que nunca dorme, após o 11 de setembro. O que começou como um festival de cinema tornou-se uma das plataformas culturais mais relevantes do mundo, acompanhando a transformação do storytelling no cinema, na música, na tecnologia e no entretenimento há mais de 25 anos.')}</p>
          </div>
          <div className="ab-split-media ab-rev"><img src={R(`${AB}/ny-brooklyn-portrait.jpg`)} alt="New York" /></div>
        </div>
      </div>
    </section>
  );
}

// ---- 02 — Legacy (indigo, 25 years) -------------------------
function LpLegacy() {
  const lang = React.useContext(LangContext);
  return (
    <section className="ab-band r-band--indigo ab-years">
      <div className="r-wrap">
        <div className="ab-rev big" aria-hidden="true">25<span className="u">{tt(lang, 'Years', 'Anos')}</span></div>
        <div className="ab-years-grid">
          <div className="ab-rev">
            <div className="ab-eyebrow" style={{ color: 'var(--vibes-hl)' }}><span className="n">{tt(lang, '02 — Legacy', '02 — Legado')}</span><span className="ln"></span></div>
            <h2 className="ab-h">{tt(lang, '25 years shaping culture', '25 anos a moldar a cultura')}</h2>
            <p className="ab-sub" style={{ marginTop: 16 }}>{tt(lang, 'Much more than a festival.', 'Muito mais do que um festival.')}</p>
          </div>
          <div className="ab-rev">
            <p className="ab-body" style={{ marginTop: 0 }}>{tt(lang,
              'For 25 years, Tribeca has been a stage for new voices, championing emerging talent and paving the way for innovative forms of storytelling through a constant reinvention of culture and creativity.',
              'Há 25 anos que o Tribeca tem sido um palco para novas vozes, impulsionando o talento emergente e abrindo caminho a formas inovadoras de storytelling, numa constante reinvenção da cultura e da criatividade.')}</p>
            <p className="ab-body">{tt(lang,
              'By bringing together different creative communities, it has become much more than a festival: a meeting point where filmmakers, artists, platforms, brands, startups, media, and creators share ideas, challenge conventions, and build the future of storytelling.',
              'Ao unir diferentes comunidades criativas, tornou-se muito mais do que um festival: um ponto de encontro onde realizadores, artistas, plataformas, marcas, startups, media e criadores partilham ideias, desafiam convenções e constroem o futuro do storytelling.')}</p>
            <p className="ab-body">{tt(lang,
              "Over the past two and a half decades, Tribeca has launched award-winning works, introduced some of today's most influential filmmakers, and propelled previously undiscovered talent, establishing itself as a benchmark platform for those shaping what comes next.",
              'Ao longo destas duas décadas e meia, o Tribeca lançou obras premiadas, revelou alguns dos mais influentes cineastas da atualidade e impulsionou talentos ainda desconhecidos, afirmando-se como uma plataforma de referência para quem está a definir o que vem a seguir.')}</p>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- 03 — Impact (keyword list, visual-led) -----------------
function LpImpact() {
  const lang = React.useContext(LangContext);
  const keys = lang === 'EN'
    ? ['Film', 'Music', 'Entertainment', 'Talent', 'Creativity']
    : ['Cinema', 'Música', 'Entretenimento', 'Talento', 'Criatividade'];
  return (
    <section className="ab-band r-band--black">
      <div className="r-wrap">
        <div className="ab-eyebrow ab-rev" style={{ color: 'var(--pink)' }}><span className="n">{tt(lang, '03 — Impact', '03 — Impacto')}</span><span className="ln"></span></div>
        <h2 className="ab-h ab-rev" style={{ marginBottom: 36, maxWidth: '14ch' }}>{tt(lang, 'A platform at the scale of culture', 'Uma plataforma à escala da cultura')}</h2>
        <div className="lp-keys ab-rev">
          {keys.map((k, i) => (
            <div className="lp-key" key={k}>
              <span className="num">{String(i + 1).padStart(2, '0')}</span>
              <span className="word">{k}</span>
            </div>
          ))}
        </div>
        <div className="lp-impact-media ab-rev"><img src={R(`${AB}/ny-times-square.jpg`)} alt="Times Square, New York" /></div>
      </div>
    </section>
  );
}

// ---- 04 — The Bridge (NY ↔ Lisbon) --------------------------
function LpBridge() {
  const lang = React.useContext(LangContext);
  return (
    <section className="r-band--black" style={{ paddingTop: 'var(--band-y)' }}>
      <div className="r-wrap">
        <div className="ab-eyebrow ab-rev" style={{ color: 'var(--pink)' }}><span className="n">{tt(lang, '04 — The Bridge', '04 — A Ponte')}</span><span className="ln"></span></div>
        <h2 className="ab-h ab-rev" style={{ marginBottom: 32, maxWidth: '18ch' }}>{tt(lang, 'Portugal as a bridge for global creativity', 'Portugal enquanto ponte para a criatividade global')}</h2>
      </div>
      <div className="ab-bridge ab-rev">
        <figure><img src={R(`${AB}/ny-brooklyn-sunset.jpg`)} alt="New York" /><div className="ab-bridge-grad"></div><figcaption><span className="tag">{tt(lang, 'Origin', 'Origem')}</span>{tt(lang, 'New York', 'Nova Iorque')}</figcaption></figure>
        <figure><img src={R(`${AB}/lisbon-bridge-bus.jpg`)} alt="Lisboa" /><div className="ab-bridge-grad"></div><figcaption><span className="tag">{tt(lang, 'Home', 'Casa')}</span>Lisboa</figcaption></figure>
      </div>
      <div className="r-wrap" style={{ marginTop: 40 }}>
        <p className="ab-body ab-rev" style={{ maxWidth: '60ch' }}>{tt(lang,
          "Lisbon has become one of Europe's most dynamic cultural and creative capitals. Tribeca Festival Lisboa was created to build a lasting cultural bridge between Lisbon and New York, connecting Portuguese talent, creators, media, and industry with international audiences, opportunities, and cultural conversations.",
          'Lisboa tornou-se uma das capitais culturais e criativas mais dinâmicas da Europa. O Tribeca Festival Lisboa foi criado para construir uma ponte cultural duradoura entre Lisboa e Nova Iorque, ligando o talento, os criadores, os media e a indústria portuguesa a audiências, oportunidades e conversas culturais internacionais.')}</p>
        <p className="ab-body ab-rev" style={{ maxWidth: '60ch' }}>{tt(lang,
          'A new hub for storytelling in Europe is born, with its eyes on the future and the world.',
          'Nasce assim um novo hub para o storytelling na Europa, de olhos postos no futuro e no mundo.')}</p>
      </div>
    </section>
  );
}

// ---- 05 — Tribeca Festival Lisboa (manifesto close) ---------
function LpClose() {
  const lang = React.useContext(LangContext);
  return (
    <section className="ab-close" style={{ background: '#000' }}>
      <div className="ab-close-in">
        <div className="r-wrap">
          <div className="ab-tfl ab-rev" style={{ marginBottom: 40 }}>
            <div className="lab">{tt(lang, '05 — Tribeca Festival Lisboa', '05 — Tribeca Festival Lisboa')}</div>
            <p className="ab-body" style={{ marginTop: 8, color: '#fff', maxWidth: '58ch' }}>{tt(lang,
              'More than a festival, Tribeca Festival Lisboa is a platform for exchange, collaboration, and cultural discovery, connecting Lisbon and New York — two cities shaped by culture.',
              'More than a festival, o Tribeca Festival Lisboa é uma plataforma de intercâmbio, colaboração e descoberta cultural, que liga Lisboa e Nova Iorque — duas cidades moldadas pela cultura.')}</p>
            <p className="ab-body" style={{ color: '#fff', maxWidth: '58ch' }}>{tt(lang,
              'More than hosting a festival, Lisbon becomes part of a global conversation about the future of culture, creativity, and entertainment. Here, we celebrate the stories that shaped us, amplify the stories being told today, and launch the stories that will define tomorrow.',
              'Mais do que receber um festival, Lisboa entra numa conversa global sobre o futuro da cultura, criatividade e entretenimento. Aqui celebram-se as histórias que nos moldaram, amplificam-se as que se contam hoje e lançam-se as que vão definir o futuro.')}</p>
          </div>
          <p className="ab-manifesto ab-rev">{tt(lang, 'While some cities host culture,', 'Enquanto algumas cidades acolhem a cultura,')}<br /><span className="hl">{tt(lang, 'others shape it.', 'outras moldam-na.')}</span></p>
        </div>
      </div>
    </section>
  );
}

// ---- TRIBECA OPEN AIR — white band, film rail + detail modal ----
// Mirrors the design handoff: pink eyebrow + two-line display title, real PT
// film one-sheets, portrait poster cards with a pink "Opening Night" badge,
// and a per-card detail modal (Tema / Moderação / Convidados / …). The poster
// IMAGE and TITLE open the same modal as "ver mais +". Bilingual via tt().
function LpOpenAirCard({ item, onOpen }) {
  const lang = React.useContext(LangContext);
  const title = tt(lang, item.titleEn || item.title, item.title);
  const open = (e) => { if (e) e.preventDefault(); onOpen(item.id); };
  const onKey = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(item.id); } };
  const buyTickets = (e) => { if (!item.ticketUrl || item.ticketUrl === '#') e.preventDefault(); else openExt(e, item.ticketUrl); };
  const label = tt(lang, `${title} — see details`, `${title} — ver detalhes`);
  return (
    <article className="r-ecard oa-card">
      <a className="r-ecard-media oa-media-link" href="#" onClick={open} onKeyDown={onKey} aria-label={label}>
        <img src={R(item.img)} alt={title} />
        <div className="oa-media-grad"></div>
        <div className="r-ecard-label"><span className="oa-label">Open Air</span></div>
        {item.kicker && <span className="oa-kicker">{tt(lang, item.kickerEn, item.kicker)}</span>}
      </a>
      <div className="r-ecard-body">
        <h3 className="r-ecard-title"><a className="oa-title-link" href="#" onClick={open}>{title}</a></h3>
        <p className="oa-line">{tt(lang, item.lineEn, item.line)} <span className="g">{tt(lang, item.lineTailEn, item.lineTail)}</span></p>
        <div className="r-ecard-venue" style={{ marginTop: 16 }}><IconPin /> {item.venue}</div>
        <div className="r-ecard-date">{tt(lang, item.dateEn, item.date)}</div>
        <div className="oa-card-actions">
          <a href={item.ticketUrl} target="_blank" rel="noopener noreferrer" onClick={buyTickets} style={{ textDecoration: 'none' }}>
            <TertiaryButton color="var(--film-hl)">{tt(lang, 'get tickets', 'comprar bilhetes')}</TertiaryButton>
          </a>
          <ButtonLink color="#fff" onClick={open}>{tt(lang, 'see more +', 'ver mais +')}</ButtonLink>
        </div>
      </div>
    </article>
  );
}

function LpOpenAirModal({ item, onClose }) {
  const lang = React.useContext(LangContext);
  const title = tt(lang, item.titleEn || item.title, item.title);
  useEffectLP(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, []);
  const buyTickets = (e) => { if (!item.ticketUrl || item.ticketUrl === '#') e.preventDefault(); else openExt(e, item.ticketUrl); };
  return (
    <div className="oa-modal" role="dialog" aria-modal="true" aria-label={title}>
      <div className="oa-modal-scrim" onClick={onClose}></div>
      <div className="oa-modal-panel">
        <div className="oa-modal-media">
          <img src={R(item.modalImg || item.img)} alt={title} />
          <button className="oa-modal-x" onClick={onClose} aria-label={tt(lang, 'Close', 'Fechar')}>✕</button>
        </div>
        <div className="oa-modal-body">
          <div className="oa-modal-badge">
            <span className="oa-label">Open Air</span>
            {item.kicker && <span className="oa-modal-kick">{tt(lang, item.kickerEn, item.kicker)}</span>}
          </div>
          <h3 className="oa-modal-title">{title}</h3>
          <p className="oa-modal-dir">{tt(lang, `Director: ${item.dir}`, `Realização: ${item.dir}`)}</p>
          <div className="oa-modal-meta">
            <span><IconPin /> {item.venue}</span>
            <span>{tt(lang, item.dateEn, item.date)}</span>
          </div>
          <div className="oa-dl">
            {item.rows.map((r, i) => (
              <div className="oa-dl-row" key={i}>
                <div className="oa-dl-k">{tt(lang, r.kEn || r.k, r.k)}</div>
                <div className="oa-dl-v">{tt(lang, r.vEn || r.v, r.v)}</div>
              </div>
            ))}
          </div>
          <div className="oa-modal-cta">
            <a href={item.ticketUrl} target="_blank" rel="noopener noreferrer" onClick={buyTickets} style={{ textDecoration: 'none' }}>
              <TertiaryButton color="var(--film-hl)">{tt(lang, 'get tickets', 'comprar bilhetes')}</TertiaryButton>
            </a>
          </div>
        </div>
      </div>
    </div>
  );
}

function LpOpenAir() {
  const lang = React.useContext(LangContext);
  const [openId, setOpenId] = useStateLP(null);
  const active = OPEN_AIR.find((c) => c.id === openId) || null;
  return (
    <section className="ab-band oa-band" id="open-air">
      <div className="r-wrap">
        <div className="ab-rev oa-head">
          <div className="ab-eyebrow" style={{ color: 'var(--pink)' }}>
            <span className="n">Tribeca Open Air · powered by Toyota</span><span className="ln"></span>
          </div>
          <h2 className="ab-h" style={{ maxWidth: '20ch' }}>Tribeca Open Air<br />Powered by Toyota</h2>
          <p className="ab-sub" style={{ marginTop: 14 }}>{FIX('Stories Under the Sky')}</p>
          <p className="oa-sky">{tt(lang, 'Four destinations. One open sky. Great stories.', 'Quatro destinos. Um céu aberto. Grandes histórias.')}</p>
          <div className="oa-intro">
            <p className="ab-body">{tt(lang,
              'More than an open-air film series, Tribeca Open Air is an extension of Tribeca Lisboa: an experience bringing together great films, inspiring conversations, and a community driven by the stories that shape contemporary culture.',
              'Mais do que um ciclo de cinema ao ar livre, o Tribeca Open Air é uma extensão do Tribeca Lisboa: uma experiência que reúne grandes filmes, conversas inspiradoras e uma comunidade movida pelas histórias que moldam a cultura contemporânea.')}</p>
          </div>
        </div>
      </div>
      <div className="r-rail oa-rail ab-rev">
        {OPEN_AIR.map((item) => <LpOpenAirCard key={item.id} item={item} onOpen={setOpenId} />)}
      </div>
      {active && <LpOpenAirModal item={active} onClose={() => setOpenId(null)} />}
    </section>
  );
}

// ---- From the feed (image-led, clickable → Instagram) -------
// Local copies of the @tribecalisboa feed (see uploads/tribeca_instagram_images/posts.json).
const LP_FEED_DIR = 'uploads/tribeca_instagram_images';
const LP_FEED = [
  { img: `${LP_FEED_DIR}/18412759585178612.webp`, url: 'https://www.instagram.com/p/DZF3-fjDu53/' },
  { img: `${LP_FEED_DIR}/18591411106012367.webp`, url: 'https://www.instagram.com/p/DZDRnTjuoeB/' },
  { img: `${LP_FEED_DIR}/18003678386923648.webp`, url: 'https://www.instagram.com/p/DZDRgtlujBm/' },
  { img: `${LP_FEED_DIR}/17963649332938054.webp`, url: 'https://www.instagram.com/p/DZDQ9s8Oatr/' },
  { img: `${LP_FEED_DIR}/18086503313620653.webp`, url: 'https://www.instagram.com/p/DYzBij1uJm0/' },
  { img: `${LP_FEED_DIR}/18426205777121836.webp`, url: 'https://www.instagram.com/p/DYP216Lu3yh/' },
  { img: `${LP_FEED_DIR}/18053843006480488.webp`, url: 'https://www.instagram.com/reel/DVtU_9RjVC2/' },
  { img: `${LP_FEED_DIR}/18091637834107737.webp`, url: 'https://www.instagram.com/p/DVjNdyODRwa/' },
  { img: `${LP_FEED_DIR}/18059995355353302.webp`, url: 'https://www.instagram.com/reel/DVf7V_aDZaj/' },
  { img: `${LP_FEED_DIR}/18096167057072614.webp`, url: 'https://www.instagram.com/p/DVbfFWcjYRj/' },
];
function LpFeed() {
  const lang = React.useContext(LangContext);
  return (
    <section className="ab-band r-band--black">
      <div className="r-wrap">
        <div className="ab-rev"><h2 className="r-h" style={{ color: '#fff' }}>{FIX('From the feed')}</h2></div>
        <div className="r-feed-head ab-rev">
          <a href={IG_URL} target="_blank" rel="noopener noreferrer" onClick={(e) => openExt(e, IG_URL)} style={{ color: '#fff', display: 'flex' }} aria-label="Instagram"><IconInstagram size={32} /></a>
          <a href={IG_URL} target="_blank" rel="noopener noreferrer" onClick={(e) => openExt(e, IG_URL)} style={{ textDecoration: 'none' }}>
            <TertiaryButton color="#fff">{tt(lang, 'follow @tribecalisboa', 'seguir @tribecalisboa')}</TertiaryButton>
          </a>
        </div>
        <div className="r-feed-grid lp-feed-grid ab-rev">
          {LP_FEED.map((p, i) => (
            <a className="r-feed-cell lp-feed-cell" key={i} href={p.url} target="_blank" rel="noopener noreferrer" onClick={(e) => openExt(e, p.url)} aria-label={`Instagram post ${i + 1}`}>
              <img src={R(p.img)} alt="" loading="lazy" />
            </a>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---- Footer → LandingChrome.jsx -----------------------------

// ---- App ----------------------------------------------------
function Landing() {
  const [lang] = useLang();
  const rootRef = useRefLP(null);
  useLpReveal(rootRef);
  return (
    <LangContext.Provider value={lang}>
      <div className="lp" ref={rootRef}>
        <LpHeader />
        <LpHero />
        <LpAbout />
        <LpOrigins />
        <LpLegacy />
        <LpImpact />
        <LpBridge />
        <LpClose />
        <LpOpenAir />
        <LpFeed />
        <LpFooter />
      </div>
    </LangContext.Provider>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<Landing />);
