/* Delto Web 2.0 — Main Application Components
   Nav, Hero (with WhatsApp live demo), Sections, Footer
*/

// Wrap the whole shell.jsx in an IIFE so useState/useEffect stay local and
// don't collide with tweaks-panel.jsx which also declares them globally.
(function() {
const { useState, useEffect, useLayoutEffect, useRef, useMemo } = React;

/* ================================================
   MOTION HOOKS
   ================================================ */
const PREFERS_REDUCED_MOTION =
  typeof window !== 'undefined' &&
  window.matchMedia &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;

function useReveal() {
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) {
      document.querySelectorAll('.reveal').forEach(el => el.classList.add('in'));
      return;
    }

    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });

    const observeAll = () => {
      document.querySelectorAll('.reveal:not(.in)').forEach(el => {
        const r = el.getBoundingClientRect();
        if (r.top < window.innerHeight * 0.92 && r.bottom > 0) {
          el.classList.add('in');
        } else {
          io.observe(el);
        }
      });
    };

    requestAnimationFrame(() => requestAnimationFrame(observeAll));

    const mo = new MutationObserver(() => observeAll());
    mo.observe(document.body, { childList: true, subtree: true });

    const failsafe = setTimeout(() => {
      document.querySelectorAll('.reveal:not(.in)').forEach(el => el.classList.add('in'));
    }, 2500);

    return () => { io.disconnect(); mo.disconnect(); clearTimeout(failsafe); };
  }, []);
}

/* useScrollProgress — writes 0..1 progress as `--scroll-p` on the
   target element while it intersects the viewport. Useful for
   pinned scrolly-telling and progress bars in upcoming rounds. */
function useScrollProgress(ref, { start = 0, end = 1 } = {}) {
  useEffect(() => {
    const el = ref.current;
    if (!el || PREFERS_REDUCED_MOTION) return;
    let raf = 0;
    const update = () => {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      const total = r.height + vh;
      const traveled = vh - r.top;
      let p = traveled / total;
      p = Math.max(0, Math.min(1, p));
      p = start + (end - start) * p;
      el.style.setProperty('--scroll-p', p.toFixed(4));
      raf = 0;
    };
    const onScroll = () => {
      if (!raf) raf = requestAnimationFrame(update);
    };
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [ref, start, end]);
}

/* Section — semantic wrapper that picks a tone class. Keeps
   index.html short and enforces the "no two consecutive sections
   share a tone" rule by making it explicit at the call site.    */
function Section({ tone = 'white', id, className = '', children, grain = false, ...rest }) {
  const toneClass =
    tone === 'dark'        ? 'on-dark' :
    tone === 'dark-deep'   ? 'on-dark-deep' :
    tone === 'sand'        ? 'on-sand' :
    tone === 'sand-soft'   ? 'on-sand-soft' :
    tone === 'lilac'       ? 'on-lilac' :
    tone === 'lilac-deep'  ? 'on-lilac-deep' :
    tone === 'cream'       ? 'on-cream' :
    '';
  return (
    <section
      id={id}
      className={`sect ${toneClass} ${grain ? 'bg-grain' : ''} ${className}`.trim()}
      {...rest}
    >
      <div className="sect-inner">{children}</div>
    </section>
  );
}

/* ================================================
   LANG CONTEXT (global via window)
   ================================================ */
function useLang() {
  const [lang, setLang] = useState(() => localStorage.getItem('delto-lang') || 'es');
  useEffect(() => {
    localStorage.setItem('delto-lang', lang);
    document.documentElement.lang = lang;
  }, [lang]);
  const t = window.DELTO_I18N[lang];
  return { lang, setLang, t };
}

/* ================================================
   NAV
   ================================================ */
function Nav({ lang, setLang, t, onHeroStyleChange }) {
  const [scrolled, setScrolled] = useState(false);
  const [openMenu, setOpenMenu] = useState(null);
  const [mobileOpen, setMobileOpen] = useState(false);
  const [mobileProductOpen, setMobileProductOpen] = useState(false);
  const closeTimerRef = useRef(null);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // Debounced close so the user can move the mouse from the trigger
  // button across the nav padding into the mega without flickering.
  const openMega = (which) => {
    if (closeTimerRef.current) { clearTimeout(closeTimerRef.current); closeTimerRef.current = null; }
    setOpenMenu(which);
  };
  const scheduleCloseMega = () => {
    if (closeTimerRef.current) clearTimeout(closeTimerRef.current);
    closeTimerRef.current = setTimeout(() => setOpenMenu(null), 220);
  };

  // Lock body scroll while mobile drawer is open
  useEffect(() => {
    document.body.style.overflow = mobileOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [mobileOpen]);

  const closeMobile = () => { setMobileOpen(false); setMobileProductOpen(false); };

  const agents = [
    {
      key: 'collections', icon: <IconCoin size={22} stroke={1.6} />,
      name: 'Collections', d: 'Cobranzas 24/7 con plan de pago',
      capabilities: [
        { t: 'Plan de pago', d: 'Negociación automática en 3 o 6 cuotas, sin intereses', badge: 'OUTBOUND' },
        { t: 'Follow-up < 24 hs', d: 'Recupero proactivo del compromiso de pago' },
        { t: 'RAG sobre políticas', d: 'Lee la normativa interna del banco antes de ofrecer' },
        { t: 'Reporting al CRM', d: 'Salesforce, Genesys, Zendesk — sincronización en tiempo real' },
      ],
    },
    {
      key: 'advisor', icon: <IconSparkles size={22} stroke={1.6} />,
      name: 'Advisor', d: 'Ventas 24/7 con personalización IA',
      capabilities: [
        { t: 'Personalización inteligente', d: 'Producto + límite + precio según el cliente', badge: 'IA' },
        { t: 'Follow-up de abandono', d: 'Re-engage automático en menos de 24 horas' },
        { t: 'Pre-aprobado en chat', d: 'Acepta y emite tarjeta sin salir de WhatsApp' },
        { t: 'RAG sobre catálogo', d: 'Conoce el portfolio comercial completo' },
      ],
    },
    {
      key: 'support', icon: <IconHeadphones size={22} stroke={1.6} />,
      name: 'Customer Support', d: '+300 razones de contacto resueltas',
      capabilities: [
        { t: '+300 razones de contacto', d: 'Bloqueo, reclamos, consultas, tarjeta virtual y más' },
        { t: 'Integración nativa', d: 'Salesforce · Zendesk · Genesys', badge: 'CRM' },
        { t: 'Aviso proactivo de tickets', d: 'Notifica cambios de estado sin que el cliente pregunte' },
        { t: 'RAG sobre KB', d: 'Conoce procedimientos y FAQs del banco' },
      ],
    },
    {
      key: 'retail', icon: <IconCreditCard size={22} stroke={1.6} />,
      name: 'Retail Banking', d: 'Transaccionalidad total en chat',
      capabilities: [
        { t: 'Transacciones en chat', d: 'Pagos, transferencias, recargas — todo en el mensaje', badge: 'CORE' },
        { t: 'Tarjetas + cuentas', d: 'Saldo, movimientos, bloqueo, virtuales — en tiempo real' },
        { t: 'Pagos automáticos', d: 'Vencimientos avisados y resueltos sin app' },
        { t: 'RAG sobre productos', d: 'Comparativos y recomendaciones contextuales' },
      ],
    },
    {
      key: 'corporate', icon: <IconBriefcase size={22} stroke={1.6} />,
      name: 'Corporate Banking', d: '+40 skills con permisos por rol',
      capabilities: [
        { t: '+40 skills corporativas', d: 'FX, transferencias, conciliación, reportes ejecutivos', badge: 'B2B' },
        { t: 'Permisos por rol', d: 'Tesorero, contador, CEO — cada uno ve lo que debe' },
        { t: 'Integración core', d: 'Conexión nativa a SAP, Oracle, sistemas internos' },
        { t: 'RAG sobre normativa', d: 'Compliance corporativo siempre presente' },
      ],
    },
  ];
  const [activeAgent, setActiveAgent] = useState(0);
  const a = agents[activeAgent];

  return (
    <>
    <nav className={`nav ${scrolled ? 'scrolled' : ''} ${mobileOpen ? 'mobile-open' : ''}`}>
      <div className="nav-left">
        <a href="/" aria-label="Delto" onClick={closeMobile}>
          <img src="/assets/logos/delto-logo-white-full.svg" alt="Delto" className="nav-logo" />
        </a>
        <div className="nav-links">
          <div className="nav-link-wrap"
               onMouseEnter={() => openMega('agents')}
               onMouseLeave={scheduleCloseMega}>
            <button className="nav-link">
              {t.nav.ai_agents} <IconChevron size={12} stroke={2} />
            </button>
          </div>
          <a href="/platform.html" className="nav-link">{t.nav.platform}</a>
          <a href="/technology.html" className="nav-link">{t.nav.tech}</a>
          <a href="/nosotros.html" className="nav-link">{t.nav.about}</a>
          <a href="/blog.html" className="nav-link">{t.nav.blog}</a>
        </div>
      </div>
      <div className="nav-right">
        <div className="lang-pick">
          {['es', 'en', 'pt'].map(l => (
            <button key={l} onClick={() => setLang(l)} className={`lang-opt ${lang === l ? 'active' : ''}`}>
              {l.toUpperCase()}
            </button>
          ))}
        </div>
        <a href="#" className="nav-signin">{t.nav.signin}</a>
        <a href="#demo" className="btn-demo">
          {t.nav.demo} <IconArrowRight size={14} stroke={2.5} className="arrow" />
        </a>
      </div>

      {/* Hamburger toggle (mobile only) */}
      <button
        className="nav-burger"
        aria-label={mobileOpen ? 'Cerrar menú' : 'Abrir menú'}
        aria-expanded={mobileOpen}
        onClick={() => setMobileOpen(o => !o)}
      >
        <span /><span /><span />
      </button>

      {/* Mobile drawer */}
      <div className={`nav-drawer ${mobileOpen ? 'open' : ''}`} role="dialog" aria-modal="true">
        <div className="nav-drawer-inner">
          <div className="nav-drawer-section">
            <button
              className={`nav-drawer-link nav-drawer-toggle ${mobileProductOpen ? 'open' : ''}`}
              onClick={() => setMobileProductOpen(o => !o)}
              aria-expanded={mobileProductOpen}
            >
              <span>{t.nav.ai_agents}</span>
              <IconChevron size={14} stroke={2} />
            </button>
            {mobileProductOpen && (
              <div className="nav-drawer-products">
                {agents.map(a => (
                  <a key={a.key} href={`/agents/${a.key}.html`} className="nav-drawer-product" onClick={closeMobile}>
                    <span className="nav-drawer-product-ico">{a.icon}</span>
                    <span>
                      <span className="nav-drawer-product-t">{a.name}</span>
                      <span className="nav-drawer-product-d">{a.d}</span>
                    </span>
                  </a>
                ))}
              </div>
            )}
            <a href="/platform.html" className="nav-drawer-link" onClick={closeMobile}>{t.nav.platform}</a>
            <a href="/technology.html" className="nav-drawer-link" onClick={closeMobile}>{t.nav.tech}</a>
            <a href="/nosotros.html" className="nav-drawer-link" onClick={closeMobile}>{t.nav.about}</a>
            <a href="/blog.html" className="nav-drawer-link" onClick={closeMobile}>{t.nav.blog}</a>
          </div>

          <div className="nav-drawer-foot">
            <a href="#demo" className="btn-demo nav-drawer-cta" onClick={closeMobile}>
              {t.nav.demo} <IconArrowRight size={14} stroke={2.5} className="arrow" />
            </a>
            <a href="#" className="nav-drawer-signin" onClick={closeMobile}>{t.nav.signin}</a>
            <div className="lang-pick nav-drawer-lang">
              {['es', 'en', 'pt'].map(l => (
                <button key={l} onClick={() => setLang(l)} className={`lang-opt ${lang === l ? 'active' : ''}`}>
                  {l.toUpperCase()}
                </button>
              ))}
            </div>
          </div>
        </div>
      </div>
    </nav>

    {/* AI Agents mega — rendered as nav sibling so it sits above
        the hero phone's stacking context (nav has backdrop-filter
        which would isolate it otherwise). 3-col layout inspired by
        akua.la / stripe / vercel mega menus. */}
    <div
      className={`mega-agents ${openMenu === 'agents' ? 'open' : ''}`}
      onMouseEnter={() => openMega('agents')}
      onMouseLeave={scheduleCloseMega}
    >
      <div className="mega-agents-inner">
        <div className="mega-agents-cols">
          {/* LEFT — Agent list */}
          <div className="mega-col mega-col-l">
            {agents.map((ag, i) => (
              <a
                key={ag.key}
                href={`/agents/${ag.key}.html`}
                className={`mega-agent-item ${i === activeAgent ? 'active' : ''}`}
                onMouseEnter={() => setActiveAgent(i)}
                onClick={() => setOpenMenu(null)}
              >
                <span className="mega-agent-item-ico">{ag.icon}</span>
                <span className="mega-agent-item-txt">
                  <span className="mega-agent-item-n">{ag.name}</span>
                  <span className="mega-agent-item-d">{ag.d}</span>
                </span>
              </a>
            ))}
          </div>

          {/* CENTER — Capabilities of the active agent */}
          <div className="mega-col mega-col-c">
            <div className="mega-cap-head">
              <span className="mega-cap-name">{a.name}</span>
              <span className="mega-cap-tag">{a.d}</span>
            </div>
            <div className="mega-cap-list">
              {a.capabilities.map((c, i) => (
                <a key={i} href="#agents" className="mega-cap">
                  <span className="mega-cap-t">
                    {c.t}
                    {c.badge && <span className="mega-cap-badge">{c.badge}</span>}
                  </span>
                  <span className="mega-cap-d">{c.d}</span>
                </a>
              ))}
            </div>
          </div>

          {/* RIGHT — Featured cases + resources */}
          <div className="mega-col mega-col-r">
            <div className="mega-side-head">Casos destacados</div>
            <a href="#customers" className="mega-side-card">
              <div className="mega-side-card-thumb mega-thumb-ficohsa">
                <span>FH</span>
              </div>
              <div className="mega-side-card-txt">
                <div className="mega-side-card-t">Ficohsa</div>
                <div className="mega-side-card-d">+60 skills · 4 países · +4M clientes</div>
              </div>
            </a>
            <a href="#customers" className="mega-side-card">
              <div className="mega-side-card-thumb mega-thumb-banreservas">
                <span>BR</span>
              </div>
              <div className="mega-side-card-txt">
                <div className="mega-side-card-t">Banreservas</div>
                <div className="mega-side-card-d">+45 skills · banco estatal · +1M clientes</div>
              </div>
            </a>

            <div className="mega-side-head mega-side-head-2">Recurso destacado</div>
            <a href="/blog.html" className="mega-side-feature">
              <div className="mega-side-feature-eyebrow">INSIGHTS · 2026</div>
              <div className="mega-side-feature-t">El estado de la banca conversacional en LATAM</div>
              <div className="mega-side-feature-cta">Leer reporte →</div>
            </a>
          </div>
        </div>

        {/* Bottom feature strip */}
        <div className="mega-agents-foot">
          <span className="mega-foot-pill">
            <span className="mega-foot-dot" /> 5 agentes pre-entrenados — listos para tu banco
          </span>
          <span className="mega-foot-pill">
            <span className="mega-foot-dot mega-foot-dot-lilac" /> WhatsApp · Web · Voice — un mismo agente, todos los canales
          </span>
          <span className="mega-foot-pill mega-foot-pill-new">NUEVO · Voice agents en GA</span>
        </div>
      </div>
    </div>
    </>
  );
}

/* ================================================
   HERO — 3 styles (A: WhatsApp phone, B: WebChat, C: Split)
   ================================================ */

// WhatsApp phone — realistic conversation, typed progressively.
// Accepts an optional `script` and `header` to override the default,
// so the same phone frame can be reused as the navigable example
// of multiple agents (collections, fraud, onboarding…).
const DEFAULT_WA_SCRIPTS = {
  es: [
    { from: 'bot', t: '¡Hola Ana! Soy Sofía, tu asistente de Banco Andes.', delay: 400 },
    { from: 'bot', t: 'Vi que tu tarjeta Visa vence en 2 días. ¿Querés pagarla ahora?', delay: 1200 },
    { from: 'user', t: 'Sí, dale', delay: 2200 },
    { from: 'bot', t: '', card: { type: 'payment' }, delay: 1000 },
    { from: 'user', t: 'Pagá todo', delay: 1800 },
    { from: 'bot', t: '✓ Listo. $17.847 debitados de tu Caja de Ahorro.', delay: 1400 },
    { from: 'bot', t: 'Comprobante enviado por email. ¿Algo más?', delay: 900 },
  ],
  en: [
    { from: 'bot', t: 'Hi Ana! I\'m Sofia, your Banco Andes assistant.', delay: 400 },
    { from: 'bot', t: 'Your Visa card is due in 2 days. Want to pay it now?', delay: 1200 },
    { from: 'user', t: 'Yes, go ahead', delay: 2200 },
    { from: 'bot', t: '', card: { type: 'payment' }, delay: 1000 },
    { from: 'user', t: 'Pay full balance', delay: 1800 },
    { from: 'bot', t: '✓ Done. $17,847 debited from your Savings.', delay: 1400 },
    { from: 'bot', t: 'Receipt sent to your email. Anything else?', delay: 900 },
  ],
  pt: [
    { from: 'bot', t: 'Olá Ana! Sou a Sofia, sua assistente do Banco Andes.', delay: 400 },
    { from: 'bot', t: 'Seu cartão Visa vence em 2 dias. Quer pagar agora?', delay: 1200 },
    { from: 'user', t: 'Sim, pode ir', delay: 2200 },
    { from: 'bot', t: '', card: { type: 'payment' }, delay: 1000 },
    { from: 'user', t: 'Pagar total', delay: 1800 },
    { from: 'bot', t: '✓ Pronto. R$17.847 debitados da sua Poupança.', delay: 1400 },
    { from: 'bot', t: 'Comprovante enviado por email. Mais alguma coisa?', delay: 900 },
  ],
};

function WhatsAppDemo({ lang, script, header, scriptKey }) {
  const msgs = script || DEFAULT_WA_SCRIPTS[lang] || DEFAULT_WA_SCRIPTS.es;
  const head = header || { brand: 'Banco Andes', status: 'en línea', initial: 'BA' };
  const [visible, setVisible] = useState(0);
  const [typing, setTyping] = useState(false);

  useEffect(() => {
    let cancelled = false;
    let i = 0;
    setVisible(0);
    setTyping(false);
    async function run() {
      // Brief intro pause when script changes — feels intentional.
      await new Promise(r => setTimeout(r, 250));
      while (!cancelled) {
        if (i >= msgs.length) {
          await new Promise(r => setTimeout(r, 4000));
          if (cancelled) return;
          i = 0;
          setVisible(0);
          continue;
        }
        const m = msgs[i];
        if (m.from === 'bot' && m.t) {
          setTyping(true);
          await new Promise(r => setTimeout(r, Math.min(m.delay || 800, 1100)));
          if (cancelled) return;
          setTyping(false);
          await new Promise(r => setTimeout(r, 120));
          if (cancelled) return;
        } else {
          await new Promise(r => setTimeout(r, m.delay || 1400));
          if (cancelled) return;
        }
        setVisible(v => v + 1);
        i++;
      }
    }
    run();
    return () => { cancelled = true; };
    // scriptKey lets parents force a restart without changing object identity
  }, [lang, scriptKey, msgs]);

  return (
    <div className="wa-phone">
      <div className="wa-notch"></div>
      <div className="wa-screen">
        <div className="wa-header">
          <button className="wa-back">‹</button>
          <div className="wa-avatar">
            {head.initial && <span className="wa-avatar-i">{head.initial}</span>}
            <div className="wa-avatar-dot"></div>
          </div>
          <div className="wa-contact">
            <div className="wa-name">{head.brand}</div>
            <div className="wa-status">
              <span className="wa-online-dot"></span>
              {head.status || 'en línea'}
            </div>
          </div>
          <div className="wa-icons">
            <span>📞</span>
            <span>⋮</span>
          </div>
        </div>
        <div className="wa-chat">
          <div className="wa-date"><span>HOY</span></div>
          {msgs.slice(0, visible).map((m, i) => (
            <Bubble key={`${scriptKey || 'd'}-${i}`} msg={m} />
          ))}
          {typing && visible < msgs.length && msgs[visible]?.from === 'bot' && msgs[visible]?.t && (
            <div className="wa-bubble wa-bot wa-typing">
              <span></span><span></span><span></span>
            </div>
          )}
        </div>
        <div className="wa-input">
          <span className="wa-input-ic">+</span>
          <div className="wa-input-field">Mensaje</div>
          <span className="wa-input-ic">🎤</span>
        </div>
      </div>
    </div>
  );
}

function Bubble({ msg }) {
  if (msg.card?.type === 'payment') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-pay-card">
          <div className="wa-pay-head">
            <div className="wa-pay-brand">VISA</div>
            <div className="wa-pay-num">•••• 4457</div>
          </div>
          <div className="wa-pay-amount">{msg.card.amount || '$17.847,00'}</div>
          <div className="wa-pay-meta">
            <div><span>Vencimiento</span><b>{msg.card.due || 'Vie 26 Abr'}</b></div>
            <div><span>Mínimo</span><b>{msg.card.min || '$2.340'}</b></div>
          </div>
          <div className="wa-pay-cta">
            <button className="wa-pay-btn wa-pay-min">Pagar mínimo</button>
            <button className="wa-pay-btn wa-pay-full">Pagar todo</button>
          </div>
        </div>
      </div>
    );
  }
  // Collections — credit card overdue summary
  if (msg.card?.type === 'progress') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-mini-card wa-card-progress">
          <div className="wa-mc-eyebrow">Tarjeta Visa ···4127</div>
          <div className="wa-mc-row"><span>Vencimiento</span><b>26 Sep</b></div>
          <div className="wa-mc-row"><span>Días de atraso</span><b className="bad">12 días</b></div>
          <div className="wa-mc-row"><span>Saldo vencido</span><b>$42.300</b></div>
          <div className="wa-mc-row"><span>Total a regularizar</span><b>$45.180</b></div>
        </div>
      </div>
    );
  }
  // Advisor — pre-approved card offer
  if (msg.card?.type === 'preapproved') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-mini-card wa-card-preapproved">
          <div className="wa-mc-tag">PRE-APROBADA</div>
          <div className="wa-mc-amount">Turing Signature</div>
          <div className="wa-mc-row"><span>Límite recomendado</span><b>$150.000</b></div>
          <div className="wa-mc-row"><span>Costo anual</span><b>$0 el primer año</b></div>
          <div className="wa-mc-row"><span>Cashback</span><b>2%</b></div>
        </div>
      </div>
    );
  }
  // Customer Support — actions card
  if (msg.card?.type === 'actions') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-mini-card wa-card-actions">
          <div className="wa-mc-eyebrow">Acciones disponibles</div>
          <div className="wa-mc-row"><span>🔒 Bloquear tarjeta</span><b className="hi">Recomendado</b></div>
          <div className="wa-mc-row"><span>🏠 Reimpresión a domicilio</span><b>$0</b></div>
          <div className="wa-mc-row"><span>💳 Tarjeta virtual inmediata</span><b>Incluida</b></div>
        </div>
      </div>
    );
  }
  // Retail Banking — bill card (UTE example)
  if (msg.card?.type === 'bill') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-mini-card wa-card-bill">
          <div className="wa-mc-eyebrow">Factura UTE (Luz)</div>
          <div className="wa-mc-row"><span>N° de cuenta</span><b>···4321</b></div>
          <div className="wa-mc-row"><span>Vencimiento</span><b>25 Oct</b></div>
          <div className="wa-mc-row"><span>Monto a pagar</span><b>$2.180</b></div>
        </div>
      </div>
    );
  }
  // Corporate Banking — dark card with disponible
  if (msg.card?.type === 'corp') {
    return (
      <div className="wa-bubble wa-bot wa-card-wrap">
        <div className="wa-mini-card wa-card-corp">
          <div className="wa-mc-corp-t">Tarjeta Corporativa Visa</div>
          <div className="wa-mc-corp-num">···· ···· ···· 4015</div>
          <div className="wa-mc-corp-lbl">Disponible hoy</div>
          <div className="wa-mc-corp-amt">$985.300</div>
          <div className="wa-mc-corp-of">de $1.500.000</div>
        </div>
      </div>
    );
  }
  // Voice note bubble — supports both bot and user.
  // The waveform is generated from a deterministic pattern so the
  // bars look organic without being random per render.
  if (msg.voice) {
    const heights = [38, 60, 82, 95, 70, 55, 40, 60, 88, 75, 50, 35, 55, 85, 92, 70, 45, 60, 80, 65, 42, 55, 70, 50];
    return (
      <div className={`wa-bubble wa-${msg.from} wa-voice`}>
        <span className="wa-voice-play" aria-hidden>▶</span>
        <span className="wa-voice-wave">
          {heights.map((h, i) => (
            <span key={i} style={{ height: `${h}%` }}></span>
          ))}
        </span>
        <span className="wa-voice-dur">{msg.voice.dur || '0:08'}</span>
        {msg.from === 'user' && <span className="wa-ticks">✓✓</span>}
      </div>
    );
  }
  return (
    <div className={`wa-bubble wa-${msg.from}`}>
      {msg.t}
      {msg.from === 'user' && <span className="wa-ticks">✓✓</span>}
    </div>
  );
}

/* ─────────── WebChatTuring (Turing Bank style — slide 4 of deck) ─────────── */
function WebChatTuring({ lang, script, header, scriptKey }) {
  const msgs = script || DEFAULT_WA_SCRIPTS[lang] || DEFAULT_WA_SCRIPTS.es;
  const head = header || { brand: 'Turing Bank' };
  const [visible, setVisible] = useState(0);
  const [typing, setTyping] = useState(false);

  useEffect(() => {
    let cancelled = false;
    let i = 0;
    setVisible(0);
    setTyping(false);
    async function run() {
      await new Promise(r => setTimeout(r, 250));
      while (!cancelled) {
        if (i >= msgs.length) {
          await new Promise(r => setTimeout(r, 4000));
          if (cancelled) return;
          i = 0;
          setVisible(0);
          continue;
        }
        const m = msgs[i];
        if (m.from === 'bot' && m.t) {
          setTyping(true);
          await new Promise(r => setTimeout(r, Math.min(m.delay || 800, 1100)));
          if (cancelled) return;
          setTyping(false);
          await new Promise(r => setTimeout(r, 120));
        } else {
          await new Promise(r => setTimeout(r, m.delay || 1400));
        }
        if (cancelled) return;
        setVisible(v => v + 1);
        i++;
      }
    }
    run();
    return () => { cancelled = true; };
  }, [lang, scriptKey, msgs]);

  // "Turing Bank" → "Turing" + boxed "Bank"
  const brandParts = (head.brand || 'Turing Bank').split(' ');
  const brandHead = brandParts[0];
  const brandTag  = brandParts.slice(1).join(' ');

  return (
    <div className="wct-phone">
      <div className="wct-screen">
        <div className="wct-orb"></div>
        <div className="wct-notch"></div>
        <div className="wct-status">
          <span>9:41</span>
          <span>•••</span>
        </div>
        <div className="wct-header">
          <div className="wct-header-orb"></div>
          <div className="wct-brand">
            {brandHead}{brandTag && <> <span>{brandTag}</span></>}
          </div>
          <button className="wct-x" aria-label="Cerrar">×</button>
        </div>
        <div className="wct-chat">
          <div className="wct-date"><span>hoy · 11:42</span></div>
          {msgs.slice(0, visible).map((m, i) => (
            <WCTBubble key={`${scriptKey || 'd'}-${i}`} msg={m} />
          ))}
          {typing && visible < msgs.length && msgs[visible]?.from === 'bot' && msgs[visible]?.t && (
            <div className="wct-bot wct-typing">
              <span></span><span></span><span></span>
            </div>
          )}
        </div>
        <div className="wct-input">
          <div className="wct-input-field">Pedime lo que quieras</div>
        </div>
        <div className="wct-home"><span></span></div>
      </div>
    </div>
  );
}

function WCTBubble({ msg }) {
  if (msg.voice) {
    const heights = [38, 60, 82, 95, 70, 55, 40, 60, 88, 75, 50];
    return (
      <div className="wct-user wct-voice">
        <span className="wct-voice-play">▶</span>
        <span className="wct-voice-wave">
          {heights.map((h, i) => <span key={i} style={{ height: `${h}%` }}></span>)}
        </span>
        <span className="wct-voice-dur">{msg.voice.dur || '0:08'}</span>
      </div>
    );
  }
  if (msg.from === 'user') {
    if (!msg.t) return null;
    return <div className="wct-user">{msg.t}</div>;
  }
  if (msg.card?.type === 'progress') {
    return (
      <div className="wct-card">
        <div className="wct-card-t">Tarjeta Visa ···4127</div>
        <div className="wct-card-row"><span>Vencimiento</span><b>26 Sep</b></div>
        <div className="wct-card-row"><span>Días de atraso</span><b className="bad">12 días</b></div>
        <div className="wct-card-row"><span>Saldo vencido</span><b>$42.300</b></div>
        <div className="wct-card-row"><span>Total a regularizar</span><b>$45.180</b></div>
      </div>
    );
  }
  if (msg.card?.type === 'preapproved') {
    return (
      <div className="wct-card">
        <div className="wct-card-tag">PRE-APROBADA</div>
        <div className="wct-card-name">Turing Signature</div>
        <div className="wct-card-row"><span>Límite recomendado</span><b>$150.000</b></div>
        <div className="wct-card-row"><span>Costo anual</span><b>$0 el primer año</b></div>
        <div className="wct-card-row"><span>Cashback</span><b>2%</b></div>
      </div>
    );
  }
  if (msg.card?.type === 'actions') {
    return (
      <div className="wct-card">
        <div className="wct-card-t">Acciones disponibles</div>
        <div className="wct-card-row"><span>🔒 Bloquear tarjeta</span><b className="hi">Recomendado</b></div>
        <div className="wct-card-row"><span>🏠 Reimpresión a domicilio</span><b>$0</b></div>
        <div className="wct-card-row"><span>💳 Tarjeta virtual inmediata</span><b>Incluida</b></div>
      </div>
    );
  }
  if (msg.card?.type === 'bill') {
    return (
      <div className="wct-card">
        <div className="wct-card-t">Factura UTE (Luz)</div>
        <div className="wct-card-row"><span>N° de cuenta</span><b>···4321</b></div>
        <div className="wct-card-row"><span>Vencimiento</span><b>25 Oct</b></div>
        <div className="wct-card-row"><span>Monto a pagar</span><b>$2.180</b></div>
      </div>
    );
  }
  if (msg.card?.type === 'corp') {
    return (
      <div className="wct-card-dark">
        <div className="wct-corp-t">Tarjeta Corporativa Visa</div>
        <div className="wct-corp-num">···· ···· ···· 4015</div>
        <div className="wct-corp-lbl">Disponible hoy</div>
        <div className="wct-corp-amt">$985.300</div>
        <div className="wct-corp-of">de $1.500.000</div>
      </div>
    );
  }
  if (!msg.t) return null;
  return <div className="wct-bot">{msg.t}</div>;
}

/* ─────────── VoiceCall (call-screen UI with transcript) ─────────── */
function VoiceCall({ lang, script, header, scriptKey }) {
  const baseMsgs = script || DEFAULT_WA_SCRIPTS[lang] || DEFAULT_WA_SCRIPTS.es;
  // Voice doesn't render cards; cards collapse into a short status line.
  const voiceMsgs = useMemo(() => baseMsgs.map(m => {
    if (m.voice) return { from: m.from, t: '🎙 (mensaje de voz)' };
    if (m.card)  return { from: m.from, t: '🔄 envío de información' };
    return m;
  }), [baseMsgs]);
  const head = header || { brand: 'Banco Andes', initial: 'BA' };

  const [visible, setVisible] = useState(0);
  const [duration, setDuration] = useState(0);

  useEffect(() => {
    let cancelled = false;
    let i = 0;
    setVisible(0);
    setDuration(0);

    async function run() {
      await new Promise(r => setTimeout(r, 600));
      while (!cancelled) {
        if (i >= voiceMsgs.length) {
          await new Promise(r => setTimeout(r, 3200));
          if (cancelled) return;
          i = 0; setVisible(0); setDuration(0);
          continue;
        }
        const m = voiceMsgs[i];
        const wait = Math.max(1400, (m.t?.length || 20) * 50);
        await new Promise(r => setTimeout(r, wait));
        if (cancelled) return;
        setVisible(v => v + 1);
        i++;
      }
    }
    const dur = setInterval(() => { if (!cancelled) setDuration(d => d + 1); }, 1000);
    run();
    return () => { cancelled = true; clearInterval(dur); };
  }, [lang, scriptKey, voiceMsgs]);

  const fmt = (s) => `${String(Math.floor(s/60)).padStart(2,'0')}:${String(s%60).padStart(2,'0')}`;
  const lastTwo = voiceMsgs.slice(Math.max(0, visible - 2), visible);
  const speaking = visible > 0 && voiceMsgs[visible - 1]?.from === 'bot';

  return (
    <div className="vc-phone">
      <div className="vc-screen">
        <div className="vc-notch"></div>
        <div className="vc-status">
          <span>9:41</span>
          <span className="vc-status-r">📶 5G</span>
        </div>
        <div className="vc-meta">
          <span className="vc-live">
            <span className="vc-live-dot"></span>
            EN LLAMADA
          </span>
          <span className="vc-dur">{fmt(duration)}</span>
        </div>
        <div className="vc-avatar-wrap">
          <span className="vc-ring r1"></span>
          <span className="vc-ring r2"></span>
          <span className="vc-ring r3"></span>
          <div className="vc-avatar">{head.initial || 'BA'}</div>
        </div>
        <div className="vc-brand">{head.brand}</div>
        <div className="vc-substate">
          <span className="vc-substate-dot"></span>
          {speaking ? 'Asistente IA · hablando' : 'Asistente IA · escuchando'}
        </div>
        <div className={`vc-wave ${speaking ? 'is-on' : ''}`}>
          {Array.from({ length: 28 }).map((_, i) => (
            <span key={i} className="vc-wave-bar" style={{ animationDelay: `${i * 60}ms` }}></span>
          ))}
        </div>
        <div className="vc-transcript">
          {lastTwo.map((m, i) => (
            <div key={`${visible}-${i}`} className={`vc-line vc-line-${m.from}`}>
              <span className="vc-line-tag">{m.from === 'bot' ? 'Asistente' : 'Tú'}</span>
              <span className="vc-line-text">{m.t}</span>
            </div>
          ))}
        </div>
        <div className="vc-controls">
          <button className="vc-ctrl" aria-label="Silenciar">🔇</button>
          <button className="vc-ctrl vc-ctrl-end" aria-label="Colgar">📞</button>
          <button className="vc-ctrl" aria-label="Altavoz">🔊</button>
        </div>
        <div className="vc-home"></div>
      </div>
    </div>
  );
}

// Web Chat style demo — bank-themed overlay
function WebChatDemo({ lang }) {
  const scripts = React.useMemo(() => ({
    es: [
      { from: 'bot', t: '¡Hola Sebastián! ¿Cómo puedo ayudarte hoy?', delay: 400 },
      { from: 'bot', suggestions: ['Pagar tarjeta', 'Enviar dinero', 'Ver gastos'], delay: 1200 },
      { from: 'user', t: 'Ver gastos del mes', delay: 2200 },
      { from: 'bot', chart: true, delay: 1000 },
    ],
    en: [
      { from: 'bot', t: 'Hi Sebastián! How can I help you today?', delay: 400 },
      { from: 'bot', suggestions: ['Pay card', 'Send money', 'See spending'], delay: 1200 },
      { from: 'user', t: 'Show my monthly spending', delay: 2200 },
      { from: 'bot', chart: true, delay: 1000 },
    ],
    pt: [
      { from: 'bot', t: 'Olá Sebastián! Como posso ajudar hoje?', delay: 400 },
      { from: 'bot', suggestions: ['Pagar cartão', 'Enviar dinheiro', 'Ver gastos'], delay: 1200 },
      { from: 'user', t: 'Ver gastos do mês', delay: 2200 },
      { from: 'bot', chart: true, delay: 1000 },
    ],
  }), []);
  const msgs = scripts[lang] || scripts.es;
  const [visible, setVisible] = useState(0);

  useEffect(() => {
    let cancelled = false;
    let i = 0;
    setVisible(0);
    async function run() {
      while (!cancelled) {
        if (i >= msgs.length) {
          await new Promise(r => setTimeout(r, 4000));
          if (cancelled) return;
          i = 0;
          setVisible(0);
          continue;
        }
        await new Promise(r => setTimeout(r, msgs[i].delay));
        if (cancelled) return;
        setVisible(v => v + 1);
        i++;
      }
    }
    run();
    return () => { cancelled = true; };
  }, [lang]);

  return (
    <div className="wc-widget">
      <div className="wc-header">
        <div className="wc-header-icon"></div>
        <div className="wc-header-title">Turing Bank · Asistente</div>
        <button className="wc-header-x">×</button>
      </div>
      <div className="wc-chat">
        <div className="wc-orb"></div>
        {msgs.slice(0, visible).map((m, i) => (
          <WCBubble key={i} msg={m} />
        ))}
      </div>
      <div className="wc-input">
        <input placeholder="Pídeme lo que quieras" disabled />
        <button>→</button>
      </div>
    </div>
  );
}

function WCBubble({ msg }) {
  if (msg.suggestions) {
    return (
      <div className="wc-suggests">
        {msg.suggestions.map((s, i) => <button key={i}>{s}</button>)}
      </div>
    );
  }
  if (msg.chart) {
    const cats = [
      { n: 'Restaurantes', v: 68, c: '#c0f43d' },
      { n: 'Transporte', v: 45, c: '#cec7ff' },
      { n: 'Servicios', v: 82, c: '#f2e0c9' },
      { n: 'Super', v: 34, c: '#5bd5d5' },
    ];
    return (
      <div className="wc-bubble wc-bot wc-card">
        <div className="wc-chart-t">Gastos de abril</div>
        <div className="wc-chart-total">$182.450</div>
        {cats.map((c, i) => (
          <div key={i} className="wc-bar-row">
            <span>{c.n}</span>
            <div className="wc-bar"><div style={{ width: `${c.v}%`, background: c.c }}></div></div>
            <b>${(c.v * 1000).toLocaleString()}</b>
          </div>
        ))}
      </div>
    );
  }
  return <div className={`wc-bubble wc-${msg.from}`}>{msg.t}</div>;
}

/* CyclingWord — rotates an array of strings inside flowing text.
   Layout: a visible-but-obscured spacer element holds the natural
   width (so the surrounding line reflows correctly) while the
   absolute-positioned siblings cross-fade with a vertical slide.
   Pauses if reduced-motion is set.                              */
function CyclingWord({ words, interval = 2400 }) {
  const [i, setI] = useState(0);
  const prev = useRef(0);

  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) return;
    const id = setInterval(() => {
      setI(v => {
        prev.current = v;
        return (v + 1) % words.length;
      });
    }, interval);
    return () => clearInterval(id);
  }, [words, interval]);

  const prevIdx = (i - 1 + words.length) % words.length;

  return (
    <span className="cycle">
      <span className="cycle-flow" aria-hidden>{words[i]}</span>
      {words.map((wd, idx) => {
        const cls =
          idx === i        ? 'is-in'  :
          idx === prevIdx  ? 'is-out' :
          '';
        return (
          <span key={idx} className={`cycle-w ${cls}`} aria-hidden={idx !== i}>
            {wd}
          </span>
        );
      })}
    </span>
  );
}

/* HeroLive — small "live ops" chip showing a fluctuating counter.
   Communicates "the platform is on right now". Numbers are
   plausible mock values that drift around a base.              */
function HeroLive({ label }) {
  const [n, setN] = useState(187);
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) return;
    const id = setInterval(() => {
      setN(v => Math.max(140, Math.min(240, v + Math.floor(Math.random() * 7) - 3)));
    }, 1800);
    return () => clearInterval(id);
  }, []);
  return (
    <div className="hero-live">
      <span className="hero-live-dot"><span></span></span>
      <span className="hero-live-n">{n}</span>
      <span className="hero-live-l">{label}</span>
    </div>
  );
}

/* HeroTicker — three drifting stat chips next to the device.
   Reads as "live ops" without distracting from the headline.   */
function HeroTicker({ items }) {
  const [vals, setVals] = useState(() => items.map(i => i.start));
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) return;
    const id = setInterval(() => {
      setVals(prev => prev.map((v, i) => {
        const it = items[i];
        const delta = (Math.random() - 0.5) * it.drift;
        return Math.max(it.min, Math.min(it.max, v + delta));
      }));
    }, 1400);
    return () => clearInterval(id);
  }, [items]);
  return (
    <div className="hero-ticker">
      {items.map((it, i) => (
        <div key={i} className="hero-ticker-chip">
          <div className="hero-ticker-v">
            {it.format ? it.format(vals[i]) : Math.round(vals[i]).toLocaleString()}
            {it.suffix && <span>{it.suffix}</span>}
          </div>
          <div className="hero-ticker-l">{it.label}</div>
        </div>
      ))}
    </div>
  );
}

/* FloatingSkills — chips that orbit slowly around the device. Provides
   a sense of "here's what the agents do" without explicit copy.   */
function FloatingSkills({ chips }) {
  if (!chips || chips.length === 0) return null;
  // Fixed positions (percent of container) for a balanced cluster.
  const slots = [
    { top: '4%',  left: '-6%',   delay: 0 },
    { top: '14%', right: '-10%', delay: -2 },
    { top: '38%', left: '-14%',  delay: -4 },
    { top: '52%', right: '-12%', delay: -1 },
    { top: '74%', left: '-8%',   delay: -3 },
    { top: '86%', right: '-4%',  delay: -5 },
    { top: '24%', left: '-2%',   delay: -6 },
    { top: '64%', right: '-2%',  delay: -7 },
  ];
  return (
    <div className="hero-skills" aria-hidden>
      {chips.slice(0, slots.length).map((c, i) => (
        <span
          key={i}
          className="hero-skill"
          style={{ ...slots[i], animationDelay: `${slots[i].delay}s` }}
        >
          <span className="hero-skill-dot"></span>
          {c}
        </span>
      ))}
    </div>
  );
}

/* Agent definitions — sourced from the commercial deck (slide 5).
   Each agent has: name, headline, description, KPIs (3), capabilities,
   and a sample WhatsApp conversation. The bank in the example is
   "Turing Bank" across the board, matching the deck.              */
const AGENT_DEFS = [
  {
    key: 'collections',
    tag: 'Collections Agent',
    name: 'Collections',
    short: 'Cobranzas 24/7 con negociación de plan de pago',
    headline: 'Automatizá la <em>cobranza 24/7</em>.',
    long: 'El agente negocia, acuerda plan de pago, hace follow-up dentro de 24 hs y reporta al CRM — todo dentro del chat del cliente, con compliance aprobado.',
    metrics: [
      { v: '−70', u: '%', l: 'reducción de costo', neg: true },
      { v: '+100', u: '%', l: 'conversión vs. humano' },
      { v: '+50', u: '%', l: 'cumplimiento de acuerdos' },
    ],
    bullets: [
      'Parámetros de negociación',
      'Follow-up < 24 hs',
      'RAG sobre políticas',
      'Seguimiento mes a mes',
    ],
    header: { brand: 'Turing Bank', initial: 'TB', status: 'en línea' },
    script: [
      { from: 'bot', t: 'Hola Sebastián 👋 Te escribe Turing Bank.', delay: 1100 },
      { from: 'bot', t: 'Detectamos un atraso en tu Visa ···4127. ¿Te ayudamos a regularizarlo?', delay: 1200 },
      { from: 'bot', card: { type: 'progress' }, delay: 900 },
      { from: 'bot', t: 'Plan en 3 o 6 cuotas, sin intereses. ¿Cuál preferís?', delay: 1100 },
      { from: 'user', t: 'Plan en 3 cuotas', delay: 1700 },
      { from: 'bot', t: '✓ Listo. Pago 1: $15.060 hoy. Te paso el comprobante por mail.', delay: 1100 },
    ],
    voiceScript: [
      { from: 'bot', t: 'Hola Sebastián, te llamo desde Turing Bank.', delay: 1100 },
      { from: 'bot', t: 'Detectamos un atraso en tu Visa terminada en 4127. ¿Te ayudamos a regularizarlo?', delay: 1200 },
      { from: 'bot', card: { type: 'progress' }, delay: 900 },
      { from: 'bot', t: 'Te puedo armar un plan en 3 o 6 cuotas, sin intereses. ¿Cuál preferís?', delay: 1100 },
      { from: 'user', t: 'Plan en 3 cuotas', delay: 1700 },
      { from: 'bot', t: 'Listo. Pago 1: $15.060 hoy. Te enviamos el comprobante por mail.', delay: 1100 },
    ],
  },
  {
    key: 'advisor',
    tag: 'Advisor Agent',
    name: 'Advisor',
    short: 'Ventas 24/7 con personalización inteligente',
    headline: 'Duplicá la <em>conversión</em> con IA comercial.',
    long: 'Personalización inteligente de productos, follow-up de abandono en 24 hs y seguimiento post-conversión para asegurar utilización.',
    metrics: [
      { v: '−65', u: '%', l: 'reducción de costo', neg: true },
      { v: '−80', u: '%', l: 'tiempo vs. humano', neg: true },
      { v: '+200', u: '%', l: 'en ventas asistidas' },
    ],
    bullets: [
      'Personalización inteligente',
      'Follow-up abandono < 24 h',
      'Seguimiento post-conversión',
      'RAG sobre catálogo',
    ],
    header: { brand: 'Turing Bank', initial: 'TB', status: 'en línea' },
    script: [
      { from: 'user', t: 'Me podés decir si califico para alguna tarjeta?', delay: 1500 },
      { from: 'bot', t: '¡Identidad validada! ✅ Tengo excelentes noticias, Sebastián.', delay: 1100 },
      { from: 'bot', card: { type: 'preapproved' }, delay: 900 },
      { from: 'bot', t: '¿Querés aceptarla y emitirla ahora mismo? 🚀', delay: 900 },
      { from: 'user', voice: { dur: '0:06' }, delay: 2000 },
      { from: 'bot', t: '✓ Tarjeta emitida. Llega a tu domicilio en 3 días hábiles.', delay: 1100 },
    ],
  },
  {
    key: 'support',
    tag: 'Customer Support Agent',
    name: 'Customer Support',
    short: 'Atención IA con +300 razones de contacto',
    headline: 'Reducí un <em>90%</em> la carga de atención.',
    long: 'Más de 300 razones de contacto pre-resueltas, integración nativa con Salesforce, Zendesk y Genesys, y aviso proactivo en cambios de tickets.',
    metrics: [
      { v: '−80', u: '%', l: 'reducción de costo', neg: true },
      { v: '−90', u: '%', l: 'tiempo vs. humano', neg: true },
      { v: '100', u: '%', l: 'tasa de respuesta' },
    ],
    bullets: [
      '+300 razones de contacto',
      'Integración Salesforce / Zendesk / Genesys',
      'Aviso proactivo de tickets',
      'RAG sobre KB',
    ],
    header: { brand: 'Turing Bank', initial: 'TB', status: 'en línea' },
    script: [
      { from: 'user', t: 'Hola, perdí mi tarjeta de débito', delay: 1500 },
      { from: 'bot', t: '¡Hola, Seba! 👋 Gracias por avisarnos tan rápido. Esto tiene solución fácil.', delay: 1100 },
      { from: 'bot', t: 'Por ahora no veo movimientos sospechosos ✅', delay: 1000 },
      { from: 'bot', card: { type: 'actions' }, delay: 900 },
      { from: 'user', t: 'Bloqueala y mandame la virtual', delay: 1900 },
      { from: 'bot', t: '✓ Bloqueada. Tu tarjeta virtual ya está activa en la app.', delay: 1100 },
    ],
  },
  {
    key: 'retail',
    tag: 'Retail Banking Agent',
    name: 'Retail Banking',
    short: 'Capacidad transaccional total en chat',
    headline: 'Un canal sin <em>fricciones</em> para la banca retail.',
    long: 'Transaccionalidad total sobre canales conversacionales, integración con tarjetas, cuentas y más, avisos de pagos y vencimientos sin intervención humana.',
    metrics: [
      { v: '+50', u: '%', l: 'conversión de clientes' },
      { v: '−70', u: '%', l: 'costos vs. apps', neg: true },
      { v: '+80', u: '%', l: 'velocidad de evolución' },
    ],
    bullets: [
      'Transacciones en chat',
      'Integración tarjetas + cuentas',
      'Avisos de pago automáticos',
      'RAG sobre productos',
    ],
    header: { brand: 'Turing Bank', initial: 'TB', status: 'en línea' },
    script: [
      { from: 'user', voice: { dur: '0:04' }, delay: 1500 },
      { from: 'bot', t: '¡Hola, Sebastián! 👋 Encontré tu factura de UTE.', delay: 1100 },
      { from: 'bot', card: { type: 'bill' }, delay: 900 },
      { from: 'bot', t: '¿La pago ahora o la programamos para el día del vencimiento?', delay: 900 },
      { from: 'user', t: 'Pagala ahora', delay: 1700 },
      { from: 'bot', t: '✓ Pagado. Comprobante #284912 enviado a tu mail.', delay: 1100 },
    ],
  },
  {
    key: 'corporate',
    tag: 'Corporate Banking Agent',
    name: 'Corporate Banking',
    short: '+40 skills corporativas con permisos por rol',
    headline: 'La solución más completa para <em>banca corporativa</em>.',
    long: '+40 skills específicas, sistema inteligente de permisos basado en roles, integración nativa con los sistemas core del banco.',
    metrics: [
      { v: '+50', u: '%', l: 'conversión' },
      { v: '−70', u: '%', l: 'costos vs. apps', neg: true },
      { v: '+80', u: '%', l: 'velocidad evolución' },
    ],
    bullets: [
      '+40 skills corporativas',
      'Permisos basados en rol',
      'Integración core bancario',
      'RAG sobre normativa',
    ],
    header: { brand: 'Turing Bank · Empresas', initial: 'TB', status: 'en línea' },
    script: [
      { from: 'user', t: 'Mañana viajo, necesito saber el disponible de la corporativa', delay: 1500 },
      { from: 'bot', t: '¡Hola, Sebastián! 👋 Bienvenido a Banca Empresas.', delay: 1100 },
      { from: 'bot', card: { type: 'corp' }, delay: 900 },
      { from: 'bot', t: 'Te dejo activado el Aviso por Viaje para que no se bloqueen las tarjetas en el exterior.', delay: 1000 },
      { from: 'user', t: 'Activalo para Brasil, 5 días', delay: 1800 },
      { from: 'bot', t: '✓ Aviso de viaje activado para Brasil hasta el 03/05.', delay: 1100 },
    ],
  },
];

/* HeroAgents — combines the hero pitch and the agent navigator
   in a single section. The WhatsApp phone is rendered once and
   stays sticky as the user scrolls from the hero into the agent
   showcase, where it becomes the live example for the active
   agent. Background is a dot pattern; nearby dots glow when the
   cursor moves over them.                                       */
function HeroAgents({ lang, t }) {
  const sectRef = useRef(null);
  const phoneRef = useRef(null);
  const dotsGlowRef = useRef(null);
  const [active, setActive] = useState(0);
  const [channel, setChannel] = useState('whatsapp');   // 'whatsapp' | 'webchat' | 'voice'
  const [userPickedChannel, setUserPickedChannel] = useState(false);
  useScrollProgress(sectRef);

  // Auto-rotate channels (pauses once the user picks one manually).
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION || userPickedChannel) return;
    const order = ['whatsapp', 'webchat', 'voice'];
    const id = setInterval(() => {
      setChannel(c => order[(order.indexOf(c) + 1) % order.length]);
    }, 7000);
    return () => clearInterval(id);
  }, [userPickedChannel]);

  const pickChannel = (c) => {
    setUserPickedChannel(true);
    setChannel(c);
  };

  // Dot-glow follow: a brighter dot layer is masked by a circular
  // gradient centered on the cursor. We lerp the position so the
  // glow eases instead of snapping.
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) return;
    const sect = sectRef.current;
    const glow = dotsGlowRef.current;
    if (!sect || !glow) return;

    let tx = 50, ty = 30;
    let x = 50, y = 30;
    let raf = 0;
    let on = false;

    const tick = () => {
      x += (tx - x) * 0.10;
      y += (ty - y) * 0.10;
      glow.style.setProperty('--mx', x.toFixed(2) + '%');
      glow.style.setProperty('--my', y.toFixed(2) + '%');
      raf = requestAnimationFrame(tick);
    };

    const onMove = (e) => {
      const r = sect.getBoundingClientRect();
      tx = ((e.clientX - r.left) / r.width)  * 100;
      ty = ((e.clientY - r.top)  / r.height) * 100;
      if (!on) { on = true; glow.classList.add('is-on'); }
    };
    const onLeave = () => { on = false; glow.classList.remove('is-on'); };

    sect.addEventListener('mousemove', onMove);
    sect.addEventListener('mouseleave', onLeave);
    raf = requestAnimationFrame(tick);
    return () => {
      sect.removeEventListener('mousemove', onMove);
      sect.removeEventListener('mouseleave', onLeave);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  // Subtle phone scale/translate driven by scroll progress, so the
  // phone visibly "settles" into the agents area instead of just
  // freezing in place.
  useEffect(() => {
    if (PREFERS_REDUCED_MOTION) return;
    const sect = sectRef.current;
    const phone = phoneRef.current;
    if (!sect || !phone) return;
    let raf = 0;
    const update = () => {
      const r = sect.getBoundingClientRect();
      const vh = window.innerHeight || 1;
      // Progress 0 at top, 1 once scrolled one viewport into the section.
      const traveled = Math.max(0, -r.top);
      const p = Math.max(0, Math.min(1, traveled / (vh * 0.9)));
      phone.style.setProperty('--phone-p', p.toFixed(3));
      raf = 0;
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  const agent = AGENT_DEFS[active];

  return (
    <section className="hero ha-section" id="top" ref={sectRef}>
      <div className="hero-bg" aria-hidden>
        <div className="hero-dots"></div>
        <div className="hero-dots-glow" ref={dotsGlowRef}></div>
      </div>

      <div className="ha-wrap">
          {/* Cream background band that covers the agents row, full
              viewport width. Sits behind agents + lower phone column.
              Placed first in DOM so subsequent grid items paint over it. */}
          <div className="ha-cream-bg" aria-hidden></div>

          {/* HERO COPY */}
          <div className="ha-hero">
            <div className="hero-eyebrow reveal r-up-sm">
              <span className="pulse"></span>
              {t.hero.eyebrow}
            </div>
            <h1
              className="reveal r-up"
              dangerouslySetInnerHTML={{ __html: t.hero.title_html }}
            />
            <p className="hero-sub reveal r-up-sm">{t.hero.sub}</p>
            <div className="hero-ctas reveal r-up-sm">
              <a href="#demo" className="btn btn-primary">
                {t.hero.cta_primary} <IconArrowRight size={16} stroke={2.5} />
              </a>
              <a href="#agents" className="btn btn-ghost">
                <IconPlay size={12} /> {t.hero.cta_secondary}
              </a>
            </div>
            <div className="hero-badges reveal r-up-sm">
              <div className="hero-badges-row">
                <img className="hero-badge-logo" src="/img/69bb038edff91be56b3b560d_microsoft logo.svg" alt="Microsoft Partner" />
                <img className="hero-badge-logo" src="/img/69bb038e8a0406623c8a4fb5_meta logo.svg" alt="Meta Business Partner" />
                <img className="hero-badge-logo hero-badge-medal" src="/img/69c1577b05ed32e8991f15ce_SELLO_DORADO_150DPI 2.svg" alt="Fintech Americas Winner 2026" />
              </div>
            </div>
            <div className="ha-scrollhint" aria-hidden>
              <span>scroll</span>
              <span className="ha-scrollhint-line"></span>
            </div>
          </div>

          {/* AGENTS NAVIGATOR */}
          <div className="ha-agents reveal" id="agents">
            <div className="ha-agents-head">
              <div className="eyebrow">{t.agents.eyebrow}</div>
              <h2>
                {t.agents.title_a}{' '}
                <span className="hl">{t.agents.title_b}</span>{' '}
                <em>{t.agents.title_c}</em>
              </h2>
              <p className="ha-agents-sub">{t.agents.sub}</p>
            </div>

            <div className="ha-agents-list">
              {AGENT_DEFS.map((a, i) => (
                <div key={a.key} className={`ha-agent-row ${active === i ? 'active' : ''}`}>
                  <button
                    className="ha-agent"
                    onClick={() => setActive(i)}
                    aria-expanded={active === i}
                  >
                    <div className="ha-agent-num">{String(i + 1).padStart(2, '0')}</div>
                    <div className="ha-agent-body">
                      <div className="ha-agent-n">{a.name}</div>
                      <div className="ha-agent-d">{a.short}</div>
                    </div>
                    <IconArrowRight className="ha-agent-arrow" size={14} stroke={2.5} />
                  </button>
                  {active === i && (
                    <div className="ha-agent-expand">
                      {a.headline && (
                        <h3 className="ha-agent-expand-h"
                            dangerouslySetInnerHTML={{ __html: a.headline }} />
                      )}
                      <p className="ha-agent-expand-p">{a.long}</p>
                      <div className="ha-agent-metrics">
                        {a.metrics.map((m, k) => (
                          <div key={k} className={`ha-metric ${m.neg ? 'neg' : 'pos'}`}>
                            <div className="ha-metric-v">
                              {m.v}<span className="ha-metric-u">{m.u}</span>
                            </div>
                            <div className="ha-metric-l">{m.l}</div>
                          </div>
                        ))}
                      </div>
                      <ul className="ha-agent-expand-bullets">
                        {a.bullets.map((b, j) => (
                          <li key={j}>
                            <span className="ha-bullet-ic"><IconCheck size={11} stroke={3} /></span>
                            {b}
                          </li>
                        ))}
                      </ul>
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>

        {/* PHONE — sticky, spans hero + agents */}
        <aside className="ha-phone-col">
          <div className="ha-phone-sticky" ref={phoneRef}>
            <div className="ha-channel-toggle" role="tablist" aria-label="Canal del ejemplo">
              <button
                role="tab"
                aria-selected={channel === 'whatsapp'}
                className={`ha-channel-btn ${channel === 'whatsapp' ? 'active' : ''}`}
                onClick={() => pickChannel('whatsapp')}
              >
                <IconWhatsapp size={14} stroke={2} /> WhatsApp
              </button>
              <button
                role="tab"
                aria-selected={channel === 'webchat'}
                className={`ha-channel-btn ${channel === 'webchat' ? 'active' : ''}`}
                onClick={() => pickChannel('webchat')}
              >
                <span className="ha-channel-ic">💬</span> Web Chat
              </button>
              <button
                role="tab"
                aria-selected={channel === 'voice'}
                className={`ha-channel-btn ${channel === 'voice' ? 'active' : ''}`}
                onClick={() => pickChannel('voice')}
              >
                <span className="ha-channel-ic">🎙</span> Voz
              </button>
            </div>
            <div className="ha-phone-stage">
              {channel === 'whatsapp' && (
                <WhatsAppDemo
                  lang={lang}
                  script={agent.script}
                  header={agent.header}
                  scriptKey={agent.key + '-wa'}
                />
              )}
              {channel === 'webchat' && (
                <WebChatTuring
                  lang={lang}
                  script={agent.script}
                  header={agent.header}
                  scriptKey={agent.key + '-wc'}
                />
              )}
              {channel === 'voice' && (
                <VoiceCall
                  lang={lang}
                  script={agent.voiceScript || agent.script}
                  header={agent.header}
                  scriptKey={agent.key + '-vc'}
                />
              )}
            </div>
          </div>
        </aside>
      </div>
    </section>
  );
}

/* ================================================
   LOGO BAR — Casos de éxito · client marquee
   Sits between the dark agents section and the light
   Suite section.  Names render as a slow right→left
   scroll across the full screen width.
   ================================================ */
function LogoBar() {
  const clients = [
    'Banreservas',
    'Ficohsa',
    'Sancor',
    'Cobre',
    'Banco de Bogotá',
    'Fedecrédito',
    'Banco Bisa',
    'Banco Patagonia',
  ];
  // Duplicate the list so the CSS translateX(-50%) loops seamlessly.
  const loop = [...clients, ...clients];
  return (
    <section className="logobar" aria-label="Casos de éxito">
      <div className="logobar-head">
        <span className="eyebrow">Casos de éxito</span>
      </div>
      <div className="logobar-marquee">
        <div className="logobar-track">
          {loop.map((b, i) => (
            <span key={i} className="logobar-logo">{b}</span>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ================================================
   ORB CHAT — sticky glass orb (bottom-left) that
   opens a Delto AI chat panel.
   ================================================ */
function OrbChat() {
  const [open, setOpen] = useState(false);
  const inputRef = useRef(null);

  const suggestions = [
    { t: '¿Qué hace Delto?',          goto: '#platform' },
    { t: '¿Cómo es el time-to-value?', goto: '#customers' },
    { t: 'Ver casos de uso',           goto: '#agents' },
    { t: 'Quiero una demo',            goto: '#demo' },
  ];

  const goTo = (selector) => {
    setOpen(false);
    setTimeout(() => {
      const el = document.querySelector(selector);
      if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }, 220);
  };

  // ESC closes
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    setTimeout(() => inputRef.current?.focus(), 350);
    return () => window.removeEventListener('keydown', onKey);
  }, [open]);

  return (
    <>
      <button
        className={`delto-orb ${open ? 'is-open' : ''}`}
        onClick={() => setOpen(o => !o)}
        aria-label={open ? 'Cerrar chat con Delto AI' : 'Abrir chat con Delto AI'}
        aria-expanded={open}
      >
        <span className="delto-orb-inner">
          <span className="delto-orb-blob delto-orb-blob-1"></span>
          <span className="delto-orb-blob delto-orb-blob-2"></span>
          <span className="delto-orb-blob delto-orb-blob-3"></span>
          <span className="delto-orb-blob delto-orb-blob-4"></span>
        </span>
        <span className="delto-orb-shine" aria-hidden></span>
      </button>

      {open && (
        <div className="delto-chat" role="dialog" aria-label="Delto AI">
          <div className="delto-chat-head">
            <div className="delto-chat-ava">
              <span className="delto-chat-ava-orb"></span>
            </div>
            <div className="delto-chat-meta">
              <div className="delto-chat-t">Delto AI</div>
              <div className="delto-chat-s">
                <span className="dot"></span>
                respondemos al instante
              </div>
            </div>
            <button
              className="delto-chat-close"
              onClick={() => setOpen(false)}
              aria-label="Cerrar"
            >×</button>
          </div>

          <div className="delto-chat-body">
            <div className="delto-chat-bot">
              ¡Hola! 👋 Soy el asistente de Delto. Preguntá lo que quieras sobre la plataforma, los agentes o el deployment.
            </div>
            <div className="delto-chat-suggests">
              {suggestions.map((s, i) => (
                <button key={i} onClick={() => goTo(s.goto)}>
                  <span>{s.t}</span>
                  <span className="delto-chat-suggest-arr">→</span>
                </button>
              ))}
            </div>
          </div>

          <form
            className="delto-chat-input"
            onSubmit={(e) => {
              e.preventDefault();
              const v = inputRef.current?.value.trim();
              if (v) {
                inputRef.current.value = '';
                goTo('#demo');
              }
            }}
          >
            <input
              ref={inputRef}
              type="text"
              placeholder="Preguntá lo que quieras sobre Delto…"
            />
            <button type="submit" aria-label="Enviar">↑</button>
          </form>
        </div>
      )}
    </>
  );
}

Object.assign(window, {
  Nav, HeroAgents, LogoBar, Section, OrbChat,
  useLang, useReveal, useScrollProgress,
  WhatsAppDemo, WebChatTuring, VoiceCall,
  AGENT_DEFS,
});
})();
