// pages.jsx — HomePage, ProductsIndex, ProductDetail, AboutPage, QualityPage, ContactPage

// Pick a localized field on an object that uses suffixed keys (foo_pt/foo_en/foo_es).
// Falls back across all langs to handle ES items still missing translation, etc.
function pickLangField(obj, base, lang) {
  if (!obj) return '';
  return obj[`${base}_${lang}`] || obj[`${base}_pt`] || obj[`${base}_en`] || obj[`${base}_es`] || '';
}

// News posts store the primary language flat (title/summary/body) and optional
// translations as title_<lang>, etc. PT is the canonical/fallback.
function pickNewsField(post, base, lang) {
  if (!post) return '';
  const suffixed = post[`${base}_${lang}`];
  if (suffixed) return suffixed;
  if (lang === 'pt') return post[base] || '';
  // For en/es, prefer the suffixed field; fall back to base (PT canonical).
  return post[`${base}_${lang}`] || post[base] || '';
}

const toneFor = (slug) => ({
  'pead-irrigation': 'water',
  'rtp-oil-gas': 'oil',
  'mining-composite': 'mining',
  'pp-compression': 'pp',
}[slug] || 'water');

function HomePage({ t, go, lang, buildUrl }) {
  return (
    <div className="page-enter">
      {/* Hero */}
      <section className="hero">
        <div className="container">
          <div className="hero-grid">
            <div>
              <span className="eyebrow">{t.home.eyebrow}</span>
              <h1>
                {t.home.h1Pre}<em>{t.home.h1Em}</em>{t.home.h1Post}
              </h1>
              <p className="hero-lead">{t.home.lead}</p>
              <div className="hero-ctas">
                <button className="btn btn-primary btn-lg arrow" onClick={() => go('contact')}>{t.home.ctaPrimary}</button>
                <button className="btn btn-secondary btn-lg" onClick={() => go('products')}>{t.home.ctaSecondary}</button>
              </div>
            </div>
            <div className="hero-visual">
              <img
                src={t.home.heroImg || '/assets/hero.jpg'}
                alt="LESSO HDPE pipes and coils"
                onError={(e) => { e.currentTarget.src = placeholderImg('LESSO · INDUSTRIAL PIPING', 'warm'); }}
              />
              <div className="hero-badge">
                <span className="mono">{t.home.badgeLabel}</span>
                <strong>{t.home.badgeNum}</strong>
              </div>
            </div>
          </div>
          <div className="stats-band">
            {t.home.stats.map((s, i) => (
              <div key={i}>
                <div className="num">{s.num}</div>
                <div className="label">{s.label}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Sectors */}
      <section className="section-tight" style={{ background: 'var(--bg-2)' }}>
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.home.sectorsHead.eyebrow}</span>
              <h2>{t.home.sectorsHead.h2}</h2>
            </div>
            <p>{t.home.sectorsHead.p}</p>
          </div>
          <div className="sector-grid">
            {t.sectors.map((s, i) => (
              <div className="sector-card" key={i} onClick={() => go('products')}>
                <div className="icon">{s.ico}</div>
                <span className="num-tag">{s.num}</span>
                <h3>{s.t}</h3>
                <p>{s.d}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* About strip */}
      <section className="section">
        <div className="container">
          <div className="about-grid">
            <AboutBigCarousel
              imgs={Array.isArray(t.home.aboutBigImgs) ? t.home.aboutBigImgs : []}
              fallback={t.home.aboutBigImg || '/assets/manufacturing-base.jpg'}
            />
            <div>
              <span className="eyebrow">{t.home.aboutHead.eyebrow}</span>
              <h2 style={{ marginTop: 14 }}>{t.home.aboutHead.h2}</h2>
              <p>{t.home.aboutHead.p}</p>
              <div className="about-feat">
                <div>
                  <h4>{t.home.aboutHead.f1}</h4>
                  <p>{t.home.aboutHead.f1d}</p>
                </div>
                <div>
                  <h4>{t.home.aboutHead.f2}</h4>
                  <p>{t.home.aboutHead.f2d}</p>
                </div>
              </div>
              <div style={{ marginTop: 28 }}>
                <button className="btn btn-secondary arrow" onClick={() => go('about')}>{t.nav.about}</button>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* HIDDEN 2026-05-16: a galeria de 6 imagens ficava aqui, mas
          duplicava a função da seção LINHAS PRINCIPAIS abaixo (ambas
          eram entradas visuais para produtos). Removida da renderização
          mas o array `gallery` em content/home.json e o widget de admin
          permanecem — para reativar, basta descomentar este bloco. */}
      {false && Array.isArray(t.home.gallery) && t.home.gallery.length > 0 && (
        <section className="section-tight home-gallery-section">
          <div className="container">
            <div className="home-gallery">
              {t.home.gallery.slice(0, 6).map((g, i) => {
                const slug = g && typeof g === 'object' ? g.href : null;
                const href = slug && buildUrl ? buildUrl(lang, 'product', { slug }) : '#';
                const clickable = !!slug;
                const onClick = (e) => {
                  if (!clickable) { e.preventDefault(); return; }
                  if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return;
                  e.preventDefault();
                  go('product', { slug });
                };
                const inner = (
                  <img
                    src={(g && g.image) || placeholderImg(`PROD ${i + 1}`, 'water')}
                    alt=""
                    loading="eager"
                    decoding="async"
                    onError={(e) => { e.currentTarget.src = placeholderImg(`PROD ${i + 1}`, 'water'); }}
                  />
                );
                return clickable ? (
                  <a key={i} className="home-gallery-item" href={href} onClick={onClick} aria-label={`Produto ${i + 1}`}>
                    {inner}
                  </a>
                ) : (
                  <div key={i} className="home-gallery-item" aria-hidden="true">
                    {inner}
                  </div>
                );
              })}
            </div>
          </div>
        </section>
      )}

      {/* Products — moved BELOW the factory carousel per request 2026-05-15.
          Uses the same ProductCard grid (one-by-one cards, no carousel). */}
      <section className="section">
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.home.productsHead.eyebrow}</span>
              <h2>{t.home.productsHead.h2}</h2>
            </div>
            <div>
              <p>{t.home.productsHead.p}</p>
              <div style={{ marginTop: 20 }}>
                <button className="btn btn-secondary arrow" onClick={() => go('products')}>
                  {t.products.viewAllCatalog}
                </button>
              </div>
            </div>
          </div>
          {/* All product categories — sorted by `order` field in app.jsx
              (productList já vem ordenado de applyContent). Para reordenar,
              ajuste o campo `order` no JSON do produto via /admin/. */}
          <div className="product-grid">
            {(Array.isArray(t.productList) ? t.productList : []).map(p => (
              <ProductCard key={p.slug} product={p} go={go} tone={toneFor(p.slug)} t={t} lang={lang} buildUrl={buildUrl} />
            ))}
          </div>
        </div>
      </section>

      {/* Process */}
      <section className="section-tight">
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.home.processHead.eyebrow}</span>
              <h2>{t.home.processHead.h2}</h2>
            </div>
            <p></p>
          </div>
          <div className="process">
            {t.home.process.map((step, i) => (
              <div className="step" key={i}>
                <span className="num">{step.num}</span>
                <h4>{step.t}</h4>
                <p>{step.d}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Cert composite intentionally NOT rendered on Home — it lives only on
          the About page now. Editors should look at /sobre to verify cert
          changes. (Removed per customer request 2026-05-14.) */}

      <CTABand t={t} go={go} />
    </div>
  );
}

function AboutBigCarousel({ imgs, fallback }) {
  const slides = (Array.isArray(imgs) ? imgs : [])
    .map((it) => (it && typeof it === 'object' ? it.src : it))
    .filter((s) => typeof s === 'string' && s);

  if (slides.length < 2) {
    const single = slides[0] || fallback;
    return (
      <div className="imgwrap">
        <img
          src={single}
          alt="LESSO manufacturing — HDPE coils and pipes"
          loading="lazy"
          onError={(e) => { e.currentTarget.src = placeholderImg('MANUFACTURING BASE · FOSHAN', 'dark'); }}
        />
      </div>
    );
  }

  const [idx, setIdx] = useState(0);
  const [paused, setPaused] = useState(false);
  useEffect(() => {
    if (paused) return undefined;
    const t = setInterval(() => setIdx((i) => (i + 1) % slides.length), 4000);
    return () => clearInterval(t);
  }, [paused, slides.length]);

  const step = (delta) => setIdx((i) => (i + delta + slides.length) % slides.length);

  return (
    <div
      className="imgwrap carousel"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
    >
      {slides.map((src, i) => (
        <img
          key={i}
          src={src}
          alt="LESSO manufacturing — HDPE coils and pipes"
          loading={i === 0 ? 'eager' : 'lazy'}
          className={i === idx ? 'is-active' : ''}
          onError={(e) => { e.currentTarget.src = placeholderImg('MANUFACTURING BASE · FOSHAN', 'dark'); }}
        />
      ))}
      <button
        type="button"
        className="carousel-arrow carousel-arrow-prev"
        aria-label="Foto anterior"
        onClick={() => step(-1)}
      >
        <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
          <path d="M15 6l-6 6 6 6" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </button>
      <button
        type="button"
        className="carousel-arrow carousel-arrow-next"
        aria-label="Próxima foto"
        onClick={() => step(1)}
      >
        <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
          <path d="M9 6l6 6-6 6" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </button>
      <div className="carousel-dots" role="tablist" aria-label="Carrossel Por que LESSO">
        {slides.map((_, i) => (
          <button
            key={i}
            type="button"
            role="tab"
            aria-label={`Foto ${i + 1}`}
            aria-selected={i === idx}
            className={i === idx ? 'is-active' : ''}
            onClick={() => setIdx(i)}
          />
        ))}
      </div>
    </div>
  );
}

function ProductsIndex({ t, go, lang, buildUrl }) {
  const isEmpty = !Array.isArray(t.productList) || t.productList.length === 0;
  // Mobile/tablet collapses the series-filter bar by default — 14 chips
  // otherwise occupy the whole viewport (see trench log entry on filter
  // blocking content). Desktop ignores this state via CSS.
  const [filterOpen, setFilterOpen] = React.useState(false);
  // Card click → opens subproduct modal with full description + specs.
  // null = closed. When set, contains the same flattened subproduct
  // object that lives in subsBySeries[].items.
  const [openSub, setOpenSub] = React.useState(null);
  React.useEffect(() => {
    if (!openSub) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpenSub(null); };
    window.addEventListener('keydown', onKey);
    // Lock body scroll while modal is open
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [openSub]);

  // Junta TODOS os sub-produtos de TODAS as 10 séries para o catálogo completo
  // abaixo da grade principal. Cada sub-produto carrega o slug da série-pai
  // para o clique levar à página de detalhe correspondente (onde o cliente
  // pode ver o sub-produto destacado).
  const allSubs = [];
  if (Array.isArray(t.productList)) {
    for (const series of t.productList) {
      if (!Array.isArray(series.subproducts)) continue;
      series.subproducts.forEach((s, si) => {
        allSubs.push({
          parent_slug: series.slug,
          parent_name: series.name || series.short,
          parent_index: si + 1,
          ...s,
        });
      });
    }
  }
  // Agrupa por série, mantendo a ordem natural (a ordem em que vieram).
  const subsBySeries = [];
  const seenParent = new Map();
  for (const sp of allSubs) {
    if (!seenParent.has(sp.parent_slug)) {
      seenParent.set(sp.parent_slug, subsBySeries.length);
      subsBySeries.push({ slug: sp.parent_slug, label: sp.parent_name, items: [] });
    }
    subsBySeries[seenParent.get(sp.parent_slug)].items.push(sp);
  }

  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.products }]} go={go} lang={lang} buildUrl={buildUrl} />
          <h1>{t.products.pageH1}</h1>
          <p className="lead">{t.products.pageLead}</p>
        </div>
      </section>
      {/* Catálogo completo — 118 produtos extraídos do PDF, agrupados pelas
          10 séries. Cada cartão tem imagem vazia para o cliente subir a foto
          real pelo /admin/. Clicar em qualquer cartão leva à página de detalhe
          da série-pai (onde aparecem specs técnicos, FAQs, etc.). */}
      {allSubs.length === 0 ? (
        <section className="section">
          <div className="container">
            <p className="muted" style={{ padding: '32px 0', textAlign: 'center' }}>
              {(t.pd && t.pd.empty) || ({
                pt: 'Nenhum produto disponível no momento.',
                en: 'No products available at the moment.',
                es: 'Ningún producto disponible en este momento.',
              }[lang] || 'No products available at the moment.')}
            </p>
          </div>
        </section>
      ) : (
        <section className="section">
          <div className="container">
            <div className="sec-head">
              <div>
                <span className="eyebrow">{t.products.catalogEyebrow}</span>
                <h2>
                  {(t.products.catalogTitleTpl || '{n} · {s}')
                    .replace('{n}', allSubs.length)
                    .replace('{s}', subsBySeries.length)}
                </h2>
              </div>
              <p>{t.products.catalogLead}</p>
            </div>

            {/* Filtro por série — barra sticky abaixo do header. Clicar em
                qualquer chip rola suavemente até o grupo correspondente.
                No mobile/tablet (≤900px), os chips ficam atrás de um botão
                toggle para não cobrir a tela inteira; ver styles.css. */}
            <div className={`series-filter-bar${filterOpen ? ' is-open' : ''}`}>
              <span className="series-filter-label">{t.products.filterLabel}</span>
              <button
                type="button"
                className="series-filter-toggle"
                aria-expanded={filterOpen}
                aria-controls="series-filter-chips"
                onClick={() => setFilterOpen(v => !v)}
              >
                <span>{subsBySeries.length}</span>
                <span className="series-filter-caret" aria-hidden="true">▾</span>
              </button>
              <div id="series-filter-chips" className="series-filter-chips">
                {subsBySeries.map((g) => (
                  <button
                    key={g.slug}
                    type="button"
                    className="series-filter-chip"
                    onClick={() => {
                      const el = document.getElementById(`series-anchor-${g.slug}`);
                      if (el) {
                        const top = el.getBoundingClientRect().top + window.pageYOffset - 130;
                        window.scrollTo({ top, behavior: 'smooth' });
                      }
                      setFilterOpen(false);
                    }}
                  >
                    {g.label} <span className="series-filter-chip-count">({g.items.length})</span>
                  </button>
                ))}
              </div>
            </div>

            {subsBySeries.map((g) => (
              <div key={g.slug} id={`series-anchor-${g.slug}`} style={{ marginTop: 32, scrollMarginTop: 130 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 16, borderBottom: '1px solid #e6e4dc', paddingBottom: 8 }}>
                  <h3 style={{ margin: 0, fontSize: 18 }}>{g.label}</h3>
                  <a
                    href={buildUrl(lang, 'product', { slug: g.slug })}
                    onClick={(e) => { if (e.metaKey||e.ctrlKey||e.shiftKey||e.button===1) return; e.preventDefault(); go('product', { slug: g.slug }); }}
                    style={{ fontSize: 13, color: 'var(--accent, #c24a1d)', textDecoration: 'none', fontWeight: 600 }}
                  >
                    {(t.products.viewSeriesTpl || 'View full series ({n} products) →').replace('{n}', g.items.length)}
                  </a>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 16 }}>
                  {g.items.map((s, i) => {
                    const name = pickLangField(s, 'name', lang);
                    const shortDesc = pickLangField(s, 'short_desc', lang) || '';
                    // Outer card is a div with role=button instead of <button>
                    // because it contains InquiryAddButton (a real <button>)
                    // and nested buttons are an HTML/A11y DOM violation
                    // (browser logs validateDOMNesting). The role + tabIndex +
                    // keyboard handlers preserve keyboard/screen-reader access.
                    const openSubFor = () => setOpenSub(s);
                    return (
                      <div
                        key={i}
                        role="button"
                        tabIndex={0}
                        onClick={openSubFor}
                        onKeyDown={(e) => {
                          if (e.key === 'Enter' || e.key === ' ') {
                            e.preventDefault();
                            openSubFor();
                          }
                        }}
                        aria-label={name}
                        style={{ border: '1px solid #e6e4dc', borderRadius: 8, overflow: 'hidden', background: '#fff', display: 'flex', flexDirection: 'column', textAlign: 'left', cursor: 'pointer', padding: 0, font: 'inherit', color: 'inherit', transition: 'transform 0.15s, box-shadow 0.15s' }}
                        onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = '0 6px 20px rgba(0,0,0,0.08)'; }}
                        onMouseLeave={(e) => { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = ''; }}
                      >
                        <div style={{ position: 'relative', aspectRatio: '4 / 3', background: '#f4f2eb', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
                          {s.image ? (
                            <img
                              src={s.image}
                              alt={name}
                              loading="lazy"
                              style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                              onError={(e) => { e.currentTarget.style.display = 'none'; }}
                            />
                          ) : (
                            <div style={{ textAlign: 'center', padding: 12, color: '#9ea09a' }}>
                              <div style={{ fontSize: 11, letterSpacing: 1.5, fontWeight: 600, textTransform: 'uppercase' }}>
                                {t.pd.noPhoto}
                              </div>
                              <div style={{ fontSize: 10, marginTop: 4, fontFamily: 'ui-monospace, Menlo, monospace' }}>
                                #{i + 1}{s.pdf_page ? ` · PDF p.${s.pdf_page}` : ''}
                              </div>
                            </div>
                          )}
                          <InquiryAddButton
                            itemKey={'sub:' + s.parent_slug + ':' + s.parent_index}
                            label={s.parent_name + ' — ' + name}
                            image={s.image || ''}
                            url={buildUrl ? buildUrl(lang, 'product', { slug: s.parent_slug }) : '#'}
                            variant="corner"
                            t={t}
                          />
                        </div>
                        <div style={{ padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 8, flex: 1 }}>
                          <h4 style={{ margin: 0, fontSize: 14, lineHeight: 1.3, fontWeight: 600 }}>{name}</h4>
                          {shortDesc && (
                            <p style={{ margin: 0, fontSize: 12, color: '#6a6b65', lineHeight: 1.4, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
                              {shortDesc}
                            </p>
                          )}
                          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 'auto' }}>
                            {s.diameter && <span className="spec-chip" style={{ fontSize: 11 }}>{s.diameter}</span>}
                            {s.pressure && <span className="spec-chip" style={{ fontSize: 11 }}>{s.pressure}</span>}
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </section>
      )}

      {openSub && (() => {
        const oName = pickLangField(openSub, 'name', lang);
        const oDesc = pickLangField(openSub, 'short_desc', lang) || '';
        return (
          <div
            className="sub-modal is-open"
            role="dialog"
            aria-modal="true"
            aria-label={oName}
            onClick={(e) => { if (e.target === e.currentTarget) setOpenSub(null); }}
          >
            <div className="sub-modal__panel" onClick={(e) => e.stopPropagation()}>
              <button
                type="button"
                className="sub-modal__close"
                aria-label={(t.products && t.products.modalCloseAria) || 'Close'}
                onClick={() => setOpenSub(null)}
              >×</button>
              <div className="sub-modal__image">
                {openSub.image ? (
                  <img src={openSub.image} alt={oName} onError={(e) => { e.currentTarget.style.display = 'none'; }} />
                ) : (
                  <div className="sub-modal__placeholder">
                    <div className="mono-label">{t.pd.noPhoto}</div>
                    <div className="sub-modal__placeholder-ref">
                      #{openSub.parent_index}{openSub.pdf_page ? ` · PDF p.${openSub.pdf_page}` : ''}
                    </div>
                  </div>
                )}
              </div>
              <div className="sub-modal__body">
                <span className="eyebrow sub-modal__series">
                  {(t.products && t.products.modalSeriesEyebrow) || 'PART OF SERIES'} · {openSub.parent_name}
                </span>
                <h2 className="sub-modal__name">{oName}</h2>
                <p className="sub-modal__desc">{oDesc || ((t.products && t.products.modalNoDesc) || 'No description available.')}</p>
                <div className="sub-modal__specs">
                  {openSub.diameter && <span className="spec-chip">{openSub.diameter}</span>}
                  {openSub.pressure && <span className="spec-chip">{openSub.pressure}</span>}
                </div>
                {openSub.standards && (
                  <p className="sub-modal__standards">{openSub.standards}</p>
                )}
                {openSub.pdf_page && (
                  <small className="sub-modal__ref">#{openSub.parent_index} · PDF p.{openSub.pdf_page}</small>
                )}
                <div className="sub-modal__actions">
                  <InquiryAddButton
                    itemKey={'sub:' + openSub.parent_slug + ':' + openSub.parent_index}
                    label={openSub.parent_name + ' — ' + oName}
                    image={openSub.image || ''}
                    url={buildUrl ? buildUrl(lang, 'product', { slug: openSub.parent_slug }) : '#'}
                    variant="row"
                    t={t}
                  />
                  <a
                    className="btn btn-primary sub-modal__cta"
                    href={buildUrl(lang, 'product', { slug: openSub.parent_slug })}
                    onClick={(e) => { if (e.metaKey||e.ctrlKey||e.shiftKey||e.button===1) return; e.preventDefault(); go('product', { slug: openSub.parent_slug }); setOpenSub(null); }}
                  >
                    {(t.products && t.products.modalViewSeriesCta) || 'View full series →'}
                  </a>
                </div>
              </div>
            </div>
          </div>
        );
      })()}

      <CTABand t={t} go={go} />
    </div>
  );
}

function ProductDetail({ t, go, slug, lang, buildUrl }) {
  const p = t.productList.find(x => x.slug === slug);
  if (!p) return <NotFoundPage t={t} go={go} lang={lang} buildUrl={buildUrl} />;
  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[
            { label: t.nav.home, to: 'home' },
            { label: t.nav.products, to: 'products' },
            { label: p.short }
          ]} go={go} lang={lang} buildUrl={buildUrl} />
          <span className="eyebrow">{p.tag}</span>
          <h1 style={{ marginTop: 16 }}>{p.name}</h1>
          <p className="lead">{p.desc}</p>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div className="pd-grid">
            <div>
              <div className="pd-hero-img">
                <img
                  src={p.image || placeholderImg(p.short.toUpperCase(), toneFor(p.slug))}
                  alt={p.name}
                  onError={(e) => { e.currentTarget.src = placeholderImg(p.short.toUpperCase(), toneFor(p.slug)); }}
                />
              </div>

              {Array.isArray(p.gallery) && p.gallery.length > 0 && (
                <div className="pd-gallery">
                  {p.gallery.map((src, i) => (
                    <div className="pd-gallery-cell" key={i}>
                      <img
                        src={src}
                        alt={`${p.short} ${i + 2}`}
                        loading="lazy"
                        onError={(e) => { e.currentTarget.src = placeholderImg(p.short.toUpperCase(), toneFor(p.slug)); }}
                      />
                    </div>
                  ))}
                </div>
              )}

              <div className="pd-answer">
                <h3>{p.answerT}</h3>
                <p>{p.answerP}</p>
              </div>

              <div className="pd-block">
                <span className="mono-label">{t.pd.benefitsLabel}</span>
                <h2>{t.pd.benefitsH}</h2>
                <ul className="check-list">
                  {p.benefits.map((b, i) => <li key={i}>{b}</li>)}
                </ul>
              </div>

              <div className="pd-block">
                <span className="mono-label">{t.pd.applicationsLabel}</span>
                <h2>{t.pd.applicationsH}</h2>
                <ul className="check-list">
                  {p.applications.map((a, i) => <li key={i}>{a}</li>)}
                </ul>
              </div>

              <div className="pd-block">
                <span className="mono-label">{t.pd.specsLabel}</span>
                <h2>{t.pd.specsH}</h2>
                {p.materialSpec && (
                  <div className="material-card">
                    <div className="material-row">
                      <span className="material-label">{t.pd.materialLabel || 'Material'}</span>
                      <span className="material-value">{p.materialSpec.material}</span>
                    </div>
                    <div className="material-row">
                      <span className="material-label">{t.pd.gradeLabel || 'Grade'}</span>
                      <span className="material-value mono">{p.materialSpec.grade}</span>
                    </div>
                    <div className="material-row">
                      <span className="material-label">{t.pd.normLabel || 'Standard'}</span>
                      <span className="material-value mono">{p.materialSpec.standard}</span>
                    </div>
                    <div className="material-row">
                      <span className="material-label">{t.pd.colorLabel || 'Color'}</span>
                      <span className="material-value">{p.materialSpec.color}</span>
                    </div>
                  </div>
                )}
                <table className="spec-table">
                  <thead>
                    <tr>{p.specCols.map((c, i) => <th key={i}>{c}</th>)}</tr>
                  </thead>
                  <tbody>
                    {p.specRows.map((r, i) => (
                      <tr key={i}>{r.map((cell, j) => <td key={j} className={j > 0 ? 'mono' : ''}>{cell}</td>)}</tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="pd-block">
                <span className="mono-label">{t.pd.standardsLabel}</span>
                <h2>{t.pd.standardsH}</h2>
                <div className="standards-row">
                  {p.standards.map((s, i) => <span className="spec-chip" key={i}>{s}</span>)}
                </div>
              </div>

              {Array.isArray(p.subproducts) && p.subproducts.length > 0 && (
                <div className="pd-block">
                  <span className="mono-label">{t.pd.subproductsLabel}</span>
                  <h2>{t.pd.subproductsH}</h2>
                  <p style={{ color: '#6a6b65', marginTop: -8, marginBottom: 16, fontSize: '0.95em' }}>
                    {(t.pd.subproductsHintTpl || '').replace('{n}', p.subproducts.length)}
                  </p>
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 16 }}>
                    {p.subproducts.map((s, i) => {
                      const name = pickLangField(s, 'name', lang);
                      const shortDesc = pickLangField(s, 'short_desc', lang) || '';
                      // Clique → leva ao formulário de orçamento com o nome do
                      // sub-produto pré-preenchido (assim o vendedor sabe
                      // exatamente qual variante o cliente quer cotar).
                      const inquirySlug = `${p.slug}__${i + 1}__${name}`;
                      const quoteHref = buildUrl(lang, 'contact', { product: inquirySlug });
                      const openQuote = () => go('contact', { product: inquirySlug });
                      return (
                        <div
                          key={i}
                          role="link"
                          tabIndex={0}
                          data-href={quoteHref}
                          onClick={(e) => {
                            if (e.defaultPrevented) return;
                            if (e.metaKey||e.ctrlKey||e.shiftKey||e.button===1) {
                              window.open(quoteHref, '_blank', 'noopener');
                              return;
                            }
                            openQuote();
                          }}
                          onKeyDown={(e) => {
                            if (e.key === 'Enter' || e.key === ' ') {
                              e.preventDefault();
                              openQuote();
                            }
                          }}
                          aria-label={({ pt: 'Solicitar cotação — ', en: 'Request quote — ', es: 'Solicitar cotización — ' }[lang] || 'Request quote — ') + name}
                          style={{ border: '1px solid #e6e4dc', borderRadius: 8, overflow: 'hidden', background: '#fff', display: 'flex', flexDirection: 'column', textDecoration: 'none', color: 'inherit', transition: 'transform 0.15s, box-shadow 0.15s', cursor: 'pointer' }}
                          onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = '0 6px 20px rgba(0,0,0,0.08)'; }}
                          onMouseLeave={(e) => { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = ''; }}
                        >
                          <div style={{ aspectRatio: '4 / 3', background: '#f4f2eb', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', overflow: 'hidden' }}>
                            {s.image ? (
                              <img
                                src={s.image}
                                alt={name}
                                loading="lazy"
                                style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                                onError={(e) => { e.currentTarget.style.display = 'none'; }}
                              />
                            ) : (
                              <div style={{ textAlign: 'center', padding: 12, color: '#9ea09a' }}>
                                <div style={{ fontSize: 11, letterSpacing: 1.5, fontWeight: 600, textTransform: 'uppercase' }}>
                                  {t.pd.noPhoto}
                                </div>
                                <div style={{ fontSize: 10, marginTop: 4, fontFamily: 'ui-monospace, Menlo, monospace' }}>
                                  #{i + 1}{s.pdf_page ? ` · PDF p.${s.pdf_page}` : ''}
                                </div>
                              </div>
                            )}
                          </div>
                          <div style={{ padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 8, flex: 1 }}>
                            <h4 style={{ margin: 0, fontSize: 15, lineHeight: 1.3, fontWeight: 600 }}>{name}</h4>
                            {shortDesc && (
                              <p style={{ margin: 0, fontSize: 13, color: '#6a6b65', lineHeight: 1.4, display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
                                {shortDesc}
                              </p>
                            )}
                            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 'auto' }}>
                              {s.diameter && <span className="spec-chip" style={{ fontSize: 11 }}>{s.diameter}</span>}
                              {s.pressure && <span className="spec-chip" style={{ fontSize: 11 }}>{s.pressure}</span>}
                            </div>
                            {s.standards && (
                              <small style={{ fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 10, color: '#9ea09a', borderTop: '1px solid #f0eee5', paddingTop: 8 }}>
                                {s.standards}
                              </small>
                            )}
                            <span style={{ fontSize: 11, color: 'var(--accent, #c24a1d)', fontWeight: 600, marginTop: 2 }}>
                              {t.pd.subproductCTA}
                            </span>
                            <InquiryAddButton
                              itemKey={'sub:' + p.slug + ':' + (i + 1)}
                              label={(p.name || p.tag || p.slug) + ' — ' + (s.name_pt || s.name_en || s.name_es || ('#' + (i + 1)))}
                              image={s.image || p.image || ''}
                              url={buildUrl ? buildUrl(lang, 'product', { slug: p.slug }) : '#'}
                              variant="row"
                              t={t}
                            />
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}

              <div className="pd-block">
                <span className="mono-label">{t.pd.faqLabel}</span>
                <h2>{t.pd.faqH}</h2>
                <div className="faq-list">
                  {p.faqs.map((f, i) => <FAQItem key={i} q={f.q} a={f.a} />)}
                </div>
              </div>
            </div>

            <aside>
              <div className="pd-side">
                <span className="mono">{t.pd.sideEyebrow}</span>
                <h3>{t.pd.sideH}</h3>
                <p>{t.pd.sideP}</p>
                <button className="btn btn-primary arrow" onClick={() => go('contact', { product: p.slug })}>
                  {t.home.ctaPrimary}
                </button>
                {p.pdf_url && (
                  <a className="btn btn-secondary" href={p.pdf_url} target="_blank" rel="noopener">
                    {t.pd.downloadPdf}
                  </a>
                )}
                <button className="btn btn-secondary" onClick={() => go('quality')}>
                  {t.pd.viewDatasheets}
                </button>
                <div className="downloads">
                  <h4>{t.pd.relatedDownloads}</h4>
                  {DOWNLOADS.filter(d => d.slug.startsWith(p.slug.split('-')[0]) || p.slug.startsWith(d.slug)).slice(0, 3).map(d => {
                    const href = d.pdf_url_external || d.pdf_url;
                    const ready = !!href;
                    const label = pickLangField(d, 'title', t.locale) || d.title_pt || d.title_en;
                    if (ready) {
                      return (
                        <a className="dl-link" key={d.slug} href={href} target="_blank" rel="noopener">
                          <span className="pdfpill">PDF</span>
                          <span>{label}</span>
                        </a>
                      );
                    }
                    return (
                      <span className="dl-link" key={d.slug} style={{ opacity: 0.5, cursor: 'not-allowed' }} title={t.locale === 'pt' ? 'Em breve' : t.locale === 'es' ? 'Próximamente' : 'Coming soon'}>
                        <span className="pdfpill">PDF</span>
                        <span>{label}</span>
                      </span>
                    );
                  })}
                </div>
              </div>
            </aside>
          </div>
        </div>
      </section>

      <CTABand t={t} go={go} />
    </div>
  );
}

// Video player card — a large poster + centred red YouTube play button.
// Used on the About page to embed an institutional video link without
// pulling in the YouTube iframe (kept lightweight: just a single anchor
// that opens YouTube in a new tab on click). Reads from t.about.video
// = { url, title, poster }. Hidden if no url is set.
//
// Poster fallback chain:
//   1. editor upload (v.poster)
//   2. YouTube auto-thumbnails — maxresdefault → sddefault → hqdefault
//      (high-quality variants degrade individually if missing on YouTube)
//   3. HQ building photo (about.aboutHqImg) — only if all YouTube
//      thumbnails fail (very rare; happens for unlisted/private videos)
//   4. bundled hero.jpg
function extractYouTubeId(url) {
  if (typeof url !== 'string') return '';
  const patterns = [
    /youtu\.be\/([A-Za-z0-9_-]{11})/,
    /youtube\.com\/watch\?[^#]*\bv=([A-Za-z0-9_-]{11})/,
    /youtube\.com\/embed\/([A-Za-z0-9_-]{11})/,
    /youtube\.com\/shorts\/([A-Za-z0-9_-]{11})/,
  ];
  for (const re of patterns) {
    const m = url.match(re);
    if (m) return m[1];
  }
  return '';
}
function VideoPlayerCard({ t }) {
  const v = (t.about && t.about.video) || {};
  if (!/^https?:\/\//.test(v.url || '')) return null;
  const ytId = extractYouTubeId(v.url);
  const ytThumbs = ytId ? [
    `https://img.youtube.com/vi/${ytId}/maxresdefault.jpg`,
    `https://img.youtube.com/vi/${ytId}/sddefault.jpg`,
    `https://img.youtube.com/vi/${ytId}/hqdefault.jpg`,
  ] : [];
  const chain = [v.poster, ...ytThumbs, t.about && t.about.aboutHqImg, '/assets/hero.jpg'].filter(Boolean);
  const [posterIdx, setPosterIdx] = useState(0);
  const poster = chain[posterIdx] || '/assets/hero.jpg';
  const cta = (t.locale === 'pt' ? 'Assistir no YouTube' : t.locale === 'es' ? 'Ver en YouTube' : 'Watch on YouTube');
  return (
    <section className="section-tight">
      <div className="container">
        <a className="video-card" href={v.url} target="_blank" rel="noopener noreferrer" aria-label={cta + ' — ' + (v.title || 'LESSO')}>
          <div className="video-card-poster">
            <img
              className="video-card-poster-img"
              src={poster}
              alt=""
              loading="lazy"
              onError={() => { if (posterIdx < chain.length - 1) setPosterIdx(posterIdx + 1); }}
            />
            <div className="video-card-overlay" />
            <span className="video-card-play" aria-hidden="true">
              <svg viewBox="0 0 68 48" width="80" height="56">
                <path d="M66.5,7.7c0,0-0.7-4.6-2.6-6.6c-2.5-2.6-5.3-2.6-6.6-2.8C48.1,0,34,0,34,0S19.9,0,11.7,0.4 c-1.3,0.1-4.1,0.2-6.6,2.8C3.2,5.2,2.5,9.8,2.5,9.8S1.8,15.2,1.8,20.7v5.1c0,5.4,0.7,10.9,0.7,10.9s0.7,4.6,2.6,6.6 c2.5,2.6,5.7,2.6,7.2,2.8c5.2,0.5,22.4,0.6,22.4,0.6s14.1,0,22.3-0.4c1.3-0.2,4.1-0.2,6.6-2.8c1.9-2,2.6-6.6,2.6-6.6s0.7-5.4,0.7-10.9v-5.1C67.1,15.2,66.5,7.7,66.5,7.7z" fill="#FF0000"/>
                <polygon points="27,14 27,34 45,24" fill="#fff"/>
              </svg>
            </span>
          </div>
          <div className="video-card-meta">
            <h3>{v.title || (t.locale === 'pt' ? 'Conheça a LESSO em vídeo' : t.locale === 'es' ? 'Conozca LESSO en vídeo' : 'Watch LESSO in action')}</h3>
            <span className="video-card-cta">{cta} →</span>
          </div>
        </a>
      </div>
    </section>
  );
}

function AboutPage({ t, go, lang, buildUrl }) {
  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.about }]} go={go} lang={lang} buildUrl={buildUrl} />
          <h1>{t.about.pageH1}</h1>
          <p className="lead">{t.about.pageLead}</p>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div className="about-grid">
            <div>
              <h2>{t.about.storyH}</h2>
              <p>{t.about.storyP}</p>
              <div className="about-feat">
                <div>
                  <h4>{t.about.rdH}</h4>
                  <p>{t.about.rdP}</p>
                </div>
                <div>
                  <h4>{t.about.mfgH}</h4>
                  <p>{t.about.mfgP}</p>
                </div>
              </div>
            </div>
            <div className="imgwrap">
              <img
                src={t.about.aboutHqImg || '/assets/about-hq.jpg'}
                alt="LESSO Headquarters — Foshan, China"
                loading="lazy"
                onError={(e) => { e.currentTarget.src = placeholderImg('HQ · FOSHAN, CHINA', 'dark'); }}
              />
            </div>
          </div>

          <div className="stats-band">
            {t.home.stats.map((s, i) => (
              <div key={i}>
                <div className="num">{s.num}</div>
                <div className="label">{s.label}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      <VideoPlayerCard t={t} />

      <section className="section-tight" style={{ background: 'var(--bg-2)' }}>
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.about.globalHead.eyebrow}</span>
              <h2>{t.about.globalHead.h2}</h2>
            </div>
            <p>{t.about.globalHead.p}</p>
          </div>
          <div className="global-grid">
            {t.about.regions.map((r, i) => (
              <div className="region-card" key={i}>
                <span className="mono">{r.code}</span>
                <h4>{r.t}</h4>
                <p>{r.d}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      <MajorProjectsSection t={t} />

      <CertsSection t={t} />

      <CTABand t={t} go={go} />
    </div>
  );
}

function MajorProjectsSection({ t }) {
  const head = (t.about && t.about.projectsHead) || null;
  if (!head) return null;
  const projects = Array.isArray(t.about.projects) ? t.about.projects : [];
  const hasStructuredProjects = projects.length > 0;
  const tileClasses = [
    'is-tall',
    'is-wide',
    'is-wide',
    '',
    'is-wide',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
  ];

  return (
    <section className="section about-projects">
      <div className="container">
        <div className="about-projects__intro">
          <div>
            <span className="eyebrow">{head.eyebrow}</span>
            <h2>{head.h2}</h2>
          </div>
          <p>{head.p}</p>
        </div>

        {hasStructuredProjects ? (
          <div className="about-projects__mosaic" aria-label={head.imgAlt || head.h2}>
            {projects.map((project, i) => (
              <article
                key={`${project.title || 'project'}-${i}`}
                className={`about-projects__item ${tileClasses[i % tileClasses.length]}`.trim()}
              >
                <div className="about-projects__photo">
                  <img
                    src={project.image || placeholderImg(project.title || 'LESSO', 'dark')}
                    alt=""
                    loading="lazy"
                    onError={(e) => { e.currentTarget.src = placeholderImg(project.title || 'LESSO', 'dark'); }}
                  />
                </div>
                <div className="about-projects__caption">
                  <span aria-hidden="true" />
                  <p>{project.title}</p>
                </div>
              </article>
            ))}
          </div>
        ) : (
          <figure className="about-projects__figure">
            <img
              src={t.about.projectsImg || '/assets/uploads/projetos-grande-porte.png'}
              alt={head.imgAlt || 'LESSO projects'}
              loading="lazy"
              onError={(e) => { e.currentTarget.style.display = 'none'; }}
            />
          </figure>
        )}
      </div>
    </section>
  );
}

function CertsSection({ t }) {
  const img = t.about && t.about.certsImage;
  const head = (t.about && t.about.certHead) || {};
  const hasImg = typeof img === 'string' && img.trim() !== '';
  const certs = Array.isArray(t.about && t.about.certs) ? t.about.certs : [];
  if (!hasImg && certs.length === 0) return null;
  return (
    <section className="section">
      <div className="container">
        <div className="sec-head">
          <div>
            <span className="eyebrow">{head.eyebrow}</span>
            <h2>{head.h2}</h2>
          </div>
          <p>{head.p}</p>
        </div>
        {hasImg ? (
          <div className="certs-image">
            <img src={img} alt="Certificações LESSO" loading="lazy" />
          </div>
        ) : (
          <div className="logo-wall">
            {certs.map((c, i) => {
              const isObj = c && typeof c === 'object';
              const label = isObj ? c.label : c;
              const image = isObj ? c.image : '';
              return (
                <div className="cell" key={i} title={label}>
                  {image ? <img src={image} alt={label} loading="lazy" /> : label}
                </div>
              );
            })}
          </div>
        )}
      </div>
    </section>
  );
}

const DOWNLOAD_LEAD_FALLBACK = {
  pt: {
    eyebrow: 'ACESSO AOS CATÁLOGOS',
    title: 'Receba o catálogo pelo WhatsApp',
    lead: 'Preencha seus dados e escolha o material de interesse. A mensagem será enviada para o WhatsApp da equipe LESSO.',
    company: 'Empresa',
    name: 'Nome',
    contact: 'E-mail corporativo ou WhatsApp',
    contactHint: 'Use e-mail corporativo ou número de WhatsApp com DDI.',
    product: 'Produto / catálogo de interesse',
    productPlaceholder: 'Selecione um produto',
    notes: 'Observações',
    notesPlaceholder: 'Produto, aplicação, quantidade ou dúvidas específicas.',
    submit: 'Enviar no WhatsApp',
    selectThis: 'Solicitar este catálogo',
    required: 'Preencha este campo.',
    noWhatsApp: 'WhatsApp de atendimento não configurado.',
    waGreeting: 'Olá LESSO!',
    waIntro: 'Gostaria de receber este material e falar com a equipe comercial:',
    waClosing: 'Aguardo retorno. Obrigado.',
    pdfLink: 'Link do material',
    note: 'Seus dados serão enviados apenas para o WhatsApp comercial LESSO.',
  },
  en: {
    eyebrow: 'CATALOG ACCESS',
    title: 'Request the catalog on WhatsApp',
    lead: 'Fill in your details and choose the material you need. The message will be sent to the LESSO team on WhatsApp.',
    company: 'Company',
    name: 'Name',
    contact: 'Corporate email or WhatsApp',
    contactHint: 'Use a business email or WhatsApp number with country code.',
    product: 'Product / catalog of interest',
    productPlaceholder: 'Select a product',
    notes: 'Notes',
    notesPlaceholder: 'Product, application, quantity, or specific questions.',
    submit: 'Request Download',
    selectThis: 'Request this catalog',
    required: 'Please fill this field.',
    noWhatsApp: 'Sales WhatsApp is not configured.',
    waGreeting: 'Hi LESSO!',
    waIntro: 'I would like to receive this material and talk with the sales team:',
    waClosing: 'Looking forward to hearing back. Thanks.',
    pdfLink: 'Material link',
    note: 'Your details will only be sent to LESSO sales WhatsApp.',
  },
  es: {
    eyebrow: 'ACCESO A CATÁLOGOS',
    title: 'Solicite el catálogo por WhatsApp',
    lead: 'Complete sus datos y elija el material de interés. El mensaje se enviará al WhatsApp del equipo LESSO.',
    company: 'Empresa',
    name: 'Nombre',
    contact: 'Correo corporativo o WhatsApp',
    contactHint: 'Use correo corporativo o número de WhatsApp con código de país.',
    product: 'Producto / catálogo de interés',
    productPlaceholder: 'Seleccione un producto',
    notes: 'Observaciones',
    notesPlaceholder: 'Producto, aplicación, cantidad o dudas específicas.',
    submit: 'Enviar por WhatsApp',
    selectThis: 'Solicitar este catálogo',
    required: 'Complete este campo.',
    noWhatsApp: 'WhatsApp comercial no configurado.',
    waGreeting: '¡Hola LESSO!',
    waIntro: 'Me gustaría recibir este material y hablar con el equipo comercial:',
    waClosing: 'Quedo a la espera. Gracias.',
    pdfLink: 'Link del material',
    note: 'Sus datos se enviarán solo al WhatsApp comercial de LESSO.',
  },
};

function getDownloadLeadCopy(t) {
  const locale = (t && t.locale) || 'en';
  return {
    ...(DOWNLOAD_LEAD_FALLBACK[locale] || DOWNLOAD_LEAD_FALLBACK.en),
    ...((t && t.downloadLeadForm) || {}),
  };
}

function getConfiguredWhatsAppDigits() {
  const contact = (typeof window !== 'undefined' && window.CONTACT) || {};
  const socialLink = contact.social && contact.social.whatsappLink;
  const raw = contact.whatsapp || socialLink || '';
  const linkMatch = String(raw).match(/wa\.me\/([0-9]+)/i);
  return linkMatch ? linkMatch[1] : String(raw).replace(/\D/g, '');
}

function QualityPage({ t, go, lang, buildUrl }) {
  // Free-form category filter — derives the chip list from whatever editors
  // typed into `cat` on each download. No strict-match against ui-labels.dlCats
  // anymore. The cat string from the entry IS the display label.
  const ALL_KEY = '__all__';
  const [activeCat, setActiveCat] = useState(ALL_KEY);
  const cats = [];
  const counts = { [ALL_KEY]: 0 };
  for (const d of DOWNLOADS) {
    counts[ALL_KEY] += 1;
    const c = (d && d.cat ? String(d.cat).trim() : '') || (t.locale === 'pt' ? 'OUTROS' : t.locale === 'es' ? 'OTROS' : 'OTHER');
    if (!counts[c]) {
      counts[c] = 0;
      cats.push(c);
    }
    counts[c] += 1;
  }
  const visible = activeCat === ALL_KEY
    ? DOWNLOADS
    : DOWNLOADS.filter(d => ((d && d.cat ? String(d.cat).trim() : '') || (t.locale === 'pt' ? 'OUTROS' : t.locale === 'es' ? 'OTROS' : 'OTHER')) === activeCat);
  const allLabel = t.locale === 'pt' ? 'Todos' : t.locale === 'es' ? 'Todos' : 'All';
  const dlForm = getDownloadLeadCopy(t);
  const downloadLeadFirstFieldRef = useRef(null);
  const downloadOptions = DOWNLOADS.map((d, i) => {
    const title = pickLangField(d, 'title', t.locale) || d.title_pt || d.title_en || '';
    return {
      key: `${d.slug || 'pdf'}-${i}`,
      title,
      href: d.pdf_url_external || d.pdf_url || '',
    };
  }).filter(item => item.title);
  const [downloadLead, setDownloadLead] = useState({
    company: '',
    name: '',
    contact: '',
    product: '',
    notes: '',
  });
  const [downloadLeadOpen, setDownloadLeadOpen] = useState(false);
  const [downloadLeadErrors, setDownloadLeadErrors] = useState({});
  const setDownloadLeadField = (key, value) => {
    setDownloadLead(form => ({ ...form, [key]: value }));
    setDownloadLeadErrors(prev => {
      if (!prev[key] && !prev._global) return prev;
      const next = { ...prev };
      delete next[key];
      delete next._global;
      return next;
    });
  };
  const openDownloadLeadModal = (title) => {
    setDownloadLead(form => ({ ...form, product: title || form.product }));
    setDownloadLeadErrors({});
    setDownloadLeadOpen(true);
  };
  useEffect(() => {
    if (!downloadLeadOpen) return undefined;
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const focusTimer = setTimeout(() => {
      if (downloadLeadFirstFieldRef.current) downloadLeadFirstFieldRef.current.focus();
    }, 0);
    const onKey = (e) => { if (e.key === 'Escape') setDownloadLeadOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => {
      clearTimeout(focusTimer);
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [downloadLeadOpen]);
  const submitDownloadLead = (ev) => {
    ev.preventDefault();
    const errors = {};
    if (!downloadLead.company.trim()) errors.company = dlForm.required;
    if (!downloadLead.name.trim()) errors.name = dlForm.required;
    if (!downloadLead.contact.trim()) errors.contact = dlForm.required;
    if (!downloadLead.product.trim()) errors.product = dlForm.required;
    if (Object.keys(errors).length) {
      setDownloadLeadErrors(errors);
      return;
    }

    const number = getConfiguredWhatsAppDigits();
    if (number.length < 8) {
      setDownloadLeadErrors({ _global: dlForm.noWhatsApp });
      return;
    }

    const selected = downloadOptions.find(item => item.title === downloadLead.product);
    const lines = [
      dlForm.waGreeting,
      '',
      dlForm.waIntro,
      `${dlForm.company}: ${downloadLead.company.trim()}`,
      `${dlForm.name}: ${downloadLead.name.trim()}`,
      `${dlForm.contact}: ${downloadLead.contact.trim()}`,
      `${dlForm.product}: ${downloadLead.product.trim()}`,
    ];
    if (selected && selected.href) lines.push(`${dlForm.pdfLink}: ${selected.href}`);
    if (downloadLead.notes.trim()) {
      lines.push('', `${dlForm.notes}:`, downloadLead.notes.trim());
    }
    lines.push('', dlForm.waClosing);
    const waUrl = `https://wa.me/${number}?text=${encodeURIComponent(lines.join('\n'))}`;
    const opened = window.open(waUrl, '_blank', 'noopener,noreferrer');
    if (!opened) window.location.href = waUrl;
  };

  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.quality }]} go={go} lang={lang} buildUrl={buildUrl} />
          <h1>{t.quality.pageH1}</h1>
          <p className="lead">{t.quality.pageLead}</p>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.quality.downloadsHead.eyebrow}</span>
              <h2>{t.quality.downloadsHead.h2}</h2>
            </div>
            <p>{t.quality.downloadsHead.p}</p>
          </div>

          {/* Category filter chips — auto-built from `cat` values in downloads.json.
              Clicking a chip filters the grid below. */}
          {cats.length > 1 && (
            <div className="dl-cat-nav" role="tablist" aria-label={t.locale === 'pt' ? 'Filtro por categoria' : t.locale === 'es' ? 'Filtro por categoría' : 'Filter by category'}>
              <button
                type="button"
                className={`dl-chip${activeCat === ALL_KEY ? ' is-active' : ''}`}
                onClick={() => setActiveCat(ALL_KEY)}
                role="tab"
                aria-selected={activeCat === ALL_KEY}
              >
                {allLabel} <span className="count">{counts[ALL_KEY]}</span>
              </button>
              {cats.map(c => (
                <button
                  key={c}
                  type="button"
                  className={`dl-chip${activeCat === c ? ' is-active' : ''}`}
                  onClick={() => setActiveCat(c)}
                  role="tab"
                  aria-selected={activeCat === c}
                >
                  {/* Translate the raw cat (PT in JSON) via t.dlCats lookup
                      so EN/ES pages don't show Portuguese chip labels.
                      Filter logic still keys on the raw cat string. */}
                  {(t.dlCats && t.dlCats[c]) || c} <span className="count">{counts[c]}</span>
                </button>
              ))}
            </div>
          )}

          <div className="dl-grid">
            {visible.map((d, i) => {
              const href = d.pdf_url_external || d.pdf_url;
              const ready = !!href;
              const title = pickLangField(d, 'title', t.locale) || d.title_pt || d.title_en;
              // Translate the raw PT cat via t.dlCats; fall back to raw if no
              // translation exists (covers user-added cats not yet in ui-labels).
              const rawCat = (d && d.cat ? String(d.cat).trim() : '');
              const catDisplay = (rawCat && t.dlCats && t.dlCats[rawCat]) || rawCat || ({ pt: 'OUTROS', en: 'OTHER', es: 'OTROS' }[t.locale] || 'OTHER');
              // Slug is not unique in the current data (many "corp" entries),
              // so we add the index as a tie-breaker for React keys.
              const key = `${d.slug || 'pdf'}-${i}`;
              return (
                <div className="dl-card" key={key}>
                  {d.cover_image ? (
                    <div style={{ width: '100%', aspectRatio: '4 / 3', overflow: 'hidden', borderRadius: 8, marginBottom: 12, background: '#f4f2eb' }}>
                      <img
                        src={d.cover_image}
                        alt={title}
                        loading="lazy"
                        style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
                        onError={(e) => { e.currentTarget.style.display = 'none'; }}
                      />
                    </div>
                  ) : (
                    <div className="pdf-ico">PDF</div>
                  )}
                  <div>
                    <span className="cat">{catDisplay}</span>
                    <h4>{title}</h4>
                    <p>{pickLangField(d, 'desc', t.locale) || d.desc_pt || d.desc_en}</p>
                    <div className="act">
                      {ready ? (
                        <button className="arrow" type="button" onClick={() => openDownloadLeadModal(title)}>{t.quality.pdfBtn}</button>
                      ) : (
                        <button className="arrow" disabled style={{ opacity: 0.5, cursor: 'not-allowed' }}>
                          {(t.pd && t.pd.pdfPending) || (t.locale === 'pt' ? 'Em breve' : t.locale === 'es' ? 'Próximamente' : 'Coming soon')}
                        </button>
                      )}
                      <span style={{ color: 'var(--muted)', fontFamily: 'JetBrains Mono, monospace', fontSize: '0.78rem' }}>{d.size}</span>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </section>

      {downloadLeadOpen && (
        <div className="dl-lead-modal" role="dialog" aria-modal="true" aria-labelledby="dl-lead-title">
          <button
            type="button"
            className="dl-lead-modal__backdrop"
            aria-label={t.locale === 'pt' ? 'Fechar' : t.locale === 'es' ? 'Cerrar' : 'Close'}
            onClick={() => setDownloadLeadOpen(false)}
          />
          <div className="dl-lead-modal__panel">
            <button
              type="button"
              className="dl-lead-modal__close"
              aria-label={t.locale === 'pt' ? 'Fechar' : t.locale === 'es' ? 'Cerrar' : 'Close'}
              onClick={() => setDownloadLeadOpen(false)}
            >
              ×
            </button>
            <form className="dl-lead-modal__form" onSubmit={submitDownloadLead} noValidate>
              <div className="dl-lead-form__head">
                <div>
                  <span className="eyebrow">{dlForm.eyebrow}</span>
                  <h3 id="dl-lead-title">{dlForm.title}</h3>
                </div>
                <p>{dlForm.lead}</p>
              </div>
              {downloadLeadErrors._global && (
                <div className="dl-lead-alert" role="alert">{downloadLeadErrors._global}</div>
              )}
              <div className="form-grid dl-lead-form__grid">
                <div className={'field' + (downloadLeadErrors.company ? ' err' : '')}>
                  <label>{dlForm.company}<span className="req">*</span></label>
                  <input
                    ref={downloadLeadFirstFieldRef}
                    type="text"
                    autoComplete="organization"
                    value={downloadLead.company}
                    onChange={e => setDownloadLeadField('company', e.target.value)}
                  />
                  {downloadLeadErrors.company && <span className="err-msg">{downloadLeadErrors.company}</span>}
                </div>
                <div className={'field' + (downloadLeadErrors.name ? ' err' : '')}>
                  <label>{dlForm.name}<span className="req">*</span></label>
                  <input
                    type="text"
                    autoComplete="name"
                    value={downloadLead.name}
                    onChange={e => setDownloadLeadField('name', e.target.value)}
                  />
                  {downloadLeadErrors.name && <span className="err-msg">{downloadLeadErrors.name}</span>}
                </div>
                <div className={'field' + (downloadLeadErrors.contact ? ' err' : '')}>
                  <label>{dlForm.contact}<span className="req">*</span></label>
                  <input
                    type="text"
                    autoComplete="email"
                    value={downloadLead.contact}
                    onChange={e => setDownloadLeadField('contact', e.target.value)}
                  />
                  <span className="hint">{dlForm.contactHint}</span>
                  {downloadLeadErrors.contact && <span className="err-msg">{downloadLeadErrors.contact}</span>}
                </div>
                <div className={'field' + (downloadLeadErrors.product ? ' err' : '')}>
                  <label>{dlForm.product}<span className="req">*</span></label>
                  <select
                    value={downloadLead.product}
                    onChange={e => setDownloadLeadField('product', e.target.value)}
                  >
                    <option value="">{dlForm.productPlaceholder}</option>
                    {downloadOptions.map(item => (
                      <option key={item.key} value={item.title}>{item.title}</option>
                    ))}
                  </select>
                  {downloadLeadErrors.product && <span className="err-msg">{downloadLeadErrors.product}</span>}
                </div>
                <div className="field full">
                  <label>{dlForm.notes}</label>
                  <textarea
                    placeholder={dlForm.notesPlaceholder}
                    value={downloadLead.notes}
                    onChange={e => setDownloadLeadField('notes', e.target.value)}
                  />
                </div>
              </div>
              <div className="form-foot">
                <div className="note">{dlForm.note}</div>
                <button className="btn btn-primary btn-lg arrow" type="submit">
                  {dlForm.submit}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      <section className="section-tight" style={{ background: 'var(--bg-2)' }}>
        <div className="container">
          <div className="sec-head">
            <div>
              <span className="eyebrow">{t.quality.faqHead.eyebrow}</span>
              <h2>{t.quality.faqHead.h2}</h2>
            </div>
            <p></p>
          </div>
          <div className="faq-list">
            {t.quality.faqs.map((f, i) => <FAQItem key={i} q={f.q} a={f.a} />)}
          </div>
        </div>
      </section>

      <CTABand t={t} go={go} />
    </div>
  );
}

function ContactPage({ t, go, prefillProduct, lang, buildUrl }) {
  const [form, setForm] = useState({
    name: '', company: '', email: '', phone: '', country: t.defaultCountry,
    sector: '', product: prefillProduct ? (t.productList.find(x => x.slug === prefillProduct)?.short || '') : '',
    dn: '', pressure: '', volume: '', message: '', docs: [],
  });
  const [errors, setErrors] = useState({});
  const [submitting, setSubmitting] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [mailHandoff, setMailHandoff] = useState(false);
  const [mailCopied, setMailCopied] = useState(false);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const toggleDoc = (d) => setForm(f => ({
    ...f,
    docs: f.docs.includes(d) ? f.docs.filter(x => x !== d) : [...f.docs, d]
  }));

  const validate = () => {
    const e = {};
    if (!form.name.trim()) e.name = t.contact.required;
    if (!form.company.trim()) e.company = t.contact.required;
    if (!form.email.trim()) e.email = t.contact.required;
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) e.email = t.contact.invalidEmail;
    if (!form.sector) e.sector = t.contact.required;
    if (!form.product) e.product = t.contact.required;
    if (!form.message.trim()) e.message = t.contact.required;
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  // Build a multi-line text body — used for both the localStorage backup and
  // the mailto: hand-off in submit().
  const buildMailBody = (f) => [
    `Name: ${f.name}`,
    `Company: ${f.company}`,
    `Email: ${f.email}`,
    `Phone: ${f.phone}`,
    `Country: ${f.country}`,
    `Sector: ${f.sector}`,
    `Product: ${f.product}`,
    `DN: ${f.dn}`,
    `Pressure: ${f.pressure}`,
    `Volume: ${f.volume}`,
    `Documents: ${f.docs.join(', ')}`,
    '',
    'Message:',
    f.message,
  ].join('\n');

  const saveLocalBackup = (f) => {
    try {
      const existing = JSON.parse(localStorage.getItem('lesso_inquiries') || '[]');
      existing.push({ ...f, at: new Date().toISOString() });
      localStorage.setItem('lesso_inquiries', JSON.stringify(existing));
    } catch(e) { /* private mode / quota */ }
  };

  // There is no form backend (Netlify Forms went away with the move to
  // Vercel): submitting hands the inquiry to the visitor's own email app,
  // addressed to contact.json → info.inquiryEmail. The `mailHandoff` banner
  // repeats the link and offers a copy button for visitors without a mail
  // app (e.g. webmail). To wire a real endpoint later, POST here and
  // setSubmitted(true) on success — the success card below is kept for that.
  const inquiryEmail = (window.CONTACT && window.CONTACT.inquiryEmail) || 'infolatam@lesso.com';
  // Some mail clients drop mailto: URLs past ~2,000 characters (an accented
  // letter encodes to 6), so the body is capped — the copy button in the
  // banner always carries the full text.
  const MAILTO_BODY_MAX = 1800;
  const mailtoHref = (f) => {
    const full = buildMailBody(f);
    let body = full;
    if (encodeURIComponent(full).length > MAILTO_BODY_MAX) {
      // Trim by code point so an emoji is never split into a lone surrogate
      // (encodeURIComponent throws on those).
      const chars = Array.from(full);
      do {
        chars.length = Math.max(0, chars.length - 40);
        body = chars.join('') + '\n[…]';
      } while (chars.length && encodeURIComponent(body).length > MAILTO_BODY_MAX);
    }
    return `mailto:${inquiryEmail}?subject=${encodeURIComponent('[LESSO Brasil] Quote — ' + (f.product || 'General') + ' — ' + f.company)}&body=${encodeURIComponent(body)}`;
  };

  const copyInquiry = () => {
    if (!navigator.clipboard) return;
    navigator.clipboard.writeText(buildMailBody(form)).then(() => setMailCopied(true), () => {});
  };

  const submit = (ev) => {
    ev.preventDefault();
    if (!validate()) return;
    saveLocalBackup(form);
    setMailHandoff(true);
    setMailCopied(false);
    // Report the hand-off as a GA4 lead. The global contact_click delegation
    // in app.jsx only sees real <a> clicks, so this is a separate signal.
    if (window.gtag) {
      window.gtag('event', 'generate_lead', {
        method: 'mailto',
        form_name: 'contact_inquiry',
        product: form.product || '',
        page_path: location.pathname,
      });
    }
    window.location.href = mailtoHref(form);
  };

  React.useEffect(() => {
    if (!mailHandoff) return;
    const el = document.querySelector('.form-mail-handoff');
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }, [mailHandoff]);

  if (submitted) {
    return (
      <div className="page-enter">
        <section className="page-hero">
          <div className="container">
            <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.contact }]} go={go} lang={lang} buildUrl={buildUrl} />
          </div>
        </section>
        <section className="section">
          <div className="container" style={{ maxWidth: 640 }}>
            <div className="success-card">
              <div className="ico">✓</div>
              <h3>{t.contact.successH}</h3>
              <p>{t.contact.successP}</p>
              <div style={{ display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
                <button className="btn btn-primary" onClick={() => go('home')}>{t.contact.successBack}</button>
                <button className="btn btn-secondary" onClick={() => { setSubmitted(false); setForm({
                  name: '', company: '', email: '', phone: '', country: t.defaultCountry,
                  sector: '', product: '', dn: '', pressure: '', volume: '', message: '', docs: [],
                }); }}>{t.contact.successNew}</button>
              </div>
            </div>
          </div>
        </section>
      </div>
    );
  }

  const F = t.contact.f;

  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.contact }]} go={go} lang={lang} buildUrl={buildUrl} />
          <h1>{t.contact.pageH1}</h1>
          <p className="lead">{t.contact.pageLead}</p>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div className="contact-grid">
            <div className="contact-info">
              {t.contact.infoTitle && <h3 className="contact-info-title">{t.contact.infoTitle}</h3>}
              <LinkedInCards t={t} />
              <div className="ci-card">
                <h4>{t.contact.infoA.k}</h4>
                <div className="val">{t.contact.infoA.v}</div>
                <div className="sub">{t.contact.infoA.s}</div>
                <span className="ci-card-corner ci-card-corner--ink" aria-hidden="true">
                  <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
                </span>
              </div>
              <WhatsAppPhoneCard t={t} />
              <div className="ci-card">
                <h4>{t.contact.infoC.k}</h4>
                <div className="val">{t.contact.infoC.v}</div>
                <div className="sub">{t.contact.infoC.s}</div>
                <span className="ci-card-corner ci-card-corner--ink" aria-hidden="true">
                  <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M12 2C8.1 2 5 5.1 5 9c0 5.3 7 13 7 13s7-7.8 7-13c0-3.9-3.1-7-7-7zm0 9.5c-1.4 0-2.5-1.1-2.5-2.5S10.6 6.5 12 6.5s2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5z"/></svg>
                </span>
              </div>
              <div className="ci-card">
                <h4>{t.contact.infoD.k}</h4>
                <div className="val">{t.contact.infoD.v}</div>
                <div className="sub">{t.contact.infoD.s}</div>
                <span className="ci-card-corner ci-card-corner--ink" aria-hidden="true">
                  <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm0 18c-4.4 0-8-3.6-8-8s3.6-8 8-8 8 3.6 8 8-3.6 8-8 8zm.5-13H11v6l5.2 3.2.8-1.3-4.5-2.7V7z"/></svg>
                </span>
              </div>
            </div>

            <form
              className="form-card"
              onSubmit={submit}
              noValidate
            >
              <h3>{t.contact.formTitle}</h3>
              <p>{t.contact.formLead}</p>

              {/* Mail hand-off notice — shown after submit() opened the visitor's
                  email app. The button and the plain address cover browsers with
                  no mail handler. Copy comes from contact.json (CMS-editable). */}
              {mailHandoff && (
                <div className="form-mail-handoff" role="status" style={{
                  padding: '14px 16px', marginBottom: 16,
                  border: '1px solid var(--line)', borderLeft: '4px solid var(--brand)',
                  background: 'var(--brand-soft)', borderRadius: 4,
                }}>
                  <p style={{ margin: '0 0 10px' }}>{t.contact.submitFallback}</p>
                  <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
                    <a className="btn btn-primary btn-sm" href={mailtoHref(form)}>{t.contact.submitFallbackBtn}</a>
                    <button type="button" className="btn btn-secondary btn-sm" onClick={copyInquiry}>
                      {t.contact.submitFallbackCopy}{mailCopied ? ' ✓' : ''}
                    </button>
                    <span style={{ userSelect: 'all' }}>{inquiryEmail}</span>
                  </div>
                </div>
              )}

              <div className="form-grid">
                <div className={'field' + (errors.name ? ' err' : '')}>
                  <label>{F.name}<span className="req">*</span></label>
                  <input type="text" placeholder={F.nameH} value={form.name} onChange={e => set('name', e.target.value)} />
                  {errors.name && <span className="err-msg">{errors.name}</span>}
                </div>
                <div className={'field' + (errors.company ? ' err' : '')}>
                  <label>{F.company}<span className="req">*</span></label>
                  <input type="text" placeholder={F.companyH} value={form.company} onChange={e => set('company', e.target.value)} />
                  {errors.company && <span className="err-msg">{errors.company}</span>}
                </div>
                <div className={'field' + (errors.email ? ' err' : '')}>
                  <label>{F.email}<span className="req">*</span></label>
                  <input type="email" value={form.email} onChange={e => set('email', e.target.value)} />
                  {errors.email && <span className="err-msg">{errors.email}</span>}
                </div>
                <div className="field">
                  <label>{F.phone}</label>
                  <input type="tel" value={form.phone} onChange={e => set('phone', e.target.value)} />
                </div>
                <div className="field">
                  <label>{F.country}</label>
                  <input type="text" value={form.country} onChange={e => set('country', e.target.value)} />
                </div>
                <div className={'field' + (errors.sector ? ' err' : '')}>
                  <label>{F.sector}<span className="req">*</span></label>
                  <select value={form.sector} onChange={e => set('sector', e.target.value)}>
                    <option value="">—</option>
                    {F.sectorOpts.map(o => <option key={o} value={o}>{o}</option>)}
                  </select>
                  {errors.sector && <span className="err-msg">{errors.sector}</span>}
                </div>
                <div className={'field full' + (errors.product ? ' err' : '')}>
                  <label>{F.product}<span className="req">*</span></label>
                  <select value={form.product} onChange={e => set('product', e.target.value)}>
                    <option value="">—</option>
                    {/* Options derive from the live productList (currently 14
                        series) — keeps the quote form in sync as products are
                        added/removed via /admin/. The static contact.json
                        productOpts is used only as a fallback if productList
                        is empty (degraded JSON load). */}
                    {Array.isArray(t.productList) && t.productList.length > 0
                      ? t.productList.map(p => <option key={p.slug} value={p.short}>{p.short}</option>)
                      : F.productOpts.map(o => <option key={o} value={o}>{o}</option>)}
                    {/* "Not sure — recommend by project" always last */}
                    {F.productOpts && F.productOpts.length > 0 && (
                      <option value={F.productOpts[F.productOpts.length - 1]}>
                        {F.productOpts[F.productOpts.length - 1]}
                      </option>
                    )}
                  </select>
                  {errors.product && <span className="err-msg">{errors.product}</span>}
                </div>
                <div className="field">
                  <label>{F.dn}</label>
                  <input type="text" placeholder={F.dnH} value={form.dn} onChange={e => set('dn', e.target.value)} />
                </div>
                <div className="field">
                  <label>{F.pressure}</label>
                  <input type="text" placeholder={F.pressureH} value={form.pressure} onChange={e => set('pressure', e.target.value)} />
                </div>
                <div className="field full">
                  <label>{F.volume}</label>
                  <input type="text" placeholder={F.volumeH} value={form.volume} onChange={e => set('volume', e.target.value)} />
                </div>
                <div className={'field full' + (errors.message ? ' err' : '')}>
                  <label>{F.message}<span className="req">*</span></label>
                  <textarea placeholder={F.messageH} value={form.message} onChange={e => set('message', e.target.value)}></textarea>
                  {errors.message && <span className="err-msg">{errors.message}</span>}
                </div>
                <div className="field full">
                  <label>{F.docs}</label>
                  <div className="checks-row">
                    {F.docOpts.map(d => (
                      <div key={d} className={'check-pill' + (form.docs.includes(d) ? ' on' : '')} onClick={() => toggleDoc(d)}>
                        <div className="box">{form.docs.includes(d) ? '✓' : ''}</div>
                        <span>{d}</span>
                      </div>
                    ))}
                  </div>
                </div>
              </div>

              <div className="form-foot">
                <div className="note">{t.contact.note}</div>
                <button className="btn btn-primary btn-lg arrow" type="submit" disabled={submitting}>
                  {submitting ? t.contact.submitting : t.contact.submit}
                </button>
              </div>
            </form>
          </div>
        </div>
      </section>

      <BusinessCardSection />
      <SocialLinksSection t={t} />
    </div>
  );
}

// Phone card with a WhatsApp corner badge. The whole card becomes a
// click-to-chat link if the WhatsApp number is configured; otherwise
// it renders as the plain info card the JSX used before.
function WhatsAppPhoneCard({ t }) {
  const info = (window.CONTACT) || {};
  const rawNumber = info.whatsapp || '';
  const digits = String(rawNumber).replace(/\D/g, '');
  const waLink = (info.social && info.social.whatsappLink) || (digits.length >= 8 ? `https://wa.me/${digits}` : '');
  const inner = (
    <React.Fragment>
      <h4>{t.contact.infoB.k}</h4>
      <div className="val">{t.contact.infoB.v}</div>
      <div className="sub">{t.contact.infoB.s}</div>
      {waLink && (
        <span className="ci-card-corner ci-card-corner--whatsapp" aria-hidden="true">
          <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor">
            <path d="M17.5 14.4c-.3-.2-1.8-.9-2.1-1-.3-.1-.5-.1-.7.2-.2.3-.8 1-1 1.2-.2.2-.4.2-.6.1-.3-.2-1.2-.4-2.2-1.4-.8-.7-1.4-1.6-1.5-1.9-.2-.3 0-.4.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5-.1-.2-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5-.2 0-.4 0-.6 0s-.5.1-.8.4c-.3.3-1.1 1-1.1 2.5 0 1.5 1.1 2.9 1.2 3.1.2.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.8-.7 2-1.4.3-.7.3-1.3.2-1.4-.1-.1-.3-.2-.6-.3zM12 2C6.5 2 2 6.5 2 12c0 1.9.5 3.7 1.5 5.3L2 22l4.8-1.5c1.5.8 3.2 1.3 5.2 1.3 5.5 0 10-4.5 10-10S17.5 2 12 2z"/>
          </svg>
        </span>
      )}
    </React.Fragment>
  );
  if (waLink) {
    return <a className="ci-card ci-card--clickable ci-card--whatsapp" href={waLink} target="_blank" rel="noopener noreferrer">{inner}</a>;
  }
  return <div className="ci-card">{inner}</div>;
}

// Compact LinkedIn cards rendered inline inside the contact-info column.
// Replaces the standalone LinkedInSection that used to live below the
// form; the customer asked to move them next to the phone card so the
// whole "ways to reach us" stack is in one place.
function LinkedInCards({ t }) {
  const info = (window.CONTACT) || {};
  const co = info.linkedinCompany;
  const coLogo = info.linkedinCompanyLogo;
  const person = info.linkedinPerson || {};
  const hasCo = typeof co === 'string' && /^https?:\/\//.test(co);
  const hasPerson = person && typeof person.url === 'string' && /^https?:\/\//.test(person.url);
  const [coLogoFailed, setCoLogoFailed] = useState(false);
  const [personPhotoFailed, setPersonPhotoFailed] = useState(false);
  if (!hasCo && !hasPerson) return null;
  const liSvg = (
    <svg viewBox="0 0 32 32" width="14" height="14" fill="currentColor" aria-hidden="true">
      <path d="M27.3 27.3h-4.7v-7.4c0-1.8 0-4-2.5-4-2.5 0-2.9 1.9-2.9 3.9v7.6h-4.7V12.1h4.5v2h.1c.6-1.2 2.1-2.5 4.4-2.5 4.7 0 5.5 3.1 5.5 7.1v8.6zm-19.9-17a2.7 2.7 0 110-5.4 2.7 2.7 0 010 5.4zm2.3 17H4.9V12.1h4.8v15.2zM29.7 0H2.3C1 0 0 1 0 2.2v27.5C0 31 1 32 2.3 32h27.4c1.3 0 2.3-1 2.3-2.2V2.2C32 1 31 0 29.7 0z"/>
    </svg>
  );
  return (
    <React.Fragment>
      {hasPerson && (
        <a className="ci-card ci-card--clickable ci-card--linkedin" href={person.url} target="_blank" rel="noopener noreferrer">
          <div className="ci-linkedin-row">
            {person.photo && !personPhotoFailed
              ? <img className="ci-linkedin-thumb" src={person.photo} alt={person.name || ''} onError={() => setPersonPhotoFailed(true)} />
              : <div className="ci-linkedin-thumb ci-linkedin-thumb--placeholder" aria-hidden="true">{(person.name || '?').trim()[0]}</div>
            }
            <div className="ci-linkedin-text">
              <h4>LinkedIn — {t.locale === 'pt' ? 'Representante' : t.locale === 'es' ? 'Representante' : 'Contact'}</h4>
              <div className="val">{person.name}</div>
              <div className="sub">{person.title}</div>
            </div>
          </div>
          <span className="ci-card-corner ci-card-corner--linkedin" aria-hidden="true">{liSvg}</span>
        </a>
      )}
      {hasCo && (
        <a className="ci-card ci-card--clickable ci-card--linkedin" href={co} target="_blank" rel="noopener noreferrer">
          <div className="ci-linkedin-row">
            {coLogo && !coLogoFailed
              ? <img className="ci-linkedin-thumb ci-linkedin-thumb--square" src={coLogo} alt="LESSO" onError={() => setCoLogoFailed(true)} />
              : <div className="ci-linkedin-thumb ci-linkedin-thumb--square ci-linkedin-thumb--placeholder" aria-hidden="true">L</div>
            }
            <div className="ci-linkedin-text">
              <h4>{t.contact.linkedinTitle}</h4>
              <div className="val">LESSO Group</div>
              <div className="sub">{t.contact.linkedinCoSubtitle}</div>
            </div>
          </div>
          <span className="ci-card-corner ci-card-corner--linkedin" aria-hidden="true">{liSvg}</span>
        </a>
      )}
    </React.Fragment>
  );
}

// Social links grid — YouTube / WhatsApp / Facebook / X / Douyin /
// Instagram / alt-email. Each platform reads its URL from
// window.CONTACT.social[platform]; a blank URL hides the corresponding
// card so editors can ignore platforms they don't run.
function SocialLinksSection({ t }) {
  const social = (window.CONTACT && window.CONTACT.social) || {};
  // Brand colors + inline SVGs. The icon set covers the platforms the
  // customer has accounts on today; new ones can be added to this map
  // and a matching key plugged into admin/config.yml.
  const platforms = [
    { id: 'youtube',  url: social.youtube,      name: 'YouTube',  color: '#FF0000',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2C0 8.1 0 12 0 12s0 3.9.5 5.8a3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1c.5-1.9.5-5.8.5-5.8s0-3.9-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z"/></svg> },
    { id: 'whatsapp', url: social.whatsappLink, name: 'WhatsApp', color: '#25D366',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M17.5 14.4c-.3-.2-1.8-.9-2.1-1-.3-.1-.5-.1-.7.2-.2.3-.8 1-1 1.2-.2.2-.4.2-.6.1-.3-.2-1.2-.4-2.2-1.4-.8-.7-1.4-1.6-1.5-1.9-.2-.3 0-.4.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5-.1-.2-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5-.2 0-.4 0-.6 0s-.5.1-.8.4c-.3.3-1.1 1-1.1 2.5 0 1.5 1.1 2.9 1.2 3.1.2.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.8-.7 2-1.4.3-.7.3-1.3.2-1.4-.1-.1-.3-.2-.6-.3zM12 2C6.5 2 2 6.5 2 12c0 1.9.5 3.7 1.5 5.3L2 22l4.8-1.5c1.5.8 3.2 1.3 5.2 1.3 5.5 0 10-4.5 10-10S17.5 2 12 2z"/></svg> },
    { id: 'facebook', url: social.facebook,     name: 'Facebook', color: '#1877F2',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M22 12c0-5.5-4.5-10-10-10S2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12z"/></svg> },
    { id: 'twitter',  url: social.twitter,      name: 'X',        color: '#000000',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg> },
    { id: 'douyin',   url: social.douyin,       name: 'TikTok',   color: '#000000',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M16.6 2c.5 1.8 1.5 3.2 3 4.2 1.1.7 2.3 1.1 3.4 1.2v3.4c-2.2 0-4.3-.7-6-2v8.6c0 3.6-2.9 6.6-6.5 6.6S4 21 4 17.4s2.9-6.6 6.5-6.6c.5 0 1 .1 1.5.2v3.5c-.5-.2-1-.3-1.5-.3-1.7 0-3.1 1.4-3.1 3.2 0 1.8 1.4 3.2 3.1 3.2s3.1-1.4 3.1-3.2V2h3z"/></svg> },
    { id: 'instagram', url: social.instagram,   name: 'Instagram', color: '#E4405F',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M12 2.2c3.2 0 3.6 0 4.8.1 1.2 0 1.8.2 2.2.4.6.2 1 .5 1.4.9.4.4.7.8.9 1.4.2.4.4 1 .4 2.2.1 1.2.1 1.6.1 4.8s0 3.6-.1 4.8c0 1.2-.2 1.8-.4 2.2-.2.6-.5 1-.9 1.4-.4.4-.8.7-1.4.9-.4.2-1 .4-2.2.4-1.2.1-1.6.1-4.8.1s-3.6 0-4.8-.1c-1.2 0-1.8-.2-2.2-.4-.6-.2-1-.5-1.4-.9-.4-.4-.7-.8-.9-1.4-.2-.4-.4-1-.4-2.2-.1-1.2-.1-1.6-.1-4.8s0-3.6.1-4.8c0-1.2.2-1.8.4-2.2.2-.6.5-1 .9-1.4.4-.4.8-.7 1.4-.9.4-.2 1-.4 2.2-.4 1.2-.1 1.6-.1 4.8-.1M12 0C8.7 0 8.3 0 7.1.1 5.8.1 5 .3 4.2.6c-.8.3-1.5.7-2.2 1.4C1.3 2.7.9 3.4.6 4.2.3 5 .1 5.8.1 7.1 0 8.3 0 8.7 0 12s0 3.7.1 4.9c0 1.3.2 2.1.5 2.9.3.8.7 1.5 1.4 2.2.7.7 1.4 1.1 2.2 1.4.8.3 1.6.5 2.9.5 1.2.1 1.6.1 4.9.1s3.7 0 4.9-.1c1.3 0 2.1-.2 2.9-.5.8-.3 1.5-.7 2.2-1.4.7-.7 1.1-1.4 1.4-2.2.3-.8.5-1.6.5-2.9.1-1.2.1-1.6.1-4.9s0-3.7-.1-4.9c0-1.3-.2-2.1-.5-2.9-.3-.8-.7-1.5-1.4-2.2C21.3 1.3 20.6.9 19.8.6 19 .3 18.2.1 16.9.1 15.7 0 15.3 0 12 0zm0 5.8c-3.4 0-6.2 2.8-6.2 6.2s2.8 6.2 6.2 6.2 6.2-2.8 6.2-6.2S15.4 5.8 12 5.8zm0 10.2c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4zm6.4-11.8c-.8 0-1.4.6-1.4 1.4s.6 1.4 1.4 1.4 1.4-.6 1.4-1.4-.6-1.4-1.4-1.4z"/></svg> },
    { id: 'email',    url: social.emailAlt ? `mailto:${social.emailAlt}` : '', name: social.emailAlt || 'E-mail', color: '#525252',
      svg: <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z"/></svg> },
  ].filter(p => p.url);
  if (platforms.length === 0) return null;
  const title = t.locale === 'pt' ? 'Redes sociais' : t.locale === 'es' ? 'Redes sociales' : 'Social media';
  const lead = t.locale === 'pt'
    ? 'Acompanhe a LESSO em todas as principais plataformas.'
    : t.locale === 'es' ? 'Siga a LESSO en todas las plataformas principales.' : 'Follow LESSO on every major platform.';
  return (
    <section className="section-tight" style={{ background: 'var(--bg-2)' }}>
      <div className="container">
        <div className="sec-head">
          <div>
            <span className="eyebrow">{t.locale === 'pt' ? 'CONECTE-SE' : t.locale === 'es' ? 'CONÉCTESE' : 'CONNECT'}</span>
            <h2>{title}</h2>
          </div>
          <p>{lead}</p>
        </div>
        <div className="social-grid">
          {platforms.map(p => (
            <a key={p.id} className="social-card" href={p.url} target="_blank" rel="noopener noreferrer"
               style={{ '--social-color': p.color }}>
              <span className="social-card-icon" style={{ background: p.color }}>{p.svg}</span>
              <span className="social-card-name">{p.name}</span>
            </a>
          ))}
        </div>
      </div>
    </section>
  );
}



// Business card — rendered as a centered image strip below the LinkedIn
// cards. Hidden entirely if no image is configured, so editors can prep
// fields without showing a broken section. The image keeps its native
// aspect ratio (object-fit: contain) so frente/verso/side-by-side scans
// all read correctly.
function BusinessCardSection() {
  const card = (window.CONTACT && window.CONTACT.businessCard) || {};
  // Same defensive pattern as LinkedInSection: a configured-but-missing
  // image triggers onError and hides the whole section, so editors can
  // pre-fill the path before uploading without breaking the page.
  const [failed, setFailed] = useState(false);
  if (!card.image || failed) return null;
  return (
    <section className="section-tight business-card-section">
      <div className="container">
        <figure className="business-card">
          <img src={card.image} alt={card.caption || 'Cartão de visita'} loading="lazy" onError={() => setFailed(true)} />
          {card.caption && <figcaption>{card.caption}</figcaption>}
        </figure>
      </div>
    </section>
  );
}

// ---------- News --------------------------------------------------------
//
// News content is multilingual. Each post is one JSON file in content/news/,
// listed via the generated content/news/_index.json. The loader in app.jsx
// stuffs them into window.NEWS sorted newest-first.
//
// Body is plain-text/markdown-light: blank-line-separated paragraphs, with
// **bold** inline emphasis. We don't run a full markdown parser to keep the
// bundle small — splitParagraphs handles paragraphs, renderInline handles
// bold.

const newsLabels = {
  pt: {
    pageH1: 'Notícias',
    pageLead: 'Atualizações da LESSO Brasil e da operação LATAM: lançamentos, certificações, eventos e marcos comerciais.',
    empty: 'Em breve, novas publicações.',
    back: '← Todas as notícias',
    crumbHome: 'Início',
    crumbNews: 'Notícias',
  },
  en: {
    pageH1: 'News',
    pageLead: 'Updates from LESSO Brasil and the LATAM operation: launches, certifications, events, and commercial milestones.',
    empty: 'New posts coming soon.',
    back: '← All news',
    crumbHome: 'Home',
    crumbNews: 'News',
  },
  es: {
    pageH1: 'Noticias',
    pageLead: 'Novedades de LESSO Brasil y la operación LATAM: lanzamientos, certificaciones, eventos e hitos comerciales.',
    empty: 'Pronto, nuevas publicaciones.',
    back: '← Todas las noticias',
    crumbHome: 'Inicio',
    crumbNews: 'Noticias',
  },
};

function formatNewsDate(iso, lang) {
  if (!iso) return '';
  // YYYY-MM-DD → human format. Use UTC parts to avoid timezone shift.
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso);
  if (!m) return iso;
  const [_, y, mo, d] = m;
  const MONTHS = {
    pt: ['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez'],
    en: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
    es: ['ene','feb','mar','abr','may','jun','jul','ago','sep','oct','nov','dic'],
  };
  const months = MONTHS[lang] || MONTHS.en;
  return `${parseInt(d,10)} ${months[parseInt(mo,10)-1]} ${y}`;
}

function renderInline(text) {
  // Split on **bold** markers, keeping the bold pieces separate so we can
  // wrap them in <strong>.
  const parts = String(text).split(/(\*\*[^*]+\*\*)/g);
  return parts.map((p, i) => {
    if (/^\*\*[^*]+\*\*$/.test(p)) return <strong key={i}>{p.slice(2, -2)}</strong>;
    return <React.Fragment key={i}>{p}</React.Fragment>;
  });
}

function NewsIndex({ t, go, lang, buildUrl }) {
  // Prefer t.news (i18n + admin-editable). Fall back to legacy newsLabels
  // hash if for some reason the i18n.jsx slice wasn't loaded yet.
  const labels = (t && t.news) || newsLabels[lang] || newsLabels.pt;
  const posts = Array.isArray(window.NEWS) ? window.NEWS : [];
  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs items={[{ label: t.nav.home, to: 'home' }, { label: t.nav.news || labels.pageH1 }]} go={go} lang={lang} buildUrl={buildUrl} />
          <h1>{labels.pageH1}</h1>
          <p className="lead">{labels.pageLead}</p>
        </div>
      </section>

      <section className="section">
        <div className="container">
          {posts.length === 0 ? (
            <p className="news-empty">{labels.empty}</p>
          ) : (
            <div className="news-grid">
              {posts.map(post => (
                <a
                  key={post.slug}
                  className="news-card"
                  href={buildUrl(lang, 'newsPost', { slug: post.slug })}
                  onClick={(e) => { if (e.metaKey||e.ctrlKey||e.shiftKey||e.button===1) return; e.preventDefault(); go('newsPost', { slug: post.slug }); }}
                >
                  {post.image && (
                    <div className="news-card-img">
                      <img src={post.image} alt="" loading="lazy" />
                    </div>
                  )}
                  <div className="news-card-body">
                    <span className="news-date mono">{formatNewsDate(post.date, lang)}</span>
                    <h3>{pickNewsField(post, 'title', lang)}</h3>
                    <p>{pickNewsField(post, 'summary', lang)}</p>
                    <span className="news-card-cta">{t.news ? t.news.readMore : ({ pt: 'Ler mais →', en: 'Read more →', es: 'Leer más →' }[lang] || 'Read more →')}</span>
                  </div>
                </a>
              ))}
            </div>
          )}
        </div>
      </section>
    </div>
  );
}

function NewsPost({ t, go, slug, lang, buildUrl }) {
  const labels = (t && t.news) || newsLabels[lang] || newsLabels.pt;
  const posts = Array.isArray(window.NEWS) ? window.NEWS : [];
  const post = posts.find(p => p.slug === slug);
  if (!post) return <NotFoundPage t={t} go={go} lang={lang} buildUrl={buildUrl} />;

  const postTitle = pickNewsField(post, 'title', lang);
  const postSummary = pickNewsField(post, 'summary', lang);
  const postBody = pickNewsField(post, 'body', lang);
  const paragraphs = String(postBody || '').split(/\n\s*\n/).map(p => p.trim()).filter(Boolean);
  return (
    <div className="page-enter">
      <section className="page-hero">
        <div className="container">
          <Crumbs
            items={[
              { label: t.nav.home, to: 'home' },
              { label: t.nav.news || labels.pageH1, to: 'news' },
              { label: postTitle },
            ]}
            go={go}
            lang={lang}
            buildUrl={buildUrl}
          />
          <span className="news-date mono">{formatNewsDate(post.date, lang)}</span>
          <h1>{postTitle}</h1>
          {postSummary && <p className="lead">{postSummary}</p>}
        </div>
      </section>

      {post.image && (
        <section className="section-tight">
          <div className="container">
            <div className="news-cover">
              <img src={post.image} alt="" />
            </div>
          </div>
        </section>
      )}

      <section className="section">
        <div className="container news-body">
          {paragraphs.map((p, i) => <p key={i}>{renderInline(p)}</p>)}
          <p>
            <a
              className="btn btn-ghost"
              href={buildUrl(lang, 'news')}
              onClick={(e) => { e.preventDefault(); go('news'); }}
            >{labels.back}</a>
          </p>
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { HomePage, ProductsIndex, ProductDetail, AboutPage, QualityPage, ContactPage, NewsIndex, NewsPost });
