/*
  sections.jsx — Nav, Featured, About, Services, Blog, ContactHero, Footer
*/

// ───────── Contacto por WhatsApp + validación ─────────
const WA_PHONE = "523327947692"; // número de Emiliano (mismo que el resto del sitio)

// Solo letras (con acentos), espacios y . ' - para nombres
const RE_NAME = /^[\p{L}][\p{L}\s'.-]*$/u;
// Correo con @ y dominio con punto + extensión (.com, .mx, etc.)
const RE_EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
// Deja solo dígitos
const onlyDigits = (s) => (s || "").replace(/\D+/g, "");

// Abre WhatsApp con un mensaje ya armado (líneas = array de strings)
function openWhatsApp(lines) {
  const text = lines.filter(Boolean).join("\n");
  const url = `https://wa.me/${WA_PHONE}?text=${encodeURIComponent(text)}`;
  window.open(url, "_blank", "noopener");
}


// ───────── NAV ─────────
function Nav({ t, lang, setLang }) {
  const [scrolled, setScrolled] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const navRef = React.useRef(null);

  // Bloquea el scroll del fondo mientras el menú móvil está abierto + cierra con Esc
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    const onKey = (e) => {if (e.key === 'Escape') setMenuOpen(false);};
    if (menuOpen) document.addEventListener('keydown', onKey);
    return () => {document.body.style.overflow = '';document.removeEventListener('keydown', onKey);};
  }, [menuOpen]);

  React.useEffect(() => {
    const onScroll = () => {
      const hero = document.getElementById('hero');
      const navH = navRef.current ? navRef.current.offsetHeight : 64;
      if (hero) {
        // Cristal durante TODO el hero; sólido sólo cuando el hero termina
        // de pasar bajo la barra (el nav "sale" del hero).
        const bottom = hero.getBoundingClientRect().bottom;
        setScrolled(bottom <= navH);
      } else {
        setScrolled((window.scrollY || 0) > 40);
      }
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
    };
  }, []);
  return (
    <>
    <nav ref={navRef} className={scrolled || menuOpen ? 'nav scrolled' : 'nav'}>
      <a href="#hero" className="nav-brand">
        {t.nav.brand}
        <small>{t.nav.brandSub}</small>
      </a>
      <div className="nav-links">
        <a href="#featured">{t.nav.featured}</a>
        <a href="propiedades.html">{t.nav.properties}</a>
        <a href="#about">{t.nav.about}</a>
        <a href="#services">{t.nav.services}</a>
        <a href="#blog">{t.nav.blog}</a>
        <a href="#contact">{t.nav.contact}</a>
      </div>
      <div className="nav-right">
        <button className="lang-toggle" onClick={() => setLang(lang === 'es' ? 'en' : 'es')}>
          <b>{lang.toUpperCase()}</b>
          <span>/ {lang === 'es' ? 'EN' : 'ES'}</span>
        </button>
        <button
            className={menuOpen ? 'nav-burger is-open' : 'nav-burger'}
            aria-label="Menú"
            aria-expanded={menuOpen}
            onClick={() => setMenuOpen((o) => !o)}>
            
          <span></span><span></span><span></span>
        </button>
      </div>
    </nav>

    <div className={menuOpen ? 'mobile-menu open' : 'mobile-menu'} role="dialog" aria-modal="true">
      <nav className="mobile-menu-links">
        <a href="#featured" onClick={() => setMenuOpen(false)}>{t.nav.featured}</a>
        <a href="propiedades.html" onClick={() => setMenuOpen(false)}>{t.nav.properties}</a>
        <a href="#about" onClick={() => setMenuOpen(false)}>{t.nav.about}</a>
        <a href="#services" onClick={() => setMenuOpen(false)}>{t.nav.services}</a>
        <a href="#blog" onClick={() => setMenuOpen(false)}>{t.nav.blog}</a>
        <a href="#contact" onClick={() => setMenuOpen(false)}>{t.nav.contact}</a>
      </nav>
      <a
          className="mobile-menu-cta"
          href={t.about.ctaUrl}
          target="_blank"
          rel="noopener noreferrer"
          onClick={() => setMenuOpen(false)}>
          
        <svg width="18" height="18" viewBox="0 0 16 16" fill="none" aria-hidden="true">
          <path d="M8 1.5a6.5 6.5 0 0 0-5.5 10L1.5 14.5l3-1A6.5 6.5 0 1 0 8 1.5Z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round" />
          <path d="M5.8 6.4c.1 1.6 1.2 2.7 2.8 2.8.4 0 .9-.2 1-.6l.4-.7c.1-.2 0-.4-.2-.5l-.9-.4c-.2-.1-.4 0-.5.1l-.3.4c-.6-.2-1.1-.7-1.3-1.3l.4-.3c.1-.1.2-.3.1-.5l-.4-.9c-.1-.2-.3-.3-.5-.2l-.7.4c-.4.1-.6.6-.6 1 0 0 0 .4 0 .4Z" fill="currentColor" />
        </svg>
        {t.about.cta}
      </a>
    </div>
    </>);

}

// ───────── REVEAL hook ─────────
function useReveal() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {if (e.isIntersecting) e.target.classList.add('is-in');});
    }, { threshold: 0.15 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

// ───────── FEATURED ─────────
// Muestra la propiedad marcada como "destacada" en el panel (campo featured).
// Si no hay ninguna o la base no está conectada, usa el contenido de respaldo.
function Featured({ t }) {
  const ref = useReveal();
  const isEN = t.featured.thisMonth.indexOf("'s") !== -1;
  const mes = new Date().toLocaleString(isEN ? 'en-US' : 'es-MX', { month: 'long' });
  const mesFrase = t.featured.thisMonth.replace('{m}', mes);

  const [prop, setProp] = React.useState(null);
  React.useEffect(() => {
    let alive = true;
    if (window.ECDB && ECDB.isConfigured()) {
      ECDB.loadPublic()
        .then((list) => { if (alive) { const fe = (list || []).find((x) => x.featured); if (fe) setProp(fe); } })
        .catch(() => {});
    }
    return () => { alive = false; };
  }, []);

  const opLabel = (op) => ((isEN
    ? { venta: 'For sale', renta: 'For rent', preventa: 'Pre-sale' }
    : { venta: 'Venta', renta: 'Renta', preventa: 'Preventa' })[op] || op);
  const fmtPrice = (p) =>
    '$' + Number(p.price || 0).toLocaleString(isEN ? 'en-US' : 'es-MX') +
    ' ' + (p.currency || 'MXN') + (p.pricePeriod ? (isEN ? ' /mo' : ' /' + p.pricePeriod) : '');
  const waFor = (p) =>
    `https://wa.me/${WA_PHONE}?text=` +
    encodeURIComponent(`${isEN ? 'Hi' : 'Hola'} Emiliano, ${isEN ? "I'm interested in" : 'me interesa'} "${p.title}" (${p.zone}).`);

  // Datos a pintar: propiedad real o respaldo estático
  let data;
  if (prop) {
    const specs = [];
    if (prop.bedrooms) specs.push([t.featured.beds, String(prop.bedrooms)]);
    if (prop.bathrooms) specs.push([t.featured.baths, String(prop.bathrooms)]);
    if (prop.constructionM2) specs.push([t.featured.area, prop.constructionM2 + ' m²']);
    if (prop.landM2) specs.push([t.featured.parking, prop.landM2 + ' m²']);
    data = {
      cover: prop.cover || (prop.photos && prop.photos[0]) || 'assets/featured-1.png',
      title: prop.title,
      loc: [prop.zone, prop.city].filter(Boolean).join(', '),
      desc: prop.description,
      specs: specs.slice(0, 4),
      priceLabel: opLabel(prop.operation),
      price: fmtPrice(prop),
      detailsHref: `propiedad.html?id=${encodeURIComponent(prop.id)}`,
      wa: waFor(prop),
    };
  } else {
    data = {
      cover: 'assets/featured-1.png',
      title: t.featured.name,
      loc: t.featured.loc,
      desc: t.featured.desc,
      specs: [[t.featured.beds, '4'], [t.featured.baths, '4.5'], [t.featured.area, '420 m²'], [t.featured.parking, '600 m²']],
      priceLabel: t.featured.priceLabel,
      price: '$18,500,000 MXN',
      detailsHref: '#contact',
      wa: t.about.ctaUrl,
    };
  }

  return (
    <section className="section" id="featured" data-screen-label="02 Featured" style={{ padding: "50px 0px 20px" }}>
      <div className="container">
        <div className="section-head section-head-center reveal" ref={ref} style={{ margin: "0px 0px 20px" }}>
          <h2 className="section-title" style={{ width: "650px", fontWeight: "700", fontSize: "46px" }}>
            {t.featured.title} <em style={{ color: "rgb(52, 201, 255)" }}>{t.featured.titleEm}</em>
          </h2>
          <p className="section-lead">{t.featured.lead} {mesFrase}</p>
        </div>
        <article className="featured reveal" ref={useReveal()}>
          <div className="featured-img">
            <div className="featured-tag">{t.featured.tag}</div>
            <img className="featured-photo" src={data.cover} alt={data.title} />
          </div>
          <div className="featured-body">
            <div>
              <div className="featured-loc">
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
                  <path d="M6 11s4-3.5 4-6.5a4 4 0 1 0-8 0C2 7.5 6 11 6 11Z" stroke="currentColor" strokeWidth="1" />
                  <circle cx="6" cy="4.5" r="1.3" stroke="currentColor" strokeWidth="1" />
                </svg>
                {data.loc}
              </div>
              <h3 className="featured-name">{data.title}</h3>
              <p className="featured-desc">{data.desc}</p>
              <div className="featured-specs">
                {data.specs.map(([label, value], i) => (
                  <div className="spec-item" key={i}><small>{label}</small><span>{value}</span></div>
                ))}
              </div>
            </div>
            <div className="featured-price">
              <div className="featured-price-value">
                <small>{data.priceLabel}</small>
                {data.price}
              </div>
              <div className="featured-actions">
                <a className="btn featured-cta-details" href={data.detailsHref}>{t.featured.cta}</a>
                <a className="btn featured-wa" href={data.wa} target="_blank" rel="noopener noreferrer">
                  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
                    <path d="M8 1.5a6.5 6.5 0 0 0-5.5 10L1.5 14.5l3-1A6.5 6.5 0 1 0 8 1.5Z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round" />
                    <path d="M5.8 6.4c.1 1.6 1.2 2.7 2.8 2.8.4 0 .9-.2 1-.6l.4-.7c.1-.2 0-.4-.2-.5l-.9-.4c-.2-.1-.4 0-.5.1l-.3.4c-.6-.2-1.1-.7-1.3-1.3l.4-.3c.1-.1.2-.3.1-.5l-.4-.9c-.1-.2-.3-.3-.5-.2l-.7.4c-.4.1-.6.6-.6 1 0 0 0 .4 0 .4Z" fill="currentColor" />
                  </svg>
                  {t.featured.cta2}
                </a>
              </div>
            </div>
          </div>
        </article>
      </div>
    </section>);

}

// ───────── COUNT UP ─────────
// Anima un número de 0 → target cuando entra en viewport (una sola vez).
// El target se extrae del string ("+6" → 6, "+100" → 100, "98%" → 98).
function CountUp({ value, duration = 1400 }) {
  const ref = React.useRef(null);
  const [display, setDisplay] = React.useState(value);

  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // Parse: prefijo no-numérico ("+", "$"), número, sufijo ("%", "+", " MXN")
    const m = String(value).match(/^(\D*)(\d+)([\s\S]*)$/);
    if (!m) {setDisplay(value);return;}
    const prefix = m[1];
    const target = parseInt(m[2], 10);
    const suffix = m[3];

    let started = false;
    const animate = () => {
      const t0 = performance.now();
      const tick = (now) => {
        const t = Math.min(1, (now - t0) / duration);
        const eased = 1 - Math.pow(1 - t, 3); // easeOutCubic
        const n = Math.round(target * eased);
        setDisplay(`${prefix}${n}${suffix}`);
        if (t < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    };

    setDisplay(`${prefix}0${suffix}`);
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          animate();
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [value, duration]);

  return <span ref={ref} style={{ color: "rgb(52, 201, 255)" }}>{display}</span>;
}

// (About vive ahora en about.jsx — 3 variantes)

// ───────── CONTACT MODAL ─────────
// Popup que se abre desde cualquier service row con el contexto del servicio.
function ContactModal({ open, onClose, service, t }) {
  const f = t.contact.form;
  const [form, setForm] = React.useState({ name: "", phone: "", email: "", preferred: "", message: "" });
  const [errors, setErrors] = React.useState({});

  React.useEffect(() => {
    if (!open) return;
    setForm({ name: "", phone: "", email: "", preferred: "", message: "" });
    setErrors({});
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    document.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = prev;
      document.removeEventListener('keydown', onKey);
    };
  }, [open, onClose]);

  if (!open) return null;
  const title = service?.title || '';
  const interes = ({ compra: 'compra', vende: 'venta', renta: 'renta' })[title.toLowerCase()] || title.toLowerCase();

  const set = (k, v) => { setForm((s) => ({ ...s, [k]: v })); setErrors((e) => ({ ...e, [k]: undefined })); };

  const validate = () => {
    const er = {};
    if (!RE_NAME.test(form.name.trim()) || form.name.trim().length < 2) er.name = f.errName;
    if (onlyDigits(form.phone).length < 10) er.phone = f.errPhone;
    if (!RE_EMAIL.test(form.email.trim())) er.email = f.errEmail;
    if (!form.preferred) er.preferred = f.errPreferred;
    if (!form.message.trim()) er.message = f.errMessage;
    setErrors(er);
    return Object.keys(er).length === 0;
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (!validate()) return;
    if (window.track) window.track('Lead', { content_name: interes, content_category: 'formulario_servicio' });
    openWhatsApp([
      `${f.waGreet} ${form.name.trim()}.`,
      `${f.waInterest}: ${interes} (${title})`,
      `${t.contact.phone}: ${form.phone}`,
      `${t.contact.email}: ${form.email.trim()}`,
      `${f.preferred}: ${form.preferred}`,
      `${f.message}: ${form.message.trim()}`,
    ]);
    onClose();
  };

  return (
    <div className="modal-root" role="dialog" aria-modal="true" onClick={onClose}>
      <div className="modal-backdrop" />
      <div className="modal-card" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose} aria-label="Cerrar">
          <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
            <path d="M5 5l10 10M15 5L5 15" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
          </svg>
        </button>
        <div className="modal-grid">
          <div className="modal-media" style={{ backgroundImage: `url(${service?.img || ''})` }}>
            <div className="modal-media-tag">{service?.tag}</div>
            <div className="modal-media-word">{title}</div>
          </div>
          <form className="modal-form" onSubmit={onSubmit} noValidate>
            <div className="modal-eyebrow">{t.contact.eyebrow}</div>
            <h3 className="modal-title">
              Cuéntame más sobre tu interés de <em>{interes}</em>
            </h3>

            <div className="modal-row">
              <div className="form-field">
                <label>{f.name}</label>
                <input type="text" value={form.name} onChange={(e) => set('name', e.target.value)} className={errors.name ? 'invalid' : ''} autoComplete="name" />
                {errors.name && <small className="form-err">{errors.name}</small>}
              </div>
              <div className="form-field">
                <label>{f.phoneL}</label>
                <input type="tel" inputMode="numeric" value={form.phone} onChange={(e) => set('phone', onlyDigits(e.target.value))} className={errors.phone ? 'invalid' : ''} autoComplete="tel" />
                {errors.phone && <small className="form-err">{errors.phone}</small>}
              </div>
            </div>
            <div className="modal-row">
              <div className="form-field">
                <label>{f.emailL}</label>
                <input type="email" value={form.email} onChange={(e) => set('email', e.target.value)} className={errors.email ? 'invalid' : ''} autoComplete="email" />
                {errors.email && <small className="form-err">{errors.email}</small>}
              </div>
              <div className="form-field">
                <label>{f.preferred}</label>
                <select value={form.preferred} onChange={(e) => set('preferred', e.target.value)} className={errors.preferred ? 'invalid' : ''}>
                  <option value="" disabled>—</option>
                  {f.preferredOpts.map((o, i) => <option key={i} value={o}>{o}</option>)}
                </select>
                {errors.preferred && <small className="form-err">{errors.preferred}</small>}
              </div>
            </div>
            <div className="form-field">
              <label>{f.message}</label>
              <textarea rows="3" value={form.message} onChange={(e) => set('message', e.target.value)} className={errors.message ? 'invalid' : ''} placeholder={f.messagePh}></textarea>
              {errors.message && <small className="form-err">{errors.message}</small>}
            </div>
            <div className="modal-submit">
              <small>{f.legal}</small>
              <button type="submit" className="btn btn-accent">
                {f.submit}
                <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7h10m0 0L8 3m4 4L8 11" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" /></svg>
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>);

}

// ───────── SERVICES ─────────
// 3 filas full-width: número + descripción + palabra grande.
// Hover: imagen aparece como fondo + flecha → · Click: abre modal con form.
function Services({ t, onOpenContact }) {
  const items = t.services.items;
  return (
    <section className="services-rows" id="services" data-screen-label="04 Services">
      <header className="services-rows-head">
        <div className="eyebrow">{t.services.eyebrow}</div>
        <h2 className="services-rows-title">
          Como puedo ayudarte.
        </h2>
      </header>

      <ul className="srow-list">
        {items.map((s, i) =>
        <li
          key={i}
          className="srow"
          onClick={() => onOpenContact && onOpenContact(s.title, s)}
          style={{ '--row-img': `url(${s.img})` }}>
            <div className="srow-bg" />
            <div className="srow-inner">
              <div className="srow-num">
                <span>{String(i + 1)}</span>
              </div>
              <div className="srow-desc">
                {s.desc}
              </div>
              <div className="srow-word">
                {s.title}
              </div>
              <div className="srow-arrow" aria-hidden="true">
                <svg width="64" height="32" viewBox="0 0 64 32" fill="none">
                  <path d="M2 16h58m0 0L46 2m14 14L46 30" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </div>
            </div>
          </li>
        )}
      </ul>
    </section>);
}

// ───────── BLOG ─────────
function Blog({ t }) {
  const isEN = !!(window.STRINGS && t === window.STRINGS.en);
  const lang = isEN ? "en" : "es";
  const [posts, setPosts] = React.useState(null);

  React.useEffect(() => {
    let alive = true;
    const fallback = window.POSTS || [];
    if (window.ECDB && ECDB.isConfigured()) {
      ECDB.loadPublicPosts()
        .then((list) => { if (alive) setPosts(list && list.length ? list : fallback); })
        .catch(() => { if (alive) setPosts(fallback); });
    } else {
      setPosts(fallback);
    }
    return () => { alive = false; };
  }, []);

  const pick = (p, base) => (p[base + "_" + lang] || p[base + "_es"] || p[base + "_en"] || "");
  const fmtD = (iso) => {
    if (!iso) return "";
    const d = new Date(iso + "T00:00:00");
    if (isNaN(d.getTime())) return iso;
    return d.toLocaleDateString(isEN ? "en-US" : "es-MX", { year: "numeric", month: "short", day: "numeric" });
  };
  const readTxt = (p) => (p.readMinutes ? p.readMinutes + (isEN ? " min read" : " min de lectura") : "");

  const list = (posts || []).slice(0, 3);

  return (
    <section className="section" id="blog" data-screen-label="05 Blog">
      <div className="container">
        <div className="section-head reveal" ref={useReveal()}>
          <h2 className="section-title">
            {t.blog.title} <em style={{ color: "rgb(52, 201, 255)" }}>{t.blog.titleEm}</em> {t.blog.title2}
          </h2>
          <p className="section-lead">{t.blog.lead}</p>
        </div>
        <div className="blog-grid">
          {list.map((p, i) => (
            <a className="blog-card" key={p.id || i} href={`nota.html?slug=${encodeURIComponent(p.id)}&lang=${lang}`}>
              <div className="blog-img" style={p.cover ? { backgroundImage: `url(${p.cover})`, backgroundSize: "cover", backgroundPosition: "center" } : null} />
              <div className="blog-cat">{pick(p, "category")}</div>
              <h3 className="blog-title">{pick(p, "title")}</h3>
              <div className="blog-meta">
                <span>{fmtD(p.publishedAt)}</span>
                {readTxt(p) && <><span>·</span><span>{readTxt(p)}</span></>}
              </div>
            </a>
          ))}
        </div>
        <div className="blog-all">
          <a href="blog.html" className="btn btn-ghost">
            {t.blog.all}
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7h10m0 0L8 3m4 4L8 11" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" /></svg>
          </a>
        </div>
      </div>
    </section>);

}

// ───────── CONTACT HERO ─────────
function ContactHero({ t, onContact }) {
  return (
    <section className="contact-hero" id="contact" data-screen-label="06 Contact" style={{ height: "443px", padding: "128px 32px" }}>
      <div className="contact-hero-inner reveal" ref={useReveal()}>
        <h2 className="contact-headline">
          {t.contact.headline1} <em>{t.contact.headlineEm}</em> {t.contact.headline2}
        </h2>
        <a className="btn contact-cta-btn contact-cta-wa" href={t.about.ctaUrl} target="_blank" rel="noopener noreferrer">
          <svg width="17" height="17" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M8 1.5a6.5 6.5 0 0 0-5.5 10L1.5 14.5l3-1A6.5 6.5 0 1 0 8 1.5Z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round" /></svg>
          {t.contact.form.submit}
        </a>
      </div>
    </section>);

}

// ───────── BASIC CONTACT MODAL ─────────
// Popup minimalista de contacto, abierto desde el botón "Enviar mensaje".
function BasicContactModal({ open, onClose, t }) {
  const f = t.contact.form;
  const [sent, setSent] = React.useState(false);
  const [form, setForm] = React.useState({ name: "", phone: "", message: "" });
  const [errors, setErrors] = React.useState({});

  React.useEffect(() => {
    if (!open) return;
    setSent(false);
    setForm({ name: "", phone: "", message: "" });
    setErrors({});
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    document.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = prev;
      document.removeEventListener('keydown', onKey);
    };
  }, [open, onClose]);

  if (!open) return null;

  const set = (k, v) => { setForm((s) => ({ ...s, [k]: v })); setErrors((e) => ({ ...e, [k]: undefined })); };

  const validate = () => {
    const er = {};
    if (!RE_NAME.test(form.name.trim()) || form.name.trim().length < 2) er.name = f.errName;
    if (onlyDigits(form.phone).length < 10) er.phone = f.errPhone;
    setErrors(er);
    return Object.keys(er).length === 0;
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (!validate()) return;
    if (window.track) window.track('Lead', { content_category: 'formulario_contacto' });
    openWhatsApp([
      `${f.waGreet} ${form.name.trim()}.`,
      `${t.contact.phone}: ${form.phone}`,
      form.message.trim() ? `${f.message}: ${form.message.trim()}` : "",
    ]);
    setSent(true);
  };

  return (
    <div className="bcm-root" role="dialog" aria-modal="true" onClick={onClose}>
      <div className="bcm-backdrop" />
      <div className="bcm-card" onClick={(e) => e.stopPropagation()}>
        <button className="bcm-close" onClick={onClose} aria-label="Cerrar">
          <svg width="18" height="18" viewBox="0 0 20 20" fill="none"><path d="M5 5l10 10M15 5L5 15" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" /></svg>
        </button>
        {sent ?
        <div className="bcm-done">
            <div className="bcm-done-ico" aria-hidden="true">
              <svg width="26" height="26" viewBox="0 0 24 24" fill="none"><path d="M5 12.5l4.5 4.5L19 7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /></svg>
            </div>
            <h3 className="bcm-title">{f.thanks}</h3>
            <p className="bcm-lead">{f.waNote}</p>
            <button className="btn btn-accent" onClick={onClose}>{f.doneBtn}</button>
          </div> :

        <form className="bcm-form" onSubmit={onSubmit} noValidate>
            <div className="bcm-eyebrow">{t.contact.eyebrow}</div>
            <h3 className="bcm-title">{f.submit}</h3>
            <div className="form-field">
              <label>{f.name}</label>
              <input type="text" value={form.name} onChange={(e) => set('name', e.target.value)} className={errors.name ? 'invalid' : ''} autoComplete="name" placeholder="—" />
              {errors.name && <small className="form-err">{errors.name}</small>}
            </div>
            <div className="form-field">
              <label>{f.phoneL}</label>
              <input type="tel" inputMode="numeric" value={form.phone} onChange={(e) => set('phone', onlyDigits(e.target.value))} className={errors.phone ? 'invalid' : ''} autoComplete="tel" placeholder="—" />
              {errors.phone && <small className="form-err">{errors.phone}</small>}
            </div>
            <div className="form-field">
              <label>{f.message}</label>
              <textarea rows="3" value={form.message} onChange={(e) => set('message', e.target.value)} placeholder={f.messagePh}></textarea>
            </div>
            <button type="submit" className="btn btn-accent bcm-submit">
              {f.submit}
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7h10m0 0L8 3m4 4L8 11" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /></svg>
            </button>
            <small className="bcm-legal">{f.legal}</small>
          </form>
        }
      </div>
    </div>);

}

// ───────── FOOTER ─────────
function Footer({ t }) {
  return (
    <footer className="footer" style={{ padding: "50px 0px" }}>
      <div className="container">
        <div className="footer-grid">
          <div>
            <div className="footer-brand">Emiliano Centenero</div>
            <p className="footer-tag">{t.footer.tag}</p>
          </div>
          <div className="footer-col">
            <h5>{t.footer.navigate}</h5>
            <ul>
              <li><a href="#featured">{t.nav.featured}</a></li>
              <li><a href="#about">{t.nav.about}</a></li>
              <li><a href="#services">{t.nav.services}</a></li>
              <li><a href="#blog">{t.nav.blog}</a></li>
            </ul>
          </div>
          <div className="footer-col">
            <h5>{t.footer.services}</h5>
            <ul>
              <li><a href="#services">{t.services.items[0].title}</a></li>
              <li><a href="#services">{t.services.items[1].title}</a></li>
              <li><a href="#services">{t.services.items[2].title}</a></li>
            </ul>
          </div>
          <div className="footer-col">
            <h5>{t.footer.contact}</h5>
            <ul>
              <li><a href={t.about.ctaUrl} target="_blank" rel="noopener noreferrer">WhatsApp</a></li>
              <li><a href="mailto:ecentenero@hotmail.com">ecentenero@hotmail.com</a></li>
              <li>{t.footer.addr}</li>
              <li>{t.footer.hours}</li>
            </ul>
          </div>
        </div>
        <div className="footer-bottom">
          <span>{t.footer.copy}</span>
          <div className="footer-socials">
            <a href="https://www.youtube.com/@emiliano_centenero" target="_blank" rel="noopener noreferrer" aria-label="YouTube">
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <rect x="1.5" y="3.5" width="13" height="9" rx="2.5" stroke="currentColor" strokeWidth="1.2" />
                <path d="M6.8 6.2v3.6l3.1-1.8-3.1-1.8Z" fill="currentColor" />
              </svg>
            </a>
            <a href="https://www.instagram.com/emiliano_centenero" target="_blank" rel="noopener noreferrer" aria-label="Instagram">
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <rect x="2" y="2" width="12" height="12" rx="3" stroke="currentColor" strokeWidth="1.2" />
                <circle cx="8" cy="8" r="2.5" stroke="currentColor" strokeWidth="1.2" />
                <circle cx="11.5" cy="4.5" r="0.7" fill="currentColor" />
              </svg>
            </a>
            <a href="https://www.tiktok.com/@ecentenero" target="_blank" rel="noopener noreferrer" aria-label="TikTok">
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <path d="M10.5 2v1.5a3.3 3.3 0 0 0 3.3 3.3v1.6a4.8 4.8 0 0 1-3.3-1.3v4.2a3.6 3.6 0 1 1-3.6-3.6c.2 0 .4 0 .6.05V9.3a2 2 0 1 0 1.4 1.9V2h1.6Z" fill="currentColor" />
              </svg>
            </a>
            <a href="https://www.linkedin.com/in/ecentenero/" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn">
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" strokeWidth="1.2" />
                <path d="M5 7v5M5 5.3v.1M8 12V7m0 0c0-.5.5-1.2 1.5-1.2S11 6.5 11 7.5V12" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />
              </svg>
            </a>
            <a href="https://x.com/EmilianoCentGTZ" target="_blank" rel="noopener noreferrer" aria-label="X">
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                <path d="M3 3l4.2 5.6L3.2 13H4.6l3.3-3.6L10.6 13H13L8.6 7.1 12.4 3H11l-2.9 3.2L5.7 3H3Z" fill="currentColor" />
              </svg>
            </a>
          </div>
          <a href="aviso-privacidad.html" style={{ color: 'var(--ink-3)' }}>{t.footer.privacy}</a>
        </div>
      </div>
    </footer>);

}

Object.assign(window, { Nav, Featured, Services, ContactModal, Blog, ContactHero, BasicContactModal, Footer, useReveal, CountUp });