/* All landing sections + small hook utilities.
   Exports components to window so app.jsx can compose them.

   Reconstruido 2026-05-17 tras corrupción NTFS del 2026-05-16 22:07 que dejó
   este archivo en 100% bytes NULL. Reconstruction combina:
   · Base sections.jsx working/newgalaxia-live-v7-hero-option-b-2026-05-15.
   · Deltas documentados en
     claude-newgalaxia-post-demo-operational-intelligence-report-2026-05-16.md
     (AgentResolvedSummarySection refinada + OperationalIntelligenceBridge nuevo).
   · Deltas documentados en
     claude-newgalaxia-hero-empleados-dashboard-ux-ui-pro-max-implementation-report-2026-05-16.md
     (EmpleadosCentro reemplaza a Capacidades · Hero sin typewriter).
   · Deltas del polish documentados en
     claude-newgalaxia-commercial-polish-about-maintenance-dashboard-report-2026-05-16.md
     (Nav con Quiénes somos · CasoReal directo · DashboardMockup vivo
     con KpiCard + updates automáticos + tooltips · Instagram fix · copy panel).
   · Hero nuevo (orbital · Operational Core) según
     claude-newgalaxia-hero-template-integration-brief-2026-05-16.md.
   Funciones removidas vs base 2026-05-15: HeroTypewriter, HeroSpinner,
   Capacidades, CapIcon, CapCard (no se usan más). */
const { useEffect, useRef, useState, useMemo, useCallback } = React;

/* ───────── Hooks ───────── */
function useReveal(opts = { threshold: 0.18, once: true }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setSeen(true);
          if (opts.once) io.disconnect();
        } else if (!opts.once) {
          setSeen(false);
        }
      });
    }, { threshold: opts.threshold, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, seen];
}

function useTilt(maxDeg = 5) {
  const ref = useRef(null);
  useEffect(() => {
    if (window.matchMedia('(pointer: coarse)').matches) return;
    const el = ref.current;if (!el) return;
    let raf = 0,tx = 0,ty = 0,ttx = 0,tty = 0;
    function onMove(e) {
      const r = el.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width - 0.5;
      const py = (e.clientY - r.top) / r.height - 0.5;
      ttx = -py * maxDeg * 2;
      tty = px * maxDeg * 2;
    }
    function onLeave() {ttx = 0;tty = 0;}
    function tick() {
      tx += (ttx - tx) * 0.12;
      ty += (tty - ty) * 0.12;
      el.style.transform = `perspective(900px) rotateX(${tx.toFixed(2)}deg) rotateY(${ty.toFixed(2)}deg)`;
      raf = requestAnimationFrame(tick);
    }
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    raf = requestAnimationFrame(tick);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
      cancelAnimationFrame(raf);
    };
  }, [maxDeg]);
  return ref;
}

function useCountUp(target, { duration = 1400, start = false, decimals = 0 } = {}) {
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!start) return;
    let raf = 0;const t0 = performance.now();
    function tick(now) {
      const k = Math.min(1, (now - t0) / duration);
      const eased = 1 - Math.pow(1 - k, 3);
      setVal(target * eased);
      if (k < 1) raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [start, target, duration]);
  return val.toFixed(decimals);
}

function Letters({ text, delay = 0, perChar = 32, className = '' }) {
  const [ref, seen] = useReveal({ threshold: 0.4, once: true });
  const words = useMemo(() => text.split(' '), [text]);
  let charIdx = 0;
  return (
    <span ref={ref} className={className} aria-label={text}>
      {words.map((word, wi) => {
        const wordChars = Array.from(word);
        const node =
        <span key={wi} style={{ display: 'inline-block', whiteSpace: 'nowrap' }}>
            {wordChars.map((c, ci) => {
            const i = charIdx++;
            return (
              <span key={ci}
              className={`letter ${seen ? 'in' : ''}`}
              style={{ transitionDelay: `${delay + i * perChar}ms` }}
              aria-hidden="true">{c}</span>);
          })}
          </span>;
        if (wi < words.length - 1) {
          charIdx++;
          return [node, <span key={`s${wi}`}> </span>];
        }
        return node;
      })}
    </span>);
}

function Reveal({ children, delay = 0, className = '', as: As = 'div' }) {
  const [ref, seen] = useReveal();
  return (
    <As ref={ref} className={`reveal-up ${seen ? 'in' : ''} ${className}`} style={{ transitionDelay: `${delay}ms` }}>
      {children}
    </As>);
}

/* V3 polish ADDENDUM 9 (2026-05-18) — SectionDivider unificado.
   Línea fina centrada con fade en extremos. Reemplaza los `border-t border-line`
   edge-to-edge que estaban inconsistentes entre secciones. Se ubica como primer
   hijo de cada `<section>` principal — la py-24 del section lo deja a ~96px
   del borde superior, creando una "marca de inicio de sección" elegante.
   NO se aplica dentro de cards, paneles, formularios ni demo V7.
   NOTA: uso `style` inline para max-width y padding porque el Tailwind CDN JIT
   no detecta confiablemente arbitrary values (`max-w-[960px]`) cuando las
   clases aparecen vía JSX/React + Babel-in-browser. */
function SectionDivider() {
  return (
    <div aria-hidden="true"
      style={{
        margin: '0 auto',
        maxWidth: 960,
        paddingLeft: 24,
        paddingRight: 24,
        width: '100%'
      }}>
      <div
        style={{
          height: 1,
          background:
            'linear-gradient(to right,' +
              ' transparent 0%,' +
              ' rgba(91,213,242,0.20) 22%,' +
              ' rgba(244,241,234,0.32) 50%,' +
              ' rgba(91,213,242,0.20) 78%,' +
              ' transparent 100%)',
          boxShadow: '0 0 12px rgba(51,194,234,0.10)'
        }} />
    </div>
  );
}

/* ───────── Empleados IA Menu — DEAD CODE STUB ─────────
   V3 polish ADDENDUM 29 (2026-05-18). Decisión Martin: los accesos públicos
   a las landings verticales externas quedan ocultos hasta mejorar esas webs.
   La función se conserva exportada en `window` con el mismo nombre para no
   romper referencias defensivas en hero-v2.jsx (que checkea typeof), pero
   retorna null. Las URLs y labels de las demos externas se eliminaron del
   código fuente para que el grep de verificación pase limpio. Para restaurar,
   consultar el historial del archivo previo a Addendum 29. */
function AIEmployeesMenu(/* { variant = 'nav' } */) {
  return null;
}

/* ───────── Nav ─────────
   V3 polish ADDENDUM 17 (2026-05-18) — Nav premium con iconos.
   Antes (Addendum 14): 5 dropdowns narrativos texto-only + drawer mobile
   con grupos colapsables texto-only. Funcionaba pero se sentía "menú
   administrativo" según el feedback de Martín.
   Ahora: cada grupo y cada sub-item lleva un icono SVG inline (no se agrega
   dependencia npm — la web es CDN-React-Babel). Visualmente:
   - Desktop dropdowns: icono badge cyan/violet a la izquierda del label,
     glow sutil cuando está active, border conic en hover. Cada subitem
     muestra icono + label + desc en 2 líneas con espaciado generoso.
   - Mobile drawer: cada grupo es un acordeón con icono badge grande +
     label + chevron. Los subitems expandidos muestran icono + label +
     desc compactos. Backdrop con shader de bg-bg/85 + blur.
   - Iconos elegidos para reforzar la narrativa: Sparkles (Inicio),
     Bot (Agente IA), Workflow (Tu negocio), Building2 (Empresa),
     Send (Contacto). Sub-items con MessageCircle, ListChecks, Layers,
     etc. Set custom inline para evitar lucide-react. */
function NavIcon({ name, size = 18, strokeWidth = 1.6 }) {
  const c = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
              stroke: 'currentColor', strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'sparkles':   return (<svg {...c}><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" /></svg>);
    case 'bot':        return (<svg {...c}><rect x="4" y="7" width="16" height="12" rx="3" /><circle cx="9" cy="13" r="1" fill="currentColor" stroke="none" /><circle cx="15" cy="13" r="1" fill="currentColor" stroke="none" /><path d="M12 3v4M8 21h8" /></svg>);
    case 'workflow':   return (<svg {...c}><rect x="3" y="3" width="6" height="6" rx="1.5" /><rect x="15" y="15" width="6" height="6" rx="1.5" /><path d="M6 9v4a3 3 0 0 0 3 3h6" /></svg>);
    case 'building':   return (<svg {...c}><path d="M6 21V5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v16" /><path d="M3 21h18M9 7h2M13 7h2M9 11h2M13 11h2M9 15h2M13 15h2" /></svg>);
    case 'send':       return (<svg {...c}><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7Z" /></svg>);
    case 'message':    return (<svg {...c}><path d="M21 11.5a8.4 8.4 0 0 1-1 4 8.5 8.5 0 0 1-7.5 4.5 8.4 8.4 0 0 1-4-1L3 21l2-5.5a8.4 8.4 0 0 1-1-4 8.5 8.5 0 0 1 4.5-7.5 8.4 8.4 0 0 1 4-1A8.5 8.5 0 0 1 21 11.5Z" /></svg>);
    case 'check':      return (<svg {...c}><path d="m3 12 3 3 5-6M11 18l3 3 7-9" /></svg>);
    case 'help':       return (<svg {...c}><circle cx="12" cy="12" r="9" /><path d="M9.5 9a2.5 2.5 0 1 1 4 2c-1 .6-1.5 1.2-1.5 2.5M12 17.5h0" /></svg>);
    case 'zap':        return (<svg {...c}><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z" /></svg>);
    case 'users':      return (<svg {...c}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" /></svg>);
    case 'grid':       return (<svg {...c}><rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" /><rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" /></svg>);
    case 'external':   return (<svg {...c}><path d="M14 3h7v7M21 3l-9 9M19 14v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h6" /></svg>);
    case 'shield':     return (<svg {...c}><path d="M12 2 4 5v7c0 5 3.5 8.5 8 10 4.5-1.5 8-5 8-10V5l-8-3Z" /><path d="m9 12 2 2 4-4" /></svg>);
    case 'phone':      return (<svg {...c}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.59 2.81.72A2 2 0 0 1 22 16.92Z" /></svg>);
    case 'instagram':  return (<svg {...c}><rect x="3" y="3" width="18" height="18" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="0.7" fill="currentColor" stroke="none" /></svg>);
    case 'mail':       return (<svg {...c}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="m3 7 9 6 9-6" /></svg>);
    case 'calendar':   return (<svg {...c}><rect x="3" y="5" width="18" height="16" rx="2" /><path d="M16 3v4M8 3v4M3 11h18" /></svg>);
    case 'home':       return (<svg {...c}><path d="m3 11 9-8 9 8M5 10v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V10" /></svg>);
    default: return null;
  }
}

function NavDropdown({ label, groupIcon, items, alignRight = false }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }
    function onKey(e) { if (e.key === 'Escape') setOpen(false); }
    if (open) {
      document.addEventListener('click', onClick);
      document.addEventListener('keydown', onKey);
      return () => { document.removeEventListener('click', onClick); document.removeEventListener('keydown', onKey); };
    }
  }, [open]);
  return (
    <div ref={ref} className="relative">
      <button type="button" onClick={() => setOpen(o => !o)} aria-haspopup="menu" aria-expanded={open}
        className={`px-2.5 lg:px-3 py-2 rounded-full inline-flex items-center gap-2 transition-all duration-300 ${open
          ? 'bg-cyan/12 text-ink shadow-[0_0_0_1px_rgba(51,194,234,0.30),0_8px_24px_-12px_rgba(51,194,234,0.45)]'
          : 'text-ink/80 hover:text-ink hover:bg-cyan/8 hover:shadow-[0_0_0_1px_rgba(51,194,234,0.18)]'}`}>
        {groupIcon && (
          <span className={`inline-flex items-center justify-center transition-colors ${open ? 'text-cyan' : 'text-ink/65 group-hover:text-cyan'}`}>
            <NavIcon name={groupIcon} size={16} />
          </span>
        )}
        <span>{label}</span>
        <svg width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden="true"
          className={`transition-transform duration-300 ${open ? 'rotate-180 text-cyan' : 'text-ink/55'}`}>
          <path d="M2 3.5 5 6.5 8 3.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </button>
      {open && (
        <div role="menu"
          className={`absolute top-full mt-3 ${alignRight ? 'right-0' : 'left-1/2 -translate-x-1/2'} rounded-2xl border border-cyan/25 z-50 overflow-hidden p-1.5`}
          style={{
            width: 'min(300px, calc(100vw - 32px))',
            background: 'linear-gradient(180deg, rgba(11,11,18,0.92) 0%, rgba(11,11,18,0.96) 100%)',
            backdropFilter: 'blur(20px) saturate(140%)',
            WebkitBackdropFilter: 'blur(20px) saturate(140%)',
            boxShadow: '0 0 0 1px rgba(51,194,234,0.10) inset, 0 18px 50px -16px rgba(0,0,0,0.65), 0 0 30px rgba(51,194,234,0.10)'
          }}>
          <div aria-hidden="true" className="absolute inset-x-3 top-0 h-px"
            style={{ background: 'linear-gradient(to right, transparent, rgba(91,213,242,0.65), transparent)' }} />
          {items.map((item, i) => (
            <a key={i} role="menuitem" href={item.href}
              {...(item.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}
              className="group flex items-start gap-3 rounded-xl px-3 py-2.5 text-ink hover:bg-cyan/10 transition-colors"
              onClick={() => setOpen(false)}>
              {item.icon && (
                <span className="mt-0.5 flex-shrink-0 flex items-center justify-center size-8 rounded-lg border border-line bg-bg/50 text-ink/75 group-hover:text-cyan group-hover:border-cyan/35 transition-colors">
                  <NavIcon name={item.icon} size={15} />
                </span>
              )}
              <span className="flex-1 min-w-0">
                <span className="flex items-center gap-1.5 text-[14px] font-medium text-ink group-hover:text-cyan transition-colors">
                  {item.label}
                  {item.external && <NavIcon name="external" size={11} />}
                </span>
                {item.desc && <span className="mt-0.5 block text-[11.5px] text-mute group-hover:text-ink/70 leading-snug transition-colors">{item.desc}</span>}
              </span>
            </a>
          ))}
        </div>
      )}
    </div>
  );
}

function MobileDrawer({ open, onClose, groups }) {
  const [expanded, setExpanded] = useState(null);
  useEffect(() => {
    if (open) {
      const original = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = original; };
    }
  }, [open]);
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-[60] md:hidden" aria-modal="true" role="dialog">
      <div className="absolute inset-0 bg-bg/85 backdrop-blur-md" onClick={onClose} aria-hidden="true" />
      <div className="absolute inset-0 flex flex-col">
        <div className="flex items-center justify-between px-5 pt-6">
          <a href="#top" onClick={onClose} className="select-none">
            <img src="./galaxia-logo-clean.png" alt="newGalaxIA" className="h-7 w-auto" />
          </a>
          <button type="button" onClick={onClose} aria-label="Cerrar menú"
            className="size-11 rounded-full border border-line bg-glass flex items-center justify-center text-ink/85 hover:text-ink hover:border-cyan/40">
            <svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
              <path d="M4 4l10 10M14 4 4 14" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
            </svg>
          </button>
        </div>
        <div className="flex-1 overflow-y-auto px-5 mt-4 pb-36">
          {groups.map((g, gi) => {
            const isOpen = expanded === gi;
            return (
              <div key={gi} className={`rounded-2xl mb-2.5 transition-colors duration-300 ${isOpen ? 'border border-cyan/25 bg-cyan/5' : 'border border-line/60 bg-glass'}`}>
                <button type="button" onClick={() => setExpanded(isOpen ? null : gi)}
                  aria-expanded={isOpen}
                  className="w-full flex items-center gap-3 px-4 py-3.5 text-left">
                  <span className={`flex-shrink-0 flex items-center justify-center size-10 rounded-xl border transition-colors duration-300 ${isOpen
                    ? 'border-cyan/45 bg-cyan/15 text-cyan'
                    : 'border-line bg-bg/50 text-ink/70'}`}>
                    <NavIcon name={g.icon} size={18} />
                  </span>
                  <span className="flex-1">
                    <span className="block text-[16px] text-ink font-medium leading-tight">{g.label}</span>
                    {g.tagline && <span className="block text-[11.5px] text-mute leading-snug mt-0.5">{g.tagline}</span>}
                  </span>
                  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true"
                    className={`flex-shrink-0 transition-all duration-300 ${isOpen ? 'rotate-180 text-cyan' : 'text-ink/45'}`}>
                    <path d="M2 4.5 6 8.5 10 4.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </button>
                {isOpen && (
                  <div className="px-2 pb-2.5 flex flex-col gap-1.5">
                    {g.items.map((item, ii) => (
                      <a key={ii} href={item.href} onClick={onClose}
                        {...(item.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}
                        className="flex items-start gap-3 rounded-xl px-3 py-2.5 text-ink/90 hover:bg-cyan/10 transition-colors">
                        {item.icon && (
                          <span className="mt-0.5 flex-shrink-0 flex items-center justify-center size-8 rounded-lg border border-line bg-bg/55 text-cyan/75">
                            <NavIcon name={item.icon} size={14} />
                          </span>
                        )}
                        <span className="flex-1 min-w-0">
                          <span className="flex items-center gap-1.5 text-[14.5px] leading-tight">
                            {item.label}
                            {item.external && <NavIcon name="external" size={11} />}
                          </span>
                          {item.desc && <span className="mt-0.5 block text-[12px] text-mute leading-snug">{item.desc}</span>}
                        </span>
                      </a>
                    ))}
                  </div>
                )}
              </div>
            );
          })}
        </div>
        <div className="absolute inset-x-0 bottom-0 px-5 pb-7 pt-4"
          style={{ background: 'linear-gradient(to top, rgba(10,10,15,0.95) 60%, rgba(10,10,15,0))' }}>
          <a href="#contacto" onClick={onClose}
            className="btn-cta w-full rounded-full bg-ink text-bg py-3.5 text-sm font-medium inline-flex items-center justify-center gap-3">
            Reservar diagnóstico <span className="btn-arrow">→</span>
          </a>
        </div>
      </div>
    </div>
  );
}

function Nav() {
  const [hidden, setHidden] = useState(false);
  const [drawerOpen, setDrawerOpen] = useState(false);
  useEffect(() => {
    let last = window.scrollY;
    function onScroll() {
      const y = window.scrollY;
      const dy = y - last;
      if (y < 80) {setHidden(false);} else
      if (dy > 6) {setHidden(true);} else
      if (dy < -6) {setHidden(false);}
      last = y;
    }
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  /* Grupos narrativos. Cada grupo y cada item tiene su icono. Items apuntan
     SOLO a anchors existentes (no se crearon IDs nuevos). */
  const groups = [
    { label: 'Inicio', icon: 'sparkles', tagline: 'Lo que prometemos', items: [
      { label: 'Promesa', desc: 'Empleados IA con tus reglas', href: '#top', icon: 'sparkles' },
      { label: 'Ver agente en vivo', desc: 'Demo WhatsApp interactiva', href: '#agente', icon: 'message' }
    ]},
    { label: 'Agente IA', icon: 'bot', tagline: 'Cómo trabaja el agente', items: [
      { label: 'Qué resuelve', desc: 'Outputs concretos del agente', href: '#lo-que-resuelve', icon: 'check' },
      { label: 'Cómo funciona', desc: 'Diagnóstico · diseño · ops', href: '#proceso', icon: 'workflow' },
      { label: 'Demo WhatsApp', desc: 'Verlo operar en vivo', href: '#agente', icon: 'message' },
      { label: 'FAQ', desc: 'Lo que siempre se pregunta', href: '#faq', icon: 'help' }
    ]},
    { label: 'Tu negocio', icon: 'workflow', tagline: 'Áreas donde puede trabajar', items: [
      { label: 'Qué podemos hacer', desc: 'Inteligencia operativa', href: '#inteligencia-operativa', icon: 'zap' },
      { label: 'Áreas y empleados IA', desc: 'Atención · ventas · docs · más', href: '#empleados-ia', icon: 'users' },
      { label: 'Casos verticales', desc: 'Inmobiliaria · clínica · más', href: '#casos', icon: 'grid' }
      /* V3 polish ADDENDUM 29 (2026-05-18) — item de demos externas oculto.
         Item removido del dropdown por decisión Martin: los accesos públicos
         a las landings verticales externas quedan ocultos hasta mejorar
         esas webs. Para restaurar, ver git history del archivo. */
    ]},
    { label: 'Empresa', icon: 'building', tagline: 'Quiénes somos', items: [
      { label: 'Quiénes somos', desc: 'Equipo · visión · misión', href: '#quienes-somos', icon: 'users' },
      { label: 'Nuestro compromiso', desc: 'QA continuo · tono propio', href: '#quienes-somos', icon: 'shield' }
    ]},
    { label: 'Contacto', icon: 'send', tagline: 'Hablemos por tu canal', items: [
      { label: 'WhatsApp', desc: '+598 92 499 463', href: 'https://wa.me/59892499463', external: true, icon: 'phone' },
      { label: 'Instagram', desc: '@new_galaxia', href: 'https://www.instagram.com/new_galaxia/', external: true, icon: 'instagram' },
      { label: 'Correo', desc: 'mmoralesoloriz@gmail.com', href: 'mailto:mmoralesoloriz@gmail.com', icon: 'mail' },
      { label: 'Reservar diagnóstico', desc: 'Bajar a la sección de contacto', href: '#contacto', icon: 'calendar' }
    ]}
  ];

  return (
    <>
      <nav className={`fixed top-0 inset-x-0 z-50 transition-transform duration-500 ${hidden ? 'nav-hide' : ''}`}
        style={{ transitionTimingFunction: 'cubic-bezier(0.65,0,0.35,1)' }}>
        <div className="mx-auto max-w-[1280px] px-4 md:px-8 pt-4 md:pt-5">
          <div className="glass rounded-full pl-3 pr-3 md:pl-4 md:pr-2 py-2 flex items-center justify-between gap-2">
            <a href="#top" className="flex items-center group select-none flex-shrink-0">
              <img src="./galaxia-logo-clean.png" alt="newGalaxIA" className="h-7 md:h-8 w-auto" />
            </a>
            <div className="hidden md:flex items-center gap-1 lg:gap-1.5 text-[14px] lg:text-[14.5px] text-ink/85">
              {groups.map((g, i) => (
                <NavDropdown key={i} label={g.label} groupIcon={g.icon} items={g.items} alignRight={i >= groups.length - 2} />
              ))}
            </div>
            <a href="#contacto" className="hidden md:inline-flex btn-cta rounded-full bg-ink text-bg text-xs md:text-sm font-medium px-3 sm:px-4 py-2 flex-shrink-0">
              Reservar diagnóstico
            </a>
            <button type="button" onClick={() => setDrawerOpen(true)} aria-label="Abrir menú"
              className="md:hidden size-10 rounded-full border border-line bg-glass flex items-center justify-center text-ink/85 hover:text-ink hover:border-cyan/40">
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
                <path d="M3 5h12M3 9h12M3 13h12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
              </svg>
            </button>
          </div>
        </div>
      </nav>
      <MobileDrawer open={drawerOpen} onClose={() => setDrawerOpen(false)} groups={groups} />
    </>);
}

/* ───────── Hero helpers (Operational Core orbital) ───────── */
const HERO_OP_STEPS = [
  { id: 'msg',      label: 'Mensaje',     icon: 'msg',      sub: 'WhatsApp' },
  { id: 'rule',     label: 'Reglas',      icon: 'rule',     sub: 'tu lógica' },
  { id: 'crm',      label: 'CRM',         icon: 'db',       sub: 'datos vivos' },
  { id: 'decision', label: 'Decisión',    icon: 'decision', sub: 'agente' },
  { id: 'followup', label: 'Seguimiento', icon: 'clock',    sub: 'agenda' },
  { id: 'team',     label: 'Equipo',      icon: 'team',     sub: 'aviso humano' }];

function HeroSysIcon({ name, size = 22 }) {
  const c = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
              stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'msg':      return (<svg {...c}><path d="M4 6.5C4 5.7 4.7 5 5.5 5h13c.8 0 1.5.7 1.5 1.5v8c0 .8-.7 1.5-1.5 1.5H10l-4 3v-3H5.5C4.7 16 4 15.3 4 14.5v-8Z" /><circle cx="9"  cy="10.5" r=".7" fill="currentColor" stroke="none" /><circle cx="12" cy="10.5" r=".7" fill="currentColor" stroke="none" /><circle cx="15" cy="10.5" r=".7" fill="currentColor" stroke="none" /></svg>);
    case 'rule':     return (<svg {...c}><path d="M12 3v18M3 8h6M3 12h6M3 16h6M15 8h6M15 12h6M15 16h6" /><circle cx="12" cy="12" r="1.3" fill="currentColor" stroke="none" /></svg>);
    case 'db':       return (<svg {...c}><ellipse cx="12" cy="5.5" rx="7" ry="2.5" /><path d="M5 5.5v6c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-6" /><path d="M5 11.5v6c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5v-6" /></svg>);
    case 'decision': return (<svg {...c}><circle cx="6"  cy="6"  r="2" /><circle cx="6"  cy="18" r="2" /><circle cx="18" cy="12" r="2" /><path d="M8 6h2a4 4 0 0 1 4 4v.5M8 18h2a4 4 0 0 0 4-4V13.5" /></svg>);
    case 'team':     return (<svg {...c}><circle cx="8"  cy="9" r="3" /><path d="M2.5 19c0-3 2.5-5 5.5-5s5.5 2 5.5 5" /><circle cx="17" cy="10" r="2.5" /><path d="M14.5 19c0-2.4 1.8-4.2 4-4.2s4 1.7 4 4.2" /></svg>);
    case 'clock':    return (<svg {...c}><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3.5 2.5" /></svg>);
    default: return null;
  }
}

function HeroPodCard({ step, idx }) {
  return (
    <div className="relative w-[118px] rounded-[20px] overflow-hidden"
      style={{
        background: 'linear-gradient(180deg, rgba(91,213,242,0.08) 0%, rgba(244,241,234,0.03) 50%, rgba(10,10,15,0.62) 100%)',
        border: '1px solid rgba(91,213,242,0.32)',
        boxShadow: '0 0 0 1px rgba(91,213,242,0.10) inset, 0 18px 30px -18px rgba(0,0,0,0.6), 0 0 24px rgba(51,194,234,0.18)',
        backdropFilter: 'blur(14px) saturate(140%)', WebkitBackdropFilter: 'blur(14px) saturate(140%)'
      }}>
      <div aria-hidden="true" className="absolute inset-x-3 top-0 h-px"
        style={{ background: 'linear-gradient(to right, transparent, rgba(91,213,242,0.85), transparent)', boxShadow: '0 0 8px rgba(91,213,242,0.7)' }} />
      <div className="absolute top-2 left-3 flex items-center gap-1.5">
        <span className="relative flex size-1.5">
          <span className="absolute inset-0 rounded-full bg-cyan opacity-75 hero-orb-ping" />
          <span className="relative rounded-full bg-cyan size-1.5" style={{ boxShadow: '0 0 8px rgba(51,194,234,0.95)' }} />
        </span>
        <span className="font-mono text-[7.5px] uppercase tracking-[0.32em] text-cyan/75">on</span>
      </div>
      <div className="absolute top-2 right-3 font-mono text-[8px] tracking-[0.18em] text-ink/40">N{(idx + 1).toString().padStart(2, '0')}</div>
      <div className="relative px-3 pt-7 pb-3 flex flex-col items-center gap-2">
        <div className="text-cyan grid place-items-center size-9 rounded-full" style={{ background: 'radial-gradient(circle, rgba(91,213,242,0.20), transparent 70%)' }}>
          <HeroSysIcon name={step.icon} size={22} />
        </div>
        <div className="text-center leading-tight">
          <div className="font-mono text-[10.5px] uppercase tracking-[0.18em] text-ink">{step.label}</div>
          <div className="font-mono text-[9px] text-ink/55 mt-0.5">{step.sub}</div>
        </div>
      </div>
    </div>);
}

function useHeroStepLoop(count, intervalMs = 1300) {
  const [active, setActive] = useState(0);
  useEffect(() => {
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const id = setInterval(() => setActive((a) => (a + 1) % count), intervalMs);
    return () => clearInterval(id);
  }, [count, intervalMs]);
  return active;
}

function HeroExecutionRail() {
  const phases = ['Entendió', 'Consultó', 'Decidió', 'Avisó'];
  const active = useHeroStepLoop(phases.length, 1300);
  return (
    <div className="inline-flex items-center gap-1.5 rounded-full border border-line bg-glass backdrop-blur-md pl-3 pr-3 py-1.5">
      <span className="font-mono text-[9.5px] uppercase tracking-[0.22em] text-ink/55 pr-1">Plan en curso</span>
      {phases.map((p, i) => {
        const isDone = i < active;
        const isLive = i === active;
        return (
          <React.Fragment key={p}>
            {i > 0 && <span aria-hidden="true" className="text-ink/30 text-[10px]">·</span>}
            <span className={`inline-flex items-center gap-1 font-mono text-[10px] uppercase tracking-[0.16em] transition-colors duration-300 ${isLive ? 'text-cyan' : isDone ? 'text-ink/75' : 'text-ink/35'}`}>
              <span className={`inline-block size-1.5 rounded-full ${isLive ? 'bg-cyan hero-orb-livedot' : isDone ? 'bg-ink/60' : 'border border-ink/30 bg-transparent'}`}
                style={isLive ? { boxShadow: '0 0 10px rgba(51,194,234,0.85)' } : {}} />
              {p}
            </span>
          </React.Fragment>);
      })}
    </div>);
}

function HeroOperationalCore() {
  const ringR = 196;
  const layout = [
    { deg: -95, r: ringR     },
    { deg: -45, r: ringR - 6 },
    { deg:   0, r: ringR     },
    { deg:  45, r: ringR - 6 },
    { deg:  95, r: ringR     },
    { deg: 180, r: ringR + 4 }];
  const pos = (deg, r) => {
    const rad = (deg - 90) * Math.PI / 180;
    return { x: Math.cos(rad) * r, y: Math.sin(rad) * r };
  };
  const exitR = (deg) => {
    if (deg === 0)            return 78;
    if (deg === 180)          return 96;
    if (Math.abs(deg) === 95) return 80;
    return 70;
  };
  const connectorPath = (s, e) => {
    const dx = e.x - s.x, dy = e.y - s.y;
    const cx1 = s.x + dx * 0.40 + (dy > 0 ? 18 : -18);
    const cy1 = s.y + dy * 0.40;
    const cx2 = s.x + dx * 0.85;
    const cy2 = s.y + dy * 0.85;
    return `M ${s.x.toFixed(1)} ${s.y.toFixed(1)} C ${cx1.toFixed(1)} ${cy1.toFixed(1)}, ${cx2.toFixed(1)} ${cy2.toFixed(1)}, ${e.x.toFixed(1)} ${e.y.toFixed(1)}`;
  };

  const VBW = 580, VBH = 520;
  const containerH = 480;
  const containerW = 620;

  return (
    <div className="relative w-full mx-auto" style={{ height: containerH, maxWidth: containerW }}>
      <svg viewBox={`-${VBW / 2} -${VBH / 2} ${VBW} ${VBH}`}
        className="absolute inset-0 w-full h-full"
        preserveAspectRatio="xMidYMid meet" aria-hidden="true">
        <defs>
          <radialGradient id="hoc-aura" cx="50%" cy="50%" r="50%">
            <stop offset="0%"  stopColor="rgba(51,194,234,0.40)" />
            <stop offset="60%" stopColor="rgba(51,194,234,0.08)" />
            <stop offset="100%" stopColor="rgba(51,194,234,0)" />
          </radialGradient>
          <radialGradient id="hoc-core-glow" cx="50%" cy="50%" r="50%">
            <stop offset="0%"   stopColor="rgba(91,213,242,0.80)" />
            <stop offset="55%"  stopColor="rgba(51,194,234,0.35)" />
            <stop offset="100%" stopColor="rgba(51,194,234,0)" />
          </radialGradient>
          <radialGradient id="hoc-core-fill" cx="50%" cy="50%" r="50%">
            <stop offset="0%"   stopColor="rgba(244,241,234,0.20)" />
            <stop offset="100%" stopColor="rgba(244,241,234,0.02)" />
          </radialGradient>
        </defs>

        <circle cx="0" cy="0" r="240" fill="url(#hoc-aura)"
          style={{ animation: 'hero-orb-breath 4.2s cubic-bezier(0.4,0,0.6,1) infinite', transformOrigin: 'center' }} />

        {[176, 206, 236].map((rr, i) => (
          <ellipse key={i} cx="0" cy="0" rx={rr} ry={rr * 0.62}
            fill="none" stroke={`rgba(244,241,234,${0.06 - i * 0.012})`}
            strokeDasharray={i === 1 ? '2 6' : '1 7'} transform="rotate(-12)" />
        ))}

        {layout.map((l, i) => {
          const s = pos(l.deg, exitR(l.deg));
          const e = pos(l.deg, l.r);
          const delay = `${(i * 0.32).toFixed(2)}s`;
          const path = connectorPath(s, e);
          return (
            <g key={i}>
              <path d={path} fill="none" stroke="#5BD5F2" strokeWidth="1.4" strokeLinecap="round"
                style={{ filter: 'drop-shadow(0 0 5px #33C2EA)' }} />
              <path d={path} fill="none" stroke="#F4F1EA" strokeWidth="1" strokeLinecap="round" strokeDasharray="2 12"
                style={{ animation: 'hero-orb-dash 1.6s linear infinite', animationDelay: delay, filter: 'drop-shadow(0 0 3px #5BD5F2)' }} />
              <circle cx={s.x} cy={s.y} r="2.5" fill="#5BD5F2" style={{ filter: 'drop-shadow(0 0 5px #33C2EA)' }} />
              <circle r="3.4" fill="#DCF5FC" style={{ filter: 'drop-shadow(0 0 9px #5BD5F2)' }}>
                <animateMotion dur="2.0s" begin={delay} repeatCount="indefinite" path={path} />
                <animate attributeName="opacity" values="0;1;1;0" keyTimes="0;0.12;0.88;1" dur="2.0s" begin={delay} repeatCount="indefinite" />
              </circle>
            </g>);
        })}

        <g style={{ animation: 'hero-orb-float 5.2s ease-in-out infinite', transformOrigin: 'center' }}>
          <circle cx="0" cy="0" r="92" fill="url(#hoc-core-glow)" opacity="0.65" />
          <circle cx="0" cy="0" r="64" fill="url(#hoc-core-fill)" stroke="rgba(91,213,242,0.55)" strokeWidth="1.4" />
          <circle cx="0" cy="0" r="46" fill="none" stroke="rgba(91,213,242,0.32)" strokeWidth="0.8" strokeDasharray="3 5" />
          {[0, 45, 90, 135, 180, 225, 270, 315].map((deg) => {
            const rad = deg * Math.PI / 180;
            return (
              <line key={deg}
                x1={20 * Math.cos(rad)} y1={20 * Math.sin(rad)}
                x2={36 * Math.cos(rad)} y2={36 * Math.sin(rad)}
                stroke="rgba(91,213,242,0.6)" strokeWidth="0.8" strokeLinecap="round" />);
          })}
          {[0, 90, 180, 270].map((deg) => {
            const rad = deg * Math.PI / 180;
            return (
              <circle key={deg}
                cx={46 * Math.cos(rad)} cy={46 * Math.sin(rad)}
                r="2.5" fill="rgba(91,213,242,0.9)"
                style={{ filter: 'drop-shadow(0 0 4px #5BD5F2)' }} />);
          })}
          <circle cx="0" cy="0" r="9" fill="rgba(91,213,242,0.6)" style={{ filter: 'drop-shadow(0 0 12px #5BD5F2)' }} />
          <circle cx="0" cy="0" r="4" fill="#DCF5FC" style={{ filter: 'drop-shadow(0 0 8px #5BD5F2)' }} />
          <text x="0" y="86" textAnchor="middle"
            fontFamily='"Geist Mono", monospace' fontSize="9.5" letterSpacing="2.6"
            fill="rgba(244,241,234,0.78)">OPERATIONAL CORE</text>
        </g>

        <style>{`
          @keyframes hero-orb-dash { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -28; } }
          @keyframes hero-orb-breath { 0%,100% { opacity:.85; transform:scale(1);} 50% { opacity:1; transform:scale(1.05);} }
          @keyframes hero-orb-float { 0%,100% { transform:translateY(0);} 50% { transform:translateY(-6px);} }
          @keyframes hero-orb-ping { 0% { transform:scale(1); opacity:.65;} 75%,100% { transform:scale(2); opacity:0;} }
          @keyframes hero-orb-livedot { 0%,100% { opacity:1;} 50% { opacity:.55;} }
          @keyframes hero-orb-scbounce { 0%,100% { transform:translateY(0); opacity:.6;} 50% { transform:translateY(4px); opacity:1;} }
          .hero-orb-ping { animation: hero-orb-ping 1.6s ease-out infinite; }
          .hero-orb-livedot { animation: hero-orb-livedot 1.2s ease-in-out infinite; }
          @media (prefers-reduced-motion: reduce) {
            [style*="hero-orb-dash"], [style*="hero-orb-breath"], [style*="hero-orb-float"],
            .hero-orb-ping, .hero-orb-livedot, [style*="hero-orb-scbounce"] { animation: none !important; }
          }
        `}</style>
      </svg>

      {layout.map((l, i) => {
        const p = pos(l.deg, l.r);
        const left = `calc(50% + ${(p.x * (containerW / VBW)).toFixed(1)}px)`;
        const top  = `calc(50% + ${(p.y * (containerH / VBH)).toFixed(1)}px)`;
        return (
          <div key={i} className="absolute" style={{ left, top, transform: 'translate(-50%, -50%)' }}>
            <HeroPodCard step={HERO_OP_STEPS[i]} idx={i} />
          </div>);
      })}
    </div>);
}

/* ───────── Hero Galaxia Composition (video + BenefitCards en streaming) ─────────
   Adaptado de C:\Descargas\Shader wallpapers\hero-v2.jsx:
     · BENEFITS         (líneas ~225-234) — 8 KPIs.
     · GalaxiaVideo     (líneas ~407-476) — video con doble feather + screen blend.
     · BenefitCard      (líneas ~944-1000) — pod cyan glass con número grande.
     · OperationalCore  (líneas ~1002-1103) — falling columns rAF.
   Diferencias vs. fuente:
     · Dimensiones compactadas (container 720×480 vs. 880×620, video 520×292 vs. 640×360)
       para que el hero entre completo en 1440×900 sin tapar la sección siguiente.
     · Iconos reducidos al set necesario (rocket/target/moon/coin/check + reuso de clock).
     · Card width 124px vs. 136px del source, número 24px vs. 28px (proporcional al video).
     · Solo se renderiza en desktop (`hidden lg:block`). En mobile no monta.
   La narrativa "video premium + benefits laterales" reemplaza al orbital
   HeroOperationalCore + HeroExecutionRail únicamente en el slot derecho del split desktop.
   El bloque mobile, el header copy y el mount HeroDemoV7Full quedan intactos. */
const HERO_BENEFITS = [
  { id: 'productivity', icon: 'rocket', value: '+200%', label: 'Productividad',     sub: 'horas liberadas' },
  { id: 'response',     icon: 'clock',  value: '−92%',  label: 'Tiempo respuesta',  sub: 'del visto al cierre' },
  { id: 'conversion',   icon: 'target', value: '+35%',  label: 'Conversión',        sub: 'leads que cierran' },
  { id: 'always',       icon: 'moon',   value: '24/7',  label: 'Sin pausa',         sub: 'también de noche' },
  { id: 'cost',         icon: 'coin',   value: '−60%',  label: 'Costo por lead',    sub: 'mismo volumen' },
  { id: 'data',         icon: 'check',  value: '100%',  label: 'CRM al día',        sub: 'cero doble carga' },
  { id: 'recovered',    icon: 'target', value: '+70%',  label: 'Leads recuperados', sub: 'que antes se perdían' },
  { id: 'capacity',     icon: 'rocket', value: '×24',   label: 'Velocidad',         sub: 'vs respuesta manual' },
];

function HeroBenefitIcon({ name, size = 18 }) {
  const c = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
              stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'clock':    return (<svg {...c}><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3.5 2.5" /></svg>);
    case 'rocket':   return (<svg {...c}><path d="M12 3c4 3 6 7 6 11l-2 2c-1-3-3-5-6-6L8 12c0-4 1-7 4-9Z" /><path d="M5 19c1-2 3-3 5-3M19 19c-2-1-4-3-5-5" /><circle cx="13" cy="9" r="1.5" /></svg>);
    case 'target':   return (<svg {...c}><circle cx="12" cy="12" r="9" /><circle cx="12" cy="12" r="5.5" /><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none" /></svg>);
    case 'moon':     return (<svg {...c}><path d="M20 14.5a8 8 0 1 1-10.5-10.5 7 7 0 0 0 10.5 10.5Z" /><circle cx="18" cy="6" r=".7" fill="currentColor" stroke="none" /><circle cx="20" cy="9.5" r=".5" fill="currentColor" stroke="none" /></svg>);
    case 'coin':     return (<svg {...c}><circle cx="12" cy="12" r="9" /><path d="M9 9.5c.5-1 2-1.5 3-1.5 1.5 0 3 1 3 2.5 0 1.5-1.5 2-3 2.5-1.5.5-3 1-3 2.5 0 1.5 1.5 2.5 3 2.5 1 0 2.5-.5 3-1.5M12 6.5v11" /></svg>);
    case 'check':    return (<svg {...c}><circle cx="12" cy="12" r="9" /><path d="M7.5 12.5l3 3 6-7" /></svg>);
    default: return null;
  }
}

function HeroBenefitCard({ b, index }) {
  return (
    <div className="relative w-[124px] rounded-[20px] overflow-hidden"
      style={{
        background: 'linear-gradient(180deg, rgba(14,18,28,0.32) 0%, rgba(10,12,18,0.22) 50%, rgba(8,9,14,0.18) 100%)',
        border: '1px solid rgba(91,213,242,0.38)',
        backdropFilter: 'blur(10px) saturate(115%)',
        WebkitBackdropFilter: 'blur(10px) saturate(115%)',
        boxShadow: '0 0 0 1px rgba(91,213,242,0.10) inset, 0 18px 32px -16px rgba(0,0,0,0.55), 0 0 28px rgba(51,194,234,0.16)'
      }}>
      <div aria-hidden="true" className="absolute inset-0 pointer-events-none"
        style={{ background: 'linear-gradient(180deg, rgba(91,213,242,0.08) 0%, rgba(91,213,242,0.0) 55%)' }} />
      <div aria-hidden="true" className="absolute inset-x-3 top-0 h-px"
        style={{ background: 'linear-gradient(to right, transparent, rgba(91,213,242,0.85), transparent)',
                 boxShadow: '0 0 8px rgba(91,213,242,0.7)' }} />
      <div className="absolute top-2.5 left-3 flex items-center gap-1.5">
        <span className="relative flex size-1.5">
          <span className="absolute inset-0 rounded-full bg-cyan opacity-75 hero-orb-ping" />
          <span className="relative rounded-full bg-cyan size-1.5"
                style={{ boxShadow: '0 0 8px rgba(51,194,234,0.95)' }} />
        </span>
        <span className="font-mono text-[7.5px] uppercase tracking-[0.32em] text-cyan/75">on</span>
      </div>
      <div className="absolute top-2.5 right-3 font-mono text-[8px] tracking-[0.18em] text-ink/40">
        N{(index + 1).toString().padStart(2, '0')}
      </div>
      <div className="relative px-3 pt-7 pb-3 flex flex-col items-center gap-1.5">
        <div className="text-cyan grid place-items-center size-8 rounded-full"
             style={{ background: 'radial-gradient(circle, rgba(91,213,242,0.22), transparent 70%)' }}>
          <HeroBenefitIcon name={b.icon} size={18} />
        </div>
        <div className="font-serif text-[24px] leading-none text-ink"
             style={{ fontFamily: '"Instrument Serif", serif',
                      textShadow: '0 0 18px rgba(91,213,242,0.45)' }}>
          {b.value}
        </div>
        <div className="font-mono text-[9px] uppercase tracking-[0.18em] text-ink/95 text-center leading-tight">
          {b.label}
        </div>
        <div className="font-mono text-[8px] text-ink/55 text-center leading-tight">
          {b.sub}
        </div>
      </div>
    </div>);
}

function HeroGalaxiaVideo({ width = 520, height = 292 }) {
  const fadeX = 0.20, fadeY = 0.24, zoom = 1.22, cropX = -0.060, cropY = -0.055;
  const buildMask = (dir, fade) => {
    const f = fade * 100;
    return `linear-gradient(${dir},
      transparent 0%,
      rgba(0,0,0,0.10) ${(f * 0.20).toFixed(2)}%,
      rgba(0,0,0,0.30) ${(f * 0.40).toFixed(2)}%,
      rgba(0,0,0,0.60) ${(f * 0.60).toFixed(2)}%,
      rgba(0,0,0,0.85) ${(f * 0.80).toFixed(2)}%,
      #000 ${f.toFixed(2)}%,
      #000 ${(100 - f).toFixed(2)}%,
      rgba(0,0,0,0.85) ${(100 - f * 0.80).toFixed(2)}%,
      rgba(0,0,0,0.60) ${(100 - f * 0.60).toFixed(2)}%,
      rgba(0,0,0,0.30) ${(100 - f * 0.40).toFixed(2)}%,
      rgba(0,0,0,0.10) ${(100 - f * 0.20).toFixed(2)}%,
      transparent 100%)`;
  };
  const horizMask = buildMask('to right', fadeX);
  const vertMask  = buildMask('to bottom', fadeY);
  return (
    <div className="relative pointer-events-none select-none"
      style={{ width, height }}>
      <div className="absolute inset-0" style={{ WebkitMaskImage: horizMask, maskImage: horizMask }}>
        <div className="absolute inset-0 overflow-hidden" style={{ WebkitMaskImage: vertMask, maskImage: vertMask }}>
          <img src="assets/galaxia-hero-static.png" alt="" aria-hidden="true"
            style={{
              position: 'absolute', top: '50%', left: '50%',
              width:  `${(zoom * 100).toFixed(2)}%`,
              height: `${(zoom * 100).toFixed(2)}%`,
              transform: `translate(calc(-50% + ${(cropX * 100).toFixed(2)}%), calc(-50% + ${(cropY * 100).toFixed(2)}%))`,
              objectFit: 'cover',
              mixBlendMode: 'screen'
            }} />
        </div>
      </div>
    </div>);
}

function HeroGalaxiaCore() {
  const NUM_PER_SIDE = 4;
  const TOTAL = NUM_PER_SIDE * 2;
  const PERIOD_MS = 20000;
  const containerW = 720;
  const containerH = 480;
  const videoW = 520, videoH = 292;
  const videoOffsetY = -110;
  const cardH = 142;
  const startY = -cardH * 0.5;
  const endY = containerH + cardH * 0.5;
  const videoTop = (containerH - videoH) / 2 + videoOffsetY;
  const videoBot = (containerH + videoH) / 2 + videoOffsetY;
  const slotRefs = useRef([]);
  if (slotRefs.current.length !== TOTAL) slotRefs.current = Array(TOTAL).fill(null);
  useEffect(() => {
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    let raf = 0;
    const t0 = performance.now();
    const loop = (now) => {
      const baseT = (now - t0) / PERIOD_MS;
      for (let i = 0; i < TOTAL; i++) {
        const el = slotRefs.current[i];
        if (!el) continue;
        const side = i < NUM_PER_SIDE ? 'left' : 'right';
        const indexInSide = i % NUM_PER_SIDE;
        const phaseOffset = indexInSide / NUM_PER_SIDE;
        const t = ((baseT + phaseOffset) % 1 + 1) % 1;
        const y = endY - t * (endY - startY);
        const x = side === 'left' ? -videoW / 2 - 12 : +videoW / 2 - 4;
        let alpha;
        if (y > videoBot)      alpha = (endY - y) / (endY - videoBot);
        else if (y > videoTop) alpha = 1;
        else                   alpha = (y - startY) / (videoTop - startY);
        alpha = Math.max(0, Math.min(1, alpha));
        el.style.top    = `${y.toFixed(1)}px`;
        el.style.left   = `calc(50% + ${x.toFixed(1)}px)`;
        el.style.opacity = alpha.toFixed(3);
      }
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);
  return (
    <div className="relative w-full mx-auto" style={{ height: containerH, maxWidth: containerW }}>
      <div className="absolute left-1/2 -translate-x-1/2 -translate-y-1/2"
           style={{ top: `calc(50% + ${videoOffsetY}px)`, zIndex: 10 }}>
        <HeroGalaxiaVideo width={videoW} height={videoH} />
      </div>
      {Array.from({ length: TOTAL }).map((_, i) => (
        <div key={i} className="absolute"
          ref={(el) => { slotRefs.current[i] = el; }}
          style={{ top: 0, left: '50%', transform: 'translate(-50%, -50%)', zIndex: 20, willChange: 'top, opacity' }}>
          <HeroBenefitCard b={HERO_BENEFITS[i]} index={i} />
        </div>
      ))}
    </div>);
}

/* SECTION: Hero · primera ventana
   Split desktop con copy izquierda + HeroGalaxiaCore (video + 8 BenefitCards
   en streaming) derecha. Mobile: copy + 2 CTAs + AIEmployeesMenu. Después del
   split, abajo del fold, se monta la Demo V7 (id="agente") como segunda
   ventana de prueba. NO modificar HeroGalaxiaCore ni HeroDemoV7Full en V1. */
function Hero({ headline }) {
  return (
    <header id="top" className="relative pt-28 md:pt-32 pb-6 md:pb-8">
      <div className="md:hidden mx-auto max-w-[1280px] px-6">
        <div className="inline-flex items-center gap-2.5 rounded-full pl-3 pr-4 py-1.5 border border-line bg-glass backdrop-blur-md text-[10px] font-mono uppercase tracking-[0.22em] text-ink/80 mb-5">
          <span className="relative flex size-1.5">
            <span className="absolute inset-0 rounded-full bg-cyan opacity-60 hero-orb-ping" />
            <span className="relative rounded-full bg-cyan size-1.5" />
          </span>
          Inteligencia operativa para empresas
        </div>
        <h1 className="font-serif text-[clamp(34px,8.5vw,44px)] leading-[1.04] text-ink/95 mb-5"
          style={{ fontFamily: '"Instrument Serif", serif' }}>
          Empleados IA que entienden tu negocio y trabajan con <span className="italic text-cyan">tus reglas</span>.
        </h1>
        <p className="text-[15px] leading-[1.55] text-ink/74 mb-7">
          Atienden clientes, consultan datos, siguen procesos, detectan oportunidades y avisan al equipo cuando hace falta.
          <span className="text-ink/85"> Más abajo vas a ver uno operando en una conversación real.</span>
        </p>
        <div className="flex flex-col gap-3" style={{ width: 'min(320px, calc(100vw - 48px))' }}>
          <a href="#agente" className="btn-cta rounded-full bg-ink text-bg px-6 py-3.5 text-sm font-medium inline-flex items-center justify-center gap-3">
            Ver un agente operando en vivo
            <span aria-hidden="true" className="btn-arrow">↓</span>
          </a>
          <a href="#empleados-ia" className="btn-cta rounded-full border border-line bg-bg/40 px-6 py-3.5 text-sm text-ink/90 inline-flex items-center justify-center gap-3">
            <span aria-hidden="true" className="size-1.5 rounded-full bg-cyan pulse-node" />
            Ver el equipo IA
            <span aria-hidden="true" className="text-cyan btn-arrow">↓</span>
          </a>
          {/* V3 polish ADDENDUM 29 (2026-05-18) — render del menú externo
              oculto. Esta función Hero quedó como dead-code después de que
              hero-v2.jsx reasigna window.Hero al HeroOrbital del template,
              pero limpiamos igual por consistencia. */}
          {/* <AIEmployeesMenu variant="hero" /> */}
        </div>
      </div>

      <div className="hidden md:block mx-auto w-full max-w-[1480px] px-6 md:px-10 lg:px-14 lg:min-h-[calc(100vh-9rem)] lg:flex lg:items-center">
        <div className="w-full grid lg:grid-cols-12 gap-8 lg:gap-12 items-center">
          <div className="lg:col-span-7 xl:col-span-6 flex flex-col gap-5 md:gap-6">
            <Reveal>
              <div className="inline-flex self-start items-center gap-2.5 rounded-full pl-3 pr-4 py-1.5 border border-line bg-glass backdrop-blur-md text-[10.5px] font-mono uppercase tracking-[0.22em] text-ink/80">
                <span className="relative flex size-1.5">
                  <span className="absolute inset-0 rounded-full bg-cyan opacity-60 hero-orb-ping" />
                  <span className="relative rounded-full bg-cyan size-1.5" />
                </span>
                Inteligencia operativa para empresas
              </div>
            </Reveal>
            <Reveal delay={100}>
              <h1 className="font-serif text-[clamp(38px,4.6vw,68px)] leading-[1.02] tracking-[-0.012em] text-ink/97"
                style={{ fontFamily: '"Instrument Serif", serif' }}>
                Empleados IA que entienden tu negocio y trabajan con{' '}
                <span className="italic text-cyan" style={{ textShadow: '0 0 28px rgba(51,194,234,0.45)' }}>tus reglas</span>.
              </h1>
            </Reveal>
            <Reveal delay={200}>
              <p className="text-[15.5px] md:text-[17px] leading-[1.55] text-ink/72 max-w-[560px]">
                Atienden clientes, consultan datos, siguen procesos, detectan oportunidades y avisan al equipo cuando hace falta.
                <span className="text-ink/88"> Abajo vas a ver uno operando en una conversación real.</span>
              </p>
            </Reveal>
            <Reveal delay={300}>
              <div className="flex flex-wrap items-center gap-3">
                <a href="#agente" className="btn-cta rounded-full bg-ink text-bg px-6 py-3.5 text-[13.5px] font-medium inline-flex items-center gap-3">
                  Ver un agente operando en vivo
                  <span aria-hidden="true" className="btn-arrow">↓</span>
                </a>
                <a href="#agente" className="btn-cta rounded-full border border-line bg-bg/40 px-6 py-3.5 text-[13.5px] text-ink/90 inline-flex items-center gap-3">
                  <span aria-hidden="true" className="size-1.5 rounded-full bg-cyan pulse-node" />
                  Ver agente en acción
                  <span aria-hidden="true" className="text-cyan btn-arrow">↓</span>
                </a>
              </div>
            </Reveal>
            <Reveal delay={400}>
              <div className="flex items-center gap-3 text-ink/55 mt-1">
                <span className="h-px w-10 bg-line" />
                <span className="font-mono uppercase tracking-[0.22em] text-[10.5px]">Ver un agente trabajando en vivo</span>
                <span className="inline-block text-cyan/85" style={{ animation: 'hero-orb-scbounce 1.8s ease-in-out infinite' }}>↓</span>
              </div>
            </Reveal>
          </div>

          <div className="hidden lg:block lg:col-span-5 xl:col-span-6">
            <Reveal delay={180}>
              <div className="flex flex-col items-center">
                <HeroGalaxiaCore />
              </div>
            </Reveal>
          </div>
        </div>
      </div>

      <div id="agente" className="hidden md:block mt-10 md:mt-16 lg:mt-20">
        {/* Wrapper transparente para el mount V7. Antes tenia clase ng-stage,
            definida en hero-v7-full.css con 2 radial-gradients violeta+cyan
            anclados at 50% 0%. Esos radials SE SUMABAN con la regla
            .vignette::after global del body (tambien at 50% 0%) y producian
            un edge visible en el top del mount, la linea reportada. Removida
            la clase ng-stage, los selectores wa-, vtab y fchip del template
            V7 no dependen de ng-stage; el wrapper queda 100% transparente y
            la vignette global sigue aportando profundidad sin doblar capa. */}
        <div className="hero-v7-mount px-3 md:px-6 lg:px-10">
          <window.HeroDemoV7Full />
        </div>
      </div>
    </header>);
}

/* ───────── HeroChat showcase (used inside SeccionUnoIntro) ───────── */
const HERO_DUR = 8800;
function HeroChat() {
  const cases = typeof window !== 'undefined' && window.HERO_CASES || [];
  const [idx, setIdx] = useState(0);
  const [paused, setPaused] = useState(false);
  const [timerKey, setTimerKey] = useState(0);
  const [ref, seen] = useReveal({ threshold: 0.2, once: true });

  useEffect(() => {
    if (!seen || paused || cases.length === 0) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const id = setInterval(() => setIdx((i) => (i + 1) % cases.length), HERO_DUR);
    return () => clearInterval(id);
  }, [seen, paused, cases.length, timerKey]);

  const goNext = () => {setIdx((i) => (i + 1) % cases.length);setTimerKey((k) => k + 1);};
  const goPrev = () => {setIdx((i) => (i - 1 + cases.length) % cases.length);setTimerKey((k) => k + 1);};
  const goTo = (i) => {setIdx(i);setTimerKey((k) => k + 1);};

  if (cases.length === 0) return null;
  const c = cases[idx];

  return (
    <div ref={ref} className="relative" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
      <div className="relative rounded-2xl overflow-hidden border border-line"
        style={{ background: 'linear-gradient(180deg, rgba(244,241,234,0.025) 0%, rgba(244,241,234,0.008) 100%)', backdropFilter: 'blur(6px) saturate(110%)', WebkitBackdropFilter: 'blur(6px) saturate(110%)' }}>
        <div className="flex items-center justify-between px-5 pt-4 pb-3 border-b border-line">
          <div className="flex items-center gap-2 text-[10px] font-mono uppercase tracking-[0.22em]">
            <span className={`size-1.5 rounded-full pulse-node ${c.type === 'email' ? 'bg-violet' : 'bg-cyan'}`} />
            <span className="text-ink/80">{c.group}</span>
            <span className="text-dim">·</span>
            <span className="text-dim">{c.type === 'email' ? 'email-handoff' : 'conversación'}</span>
          </div>
          <div className="text-[10px] font-mono text-dim tracking-[0.2em]">caso · {c.code}</div>
        </div>
        <div className="relative" style={{ height: 560 }}>
          <div key={`${c.code}-${c.type}`} className="absolute inset-0 overflow-auto px-5 py-5"
            style={{ animation: 'heroFade 360ms cubic-bezier(0.65,0,0.35,1) both' }}>
            {c.type === 'chat' && <ChatSlide c={c} />}
            {c.type === 'email' && <EmailSlide c={c} />}
          </div>
          <button onClick={goPrev} aria-label="Caso anterior"
            className="absolute left-3 top-1/2 -translate-y-1/2 z-20 flex items-center justify-center text-ink/35 hover:text-cyan transition-colors duration-300"
            style={{ fontFamily: '"Instrument Serif", serif', fontSize: '38px', lineHeight: 1, fontWeight: 400 }}>
            <span aria-hidden="true">‹</span>
          </button>
          <button onClick={goNext} aria-label="Caso siguiente"
            className="absolute right-3 top-1/2 -translate-y-1/2 z-20 flex items-center justify-center text-ink/35 hover:text-cyan transition-colors duration-300"
            style={{ fontFamily: '"Instrument Serif", serif', fontSize: '38px', lineHeight: 1, fontWeight: 400 }}>
            <span aria-hidden="true">›</span>
          </button>
        </div>
        {c.behind &&
          <div key={`b-${c.code}`} className="px-5 py-3.5 border-t border-line"
            style={{ background: 'rgba(51,194,234,0.025)', animation: 'heroFade 480ms cubic-bezier(0.65,0,0.35,1) both', animationDelay: '120ms' }}>
            <div className="flex items-center gap-2 mb-1.5">
              <span className={`size-1.5 rounded-full ${c.badge && c.badge.tone === 'violet' ? 'bg-violet' : 'bg-cyan'} pulse-node`} />
              <span className="text-[10px] font-mono uppercase tracking-[0.22em] text-ink/85">{c.badge ? c.badge.txt : 'Detrás de escena'}</span>
            </div>
            <p className="text-[12px] leading-[1.55] text-mute">{c.behind}</p>
          </div>
        }
        <div className="px-4 py-3 border-t border-line flex items-center gap-1.5 overflow-x-auto">
          {cases.map((_, i) =>
            <button key={i} onClick={() => goTo(i)} aria-label={`Caso ${i + 1}`}
              className="group h-0.5 rounded-full bg-line overflow-hidden interactive shrink-0" style={{ width: 14 }}>
              <span className="block h-full bg-cyan origin-left"
                style={{
                  transform: `scaleX(${i < idx ? 1 : i === idx ? seen && !paused ? 1 : 0.05 : 0})`,
                  transition: i === idx && seen && !paused ? `transform ${HERO_DUR}ms linear` : 'transform 320ms ease'
                }} />
            </button>
          )}
          <span className="ml-auto pl-2 text-[10px] font-mono text-dim tabular shrink-0">{String(idx + 1).padStart(2, '0')} / {String(cases.length).padStart(2, '0')}</span>
        </div>
      </div>
      <style>{`
        @keyframes heroFade { 0% { opacity: 0; transform: translateY(6px); } 100% { opacity: 1; transform: translateY(0); } }
        @keyframes heroIn   { 0% { opacity: 0; transform: translateY(8px); } 100% { opacity: 1; transform: translateY(0); } }
        @keyframes typing   { 0%, 100% { opacity: 0.35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-2px); } }
        .typing-dot { animation: typing 1.1s ease-in-out infinite; }
      `}</style>
    </div>);
}

function ChatSlide({ c }) {
  return (
    <React.Fragment>
      <div className="flex items-center gap-3 mb-4">
        <div className="size-9 rounded-full bg-gradient-to-br from-cyan/35 to-violet/25 flex items-center justify-center text-[11px] font-mono">{c.who}</div>
        <div className="flex-1 min-w-0">
          <div className="text-[14px] truncate">{c.name}</div>
          <div className="text-[10px] text-dim font-mono uppercase tracking-[0.15em] truncate">{c.sub}</div>
        </div>
      </div>
      <div className="flex flex-col gap-2.5">
        {c.lines.map((m, i) => {
          const style = { animation: 'heroIn 460ms cubic-bezier(0.65,0,0.35,1) both', animationDelay: `${i * 150 + 80}ms` };
          if (m.thought) return <ThoughtAnno key={i} kind="thought" t={m.thought} style={style} />;
          if (m.action) return <ThoughtAnno key={i} kind="action" t={m.action} style={style} />;
          return <HeroBubble key={i} who={m.who} t={m.t} tm={m.tm} style={style} />;
        })}
      </div>
    </React.Fragment>);
}

function ThoughtAnno({ kind, t, style }) {
  const isAction = kind === 'action';
  return (
    <div className="flex items-center gap-3 my-1.5" style={style}>
      <span className="flex-1 h-px" style={{ backgroundImage: 'linear-gradient(to right, transparent, rgba(51,194,234,0.22))' }} />
      <span className={`inline-flex items-center gap-2 px-2.5 py-1 rounded-full text-[10.5px] font-mono uppercase tracking-[0.14em] ${isAction ? 'bg-violet/10 text-violet border border-violet/25' : 'bg-cyan/8 text-cyan/95 border border-cyan/20'}`}>
        <span aria-hidden="true">{isAction ? '⚡' : '✦'}</span>
        <span style={{ letterSpacing: '0.08em', textTransform: 'none' }} className="font-mono normal-case">{t}</span>
      </span>
      <span className="flex-1 h-px" style={{ backgroundImage: 'linear-gradient(to left, transparent, rgba(51,194,234,0.22))' }} />
    </div>);
}

function HeroBubble({ who, t, tm, style }) {
  const isUser = who === 'user';
  return (
    <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`} style={style}>
      <div className={`max-w-[86%] rounded-2xl px-3.5 py-2.5 text-[13.5px] leading-[1.42] ${isUser ? 'bg-cyan/15 border border-cyan/25 text-ink rounded-br-md' : 'bg-glass border border-line text-ink/95 rounded-bl-md'}`}>
        <div>{t}</div>
        <div className="text-[9.5px] font-mono mt-1 text-dim uppercase tracking-[0.15em]">{tm}{isUser ? ' ✓✓' : ''}</div>
      </div>
    </div>);
}

function EmailSlide({ c }) {
  const isUrgent = c.priority && c.priority.includes('ALTA');
  return (
    <div className="font-mono text-[12px]" style={{ animation: 'heroFade 480ms cubic-bezier(0.65,0,0.35,1) both' }}>
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <span className={`size-2 rounded-full ${isUrgent ? 'bg-violet pulse-node' : 'bg-cyan/70'}`} />
          <span className={`text-[10px] uppercase tracking-[0.2em] ${isUrgent ? 'text-violet' : 'text-dim'}`}>{c.priority || 'NORMAL'}</span>
        </div>
        <span className="text-[10px] uppercase tracking-[0.2em] text-dim">email · matías</span>
      </div>
      <div className="border-t border-b border-line py-3 mb-4 space-y-1.5">
        <div className="text-[11px] text-dim">De: <span className="text-ink/80">Bot Baridón &lt;bot@baridonpropiedades.com&gt;</span></div>
        <div className="text-[11px] text-dim">Para: <span className="text-ink/80">Matías</span></div>
      </div>
      <h4 className="font-serif text-[22px] leading-[1.18] mb-3 text-ink" style={{ fontFamily: '"Instrument Serif", serif' }}>{c.subject}</h4>
      <p className="text-[12.5px] text-mute leading-relaxed mb-5" style={{ fontFamily: 'Geist, system-ui, sans-serif' }}>{c.intro}</p>
      <div className="space-y-2 mb-5">
        {c.fields.map(([k, v], i) =>
          <div key={i} className="grid grid-cols-[110px_1fr] gap-3 py-1.5 border-b border-line/60">
            <span className="text-[10.5px] uppercase tracking-[0.15em] text-dim">{k}</span>
            <span className="text-[12.5px] text-ink/90" style={{ fontFamily: 'Geist, system-ui, sans-serif' }}>{v}</span>
          </div>
        )}
      </div>
      <button className="w-full mt-2 rounded-full bg-cyan/15 border border-cyan/35 px-4 py-2.5 text-[12px] text-cyan inline-flex items-center justify-center gap-2 hover:bg-cyan/20 transition-colors">
        <span aria-hidden="true">📱</span>
        <span style={{ fontFamily: 'Geist, system-ui, sans-serif' }}>{c.cta}</span>
      </button>
    </div>);
}

/* SECTION: Problema · qué dolor cubre el agente
   Tres síntomas universales para PyME: leads de noche perdidos, repetición
   del equipo, CRM y WhatsApp desconectados. */
function Problema() {
  const cards = [
    { k: '01', t: 'Perdés leads de noche.', d: 'Te escriben 22:40 y ven tu "visto" a las 9:00 del día siguiente. Para entonces ya consultaron a tres más.' },
    { k: '02', t: 'Tu equipo repite\nla misma respuesta 30 veces por día.', d: 'Precio, zonas, garantía, horarios. Pegan el mismo texto un millón de veces y se equivocan en uno.' },
    { k: '03', t: 'Tu CRM y tu WhatsApp\nviven en mundos distintos.', d: 'Carga manual, doble entrada, leads que se diluyen entre planillas. El follow-up se hace cuando se acuerdan.' }];
  return (
    <section id="problema" className="relative py-24 md:py-28">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="flex items-baseline justify-between gap-6 mb-16">
            <div>
              <div className="kicker mb-3">El problema</div>
              <h2 className="display-lg text-[clamp(40px,5.2vw,72px)] max-w-[800px]">
                La operación se rompe en los <span className="italic">bordes</span> —<br />donde nadie está mirando.
              </h2>
            </div>
          </div>
        </Reveal>
        <div className="grid md:grid-cols-3 gap-5">
          {cards.map((c, i) => <ProblemaCard key={i} {...c} delay={i * 120} />)}
        </div>
      </div>
    </section>);
}

function ProblemaCard({ k, t, d, delay }) {
  const tilt = useTilt(5);
  const [ref, seen] = useReveal();
  return (
    <div ref={ref} className={`reveal-up ${seen ? 'in' : ''}`} style={{ transitionDelay: `${delay}ms` }}>
      <div ref={tilt}
        className="card-solid conic-border group rounded-2xl p-8 md:p-9 h-full min-h-[380px] flex flex-col relative overflow-hidden"
        style={{ transformStyle: 'preserve-3d' }}>
        <div className="flex items-center gap-3 mb-8">
          <span className="font-mono text-[12px] tracking-[0.24em] uppercase text-cyan/85">{k}</span>
          <span className="h-px flex-1 bg-line group-hover:bg-cyan/30 transition-colors duration-500" />
          <span className="font-mono text-[11px] tracking-[0.2em] uppercase text-dim">síntoma</span>
        </div>
        <h3 className="font-serif text-[30px] md:text-[36px] leading-[1.05] tracking-tight whitespace-pre-line">{t}</h3>
        <div className="my-6 h-px bg-line origin-left scale-x-[0.18] group-hover:scale-x-100 transition-transform duration-700"
          style={{ transitionTimingFunction: 'cubic-bezier(0.65,0,0.35,1)' }} />
        <p className="text-[16px] md:text-[17px] text-ink/78 leading-[1.55] mt-auto">{d}</p>
        <span aria-hidden="true"
          className="absolute bottom-5 right-6 font-mono text-[11px] tracking-[0.2em] uppercase text-dim opacity-0 group-hover:opacity-100 transition-opacity duration-500">
          se puede automatizar →
        </span>
      </div>
    </div>);
}

/* SECTION: Proceso · cómo lo armamos
   Cuatro etapas: Diagnóstico / Diseño del agente / Implementación / Operación.
   Sirve como respuesta operativa a "¿cómo arranca esto en mi empresa?". */
function Proceso() {
  const steps = [
    { n: '01', t: 'Diagnóstico', d: 'Mapeamos tu operación: dónde se pierde tiempo, qué decisiones repite tu equipo, qué herramientas ya tenés.' },
    { n: '02', t: 'Diseño del agente', d: 'Definimos flujos, tono, reglas duras (lo que el bot nunca hace), y qué casos derivan a humano.' },
    { n: '03', t: 'Implementación', d: 'Conectamos WhatsApp, Notion, Sheets, tu CRM. Código real, versionado, con tests automatizados.' },
    { n: '04', t: 'Operación', d: 'QA continuo, métricas semanales, frases canónicas que vos editás sin redeploy. Mejora iterativa.' }];
  const [ref, seen] = useReveal({ threshold: 0.25 });
  const [progress, setProgress] = useState(0);
  useEffect(() => {
    if (!seen) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {setProgress(1);return;}
    const total = 3200;
    const t0 = performance.now() + 300;
    let raf = 0;
    const tick = (now) => {
      const k = Math.max(0, Math.min(1, (now - t0) / total));
      const eased = 1 - Math.pow(1 - k, 3);
      setProgress(eased);
      if (k < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [seen]);
  const threshold = (i) => i / (steps.length - 1);
  return (
    <section id="proceso" className="relative py-24 md:py-28">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="kicker mb-3">Cómo trabajamos</div>
          <h2 className="display-lg text-[clamp(40px,5.2vw,72px)] mb-16 max-w-[1000px]">
            <span className="italic">Cuatro etapas</span> te separan de tu actualización.
          </h2>
        </Reveal>
        <div ref={ref} className="relative">
          <div className="hidden md:block absolute top-[26px] left-[36px] right-[36px] h-[2px] bg-line overflow-hidden rounded-full">
            <div className="h-full origin-left"
              style={{ width: `${progress * 100}%`, background: 'linear-gradient(to right, rgba(51,194,234,0.55) 0%, #33C2EA 70%, rgba(91,213,242,0.95) 100%)', boxShadow: '0 0 12px rgba(51,194,234,0.6)' }} />
          </div>
          <div className="grid md:grid-cols-4 gap-8 md:gap-6">
            {steps.map((s, i) => {
              const lit = progress >= threshold(i) - 0.005;
              return (
                <div key={i} className="reveal-up"
                  ref={(el) => {
                    if (!el) return;
                    if (seen) el.classList.add('in'); else el.classList.remove('in');
                    el.style.transitionDelay = `${400 + i * 220}ms`;
                  }}>
                  <div className="relative z-10 size-[56px] rounded-full flex items-center justify-center font-mono text-cyan text-sm transition-all duration-500"
                    style={{ background: 'rgba(10,10,15,0.92)', borderWidth: '2px', borderStyle: 'solid',
                      borderColor: lit ? 'rgba(51,194,234,0.9)' : 'rgba(244,241,234,0.12)',
                      boxShadow: lit ? '0 0 0 4px rgba(51,194,234,0.10), 0 0 22px rgba(51,194,234,0.45)' : '0 0 0 0 rgba(51,194,234,0)'
                    }}>
                    {s.n}
                  </div>
                  <h3 className="font-serif text-2xl md:text-[28px] mt-6 mb-3 leading-tight">{s.t}</h3>
                  <p className="text-[16px] text-ink/78 leading-[1.55] max-w-[280px]">{s.d}</p>
                </div>);
            })}
          </div>
        </div>
      </div>
    </section>);
}

/* ───────── EmpleadosCentro · data + helpers ───────── */
const EMPLEADOS = [
  { rol: 'ATENCIÓN · INBOUND', nombre: 'Atención al cliente', desc: 'Responde 24/7, aplica tus reglas y deriva al humano cuando el caso lo amerita.',
    skills: ['entiende audios, imágenes y PDFs', 'consulta tu base de datos en vivo', 'detecta urgencia y escala'],
    verticales: ['Inmobiliaria', 'Club', 'Servicios'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M4 6.5C4 5.7 4.7 5 5.5 5h13c.8 0 1.5.7 1.5 1.5v8c0 .8-.7 1.5-1.5 1.5H10l-4 3v-3H5.5C4.7 16 4 15.3 4 14.5v-8Z"/><circle cx="9" cy="10.5" r=".7" fill="currentColor" stroke="none"/><circle cx="12" cy="10.5" r=".7" fill="currentColor" stroke="none"/><circle cx="15" cy="10.5" r=".7" fill="currentColor" stroke="none"/></svg>) },
  { rol: 'VENTAS · COMERCIAL', nombre: 'Comercial', desc: 'Califica leads, cotiza con tu catálogo, agenda visitas y avisa al equipo con resumen.',
    skills: ['califica intención y urgencia', 'cotiza con tus reglas', 'agenda en tu calendario'],
    verticales: ['Inmobiliaria', 'Concesionaria', 'B2B'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M3 17l5-5 4 4 8-8"/><path d="M14 8h7v7"/></svg>) },
  { rol: 'RESERVAS · AGENDA', nombre: 'Reservas y turnos', desc: 'Toma reservas, confirma asistencia, libera turnos cancelados y recuerda al cliente.',
    skills: ['valida disponibilidad real', 'recordatorios automáticos', 'reasigna ante cancelación'],
    verticales: ['Clínica', 'Restaurante', 'Spa'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></svg>) },
  { rol: 'DOCS · BACKOFFICE', nombre: 'Documentos', desc: 'Lee DNI, constancias, comprobantes y formularios; extrae datos y los deja estructurados.',
    skills: ['OCR + comprensión semántica', 'valida campos obligatorios', 'archiva con etiquetas'],
    verticales: ['Contable', 'Inmobiliaria', 'Legal'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6M8 13h8M8 17h5"/></svg>) },
  { rol: 'STOCK · PEDIDOS', nombre: 'Stock y pedidos', desc: 'Toma pedidos por WhatsApp, valida stock en vivo y deja la orden lista para armar.',
    skills: ['catálogo sincronizado', 'detecta producto inexistente', 'integra a tu sistema'],
    verticales: ['Distribuidora', 'E-commerce', 'Gastronomía'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M3 7h18l-1 12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2L3 7z"/><path d="M8 7V5a4 4 0 0 1 8 0v2"/></svg>) },
  { rol: 'SEGUIMIENTO · FOLLOW-UP', nombre: 'Seguimiento', desc: 'Retoma conversaciones frías, agenda recordatorios y no deja caer oportunidades.',
    skills: ['detecta "después te aviso"', 'agenda follow-up con condición', 'retoma contexto al día siguiente'],
    verticales: ['Inmobiliaria', 'B2B', 'Servicios'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><circle cx="12" cy="12" r="8"/><path d="M12 7.5V12l3 2"/><path d="M20 5.5l-2 1.5"/></svg>) }];

const OPORTUNIDADES_CHIPS = [
  { tag: 'demanda',     titulo: 'Producto inexistente',  ejemplo: '8 clientes preguntaron por alquiler con piscina — ninguna propiedad ofrece esa característica.' },
  { tag: 'horario',     titulo: 'Horario poco cubierto', ejemplo: '12 consultas viernes 18–20h — hoy el consultorio cierra a las 17h.' },
  { tag: 'idioma',      titulo: 'Idioma no atendido',    ejemplo: '3 consultas en portugués sobre membresías premium — sin respuesta bilingüe disponible.' },
  { tag: 'fricción',    titulo: 'Objeción frecuente',    ejemplo: '35% de leads nuevos pregunta "atienden con tarjeta" antes de avanzar.' },
  { tag: 'reactivable', titulo: 'Lead frío reactivable', ejemplo: '22 contactos con interés declarado hace +30 días, sin seguimiento.' }];

const DASHBOARD_KPIS = [
  { label: 'Mensajes leídos',        numeric: 1284, fmt: 'thousands',               trend: '+18%',       sub: 'audios · imágenes · documentos',
    tip: 'Audios, imágenes y documentos procesados por tu agente sin que un humano tenga que intervenir.' },
  { label: 'Visitas / reservas',     numeric: 47,   fmt: 'plain',                   trend: '+6',         sub: 'coordinadas por tu agente',
    tip: 'Oportunidades filtradas y listas para que tu equipo solo confirme día y hora con el cliente.' },
  { label: 'Costo operativo',        numeric: 150,  fmt: 'plain',     prefix: '$ ', trend: 'USD',        sub: 'modelo · API · hosting · monitoreo',
    tip: 'Costo total del sistema funcionando: modelo IA, infraestructura, integraciones y monitoreo continuo.' },
  { label: 'Oportunidades nuevas',   numeric: 12,   fmt: 'plain',                   trend: 'detectadas', sub: 'demanda no atendida',
    tip: 'Señales de demanda, fricciones recurrentes e idiomas no atendidos que tu IA detectó en conversaciones.' }];

const DASHBOARD_LIVE_EVENTS = [
  { type: 'mensaje', text: 'Audio leído · intención de visita detectada' },
  { type: 'cliente', text: 'Sofía R. pasó a esperando staff' },
  { type: 'oportunidad', text: 'Nueva demanda detectada: alquiler con piscina' },
  { type: 'costo', text: 'Costo actualizado por procesamiento de documentos' },
  { type: 'cliente', text: 'Mariana P. confirmó visita para viernes' },
  { type: 'mensaje', text: 'PDF leído · datos extraídos' },
  { type: 'oportunidad', text: 'Horario 18-20h vuelve a concentrar consultas' },
  { type: 'cliente', text: 'Federico G. entra en seguimiento automático' }];

const DASHBOARD_CLIENTES = [
  { iniciales: 'DM', nombre: 'Diego Martínez',     intencion: 'Alquiler · Pocitos',          estado: 'Calificado',         estadoTone: 'cyan',     proximo: 'Agendar visita' },
  { iniciales: 'SR', nombre: 'Sofía Ramírez',      intencion: 'Match link MercadoLibre',     estado: 'Esperando staff',    estadoTone: 'amber',    proximo: 'Confirmar mascotas' },
  { iniciales: 'MP', nombre: 'Mariana Pereyra',    intencion: 'Mudanza viernes · urgente',   estado: 'Visita agendada',    estadoTone: 'violet',   proximo: 'Vie 09:30 confirmado' },
  { iniciales: 'FG', nombre: 'Federico González',  intencion: 'Promesa de cierre · viernes', estado: 'Seguimiento',        estadoTone: 'cyan',     proximo: 'Cron · vie 09:00' },
  { iniciales: 'LB', nombre: 'Luciana Bermúdez',   intencion: 'Pidió piscina · sin stock',   estado: 'Oportunidad',        estadoTone: 'gradient', proximo: 'Captar inventario' }];

const DASHBOARD_CLIENT_UPDATES = [
  { idx: 0, estado: 'Calificado',      estadoTone: 'cyan',     proximo: 'Agendar visita',           intencion: 'Alquiler · Pocitos' },
  { idx: 1, estado: 'Esperando staff', estadoTone: 'amber',    proximo: 'Confirmar mascotas',       intencion: 'Match link MercadoLibre' },
  { idx: 4, estado: 'Oportunidad',     estadoTone: 'gradient', proximo: 'Captar inventario',        intencion: 'Pidió piscina · sin stock' },
  { idx: 2, estado: 'Visita agendada', estadoTone: 'violet',   proximo: 'Vie 09:30 confirmado',     intencion: 'Mudanza viernes · urgente' },
  { idx: 3, estado: 'Seguimiento',     estadoTone: 'cyan',     proximo: 'Cron · vie 09:00',         intencion: 'Promesa de cierre · viernes' },
  { idx: 0, estado: 'Esperando staff', estadoTone: 'amber',    proximo: 'Revisar garantía ANDA',    intencion: 'Garantía · consulta nueva' },
  { idx: 1, estado: 'Visita agendada', estadoTone: 'violet',   proximo: 'Sáb 11:00 confirmado',     intencion: 'Quiere ver apartamento' },
  { idx: 4, estado: 'Seguimiento',     estadoTone: 'cyan',     proximo: 'Avisar si entra piscina',  intencion: 'Demanda sin stock' }];

const DASHBOARD_OPORTUNIDADES = [
  { titulo: '8 clientes piden alquiler con piscina',  accion: 'Captar inventario · campaña outbound' },
  { titulo: 'Demanda viernes 18-20h sin cubrir',      accion: 'Evaluar extender un turno o lista de espera' },
  { titulo: '3 leads en portugués sin respuesta',     accion: 'Activar agente bilingüe' },
  { titulo: 'Objeción repetida: garantía ANDA',       accion: 'Agregar respuesta canónica al agente' },
  { titulo: 'Leads fríos con interés declarado',      accion: 'Reactivar con seguimiento automático' },
  { titulo: 'Consultas por mascota antes de visitar', accion: 'Marcar propiedades pet-friendly' }];

const DASHBOARD_COST_MIX = [
  [46, 26, 14, 14],
  [44, 28, 14, 14],
  [48, 24, 13, 15],
  [45, 27, 15, 13]];

function formatKpi(k, n) {
  const rounded = Math.max(0, Math.round(n));
  const body = k.fmt === 'thousands'
    ? rounded.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
    : String(rounded);
  return `${k.prefix || ''}${body}${k.suffix || ''}`;
}

function KpiCard({ k, started, delay = 0, active = false }) {
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!started) return;
    let raf = 0;
    let t0;
    const from = val;
    const target = k.numeric;
    const dur = 520;
    function tick(now) {
      if (t0 === undefined) t0 = now;
      const k2 = Math.min(1, Math.max(0, (now - t0 - delay) / dur));
      const eased = 1 - Math.pow(1 - k2, 3);
      setVal(from + (target - from) * eased);
      if (k2 < 1) raf = requestAnimationFrame(tick);
    }
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [started, k.numeric, delay]);

  const displayed = started ? formatKpi(k, val) : formatKpi(k, 0);

  return (
    <div className={`rounded-xl border bg-bg/40 px-4 py-3.5 relative group transition-all duration-300 hover:border-cyan/35 focus-within:border-cyan/35 ${active ? 'border-cyan/45 shadow-[0_0_28px_-18px_rgba(51,194,234,0.95)]' : 'border-line'}`}>
      <div className="flex items-start gap-2 mb-1.5">
        <span className="text-[10px] font-mono uppercase tracking-[0.18em] text-dim flex-1 leading-[1.3]">{k.label}</span>
        {k.tip &&
          <button type="button" aria-label={`Qué significa ${k.label}`}
            onClick={(e) => e.preventDefault()}
            className="size-3.5 rounded-full border border-cyan/40 text-cyan/85 hover:text-cyan hover:border-cyan focus:text-cyan focus:border-cyan focus:outline-none flex items-center justify-center text-[9px] font-mono leading-none transition-colors flex-shrink-0">
            i
          </button>
        }
      </div>
      <div className="flex items-baseline gap-2 min-w-0">
        <span className="text-[22px] md:text-[24px] font-serif text-ink tabular leading-none whitespace-nowrap flex-shrink-0" style={{ fontFamily: '"Instrument Serif", serif' }}>{displayed}</span>
        <span className="text-[10.5px] font-mono uppercase tracking-[0.12em] text-cyan/85 min-w-0 truncate">{k.trend}</span>
      </div>
      <div className="text-[10.5px] text-dim mt-1.5 leading-[1.35]">{k.sub}</div>
      <span className={`absolute right-3 bottom-3 size-1.5 rounded-full bg-cyan transition-opacity duration-300 ${active ? 'opacity-100 ng-live-dot' : 'opacity-0'}`} aria-hidden="true" />
      {k.tip &&
        <div role="tooltip" className="absolute left-2 right-2 -top-2 -translate-y-full opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-200 pointer-events-none z-30">
          <div className="rounded-lg px-3 py-2 text-[11.5px] leading-[1.45] text-ink/92"
            style={{ background: 'rgba(11,11,18,0.96)', border: '1px solid rgba(51,194,234,0.35)', boxShadow: '0 12px 28px -10px rgba(0,0,0,0.6), 0 0 0 1px rgba(51,194,234,0.06)' }}>
            {k.tip}
          </div>
        </div>
      }
    </div>);
}

function EmpleadoCard({ emp, idx }) {
  return (
    <article className="card-solid rounded-2xl p-6 md:p-7 group transition-all duration-300 hover:border-cyan/35 hover:-translate-y-0.5 flex flex-col h-full w-full"
      style={{ boxShadow: '0 0 0 1px rgba(244,241,234,0.04), 0 18px 40px -28px rgba(0,0,0,0.55)' }}>
      <div className="flex items-start justify-between mb-5">
        <div className="size-10 rounded-xl bg-cyan/10 border border-cyan/30 text-cyan flex items-center justify-center">{emp.icon}</div>
        <span className="text-[10px] font-mono uppercase tracking-[0.2em] text-dim">0{idx + 1}</span>
      </div>
      <div className="kicker mb-2 text-cyan/85" style={{ color: 'rgba(51,194,234,0.85)' }}>{emp.rol}</div>
      <h4 className="font-serif text-[24px] md:text-[26px] leading-[1.1] text-ink/95 mb-3" style={{ fontFamily: '"Instrument Serif", serif' }}>{emp.nombre}</h4>
      <p className="text-[14px] leading-[1.5] text-mute mb-5">{emp.desc}</p>
      <ul className="space-y-1.5 mb-6 flex-1">
        {emp.skills.map((s, i) => (
          <li key={i} className="flex items-start gap-2 text-[13px] text-ink/82 leading-[1.45]">
            <span className="text-cyan flex-shrink-0 mt-[1px]" aria-hidden="true">✓</span><span>{s}</span>
          </li>
        ))}
      </ul>
      <div className="flex flex-wrap gap-1.5 pt-4 border-t border-line">
        {emp.verticales.map((v, i) => (
          <span key={i} className="text-[10px] font-mono uppercase tracking-[0.14em] text-dim px-2 py-0.5 rounded-full border border-line">{v}</span>
        ))}
      </div>
    </article>);
}

function EstadoChip({ tone, label }) {
  const styles = {
    cyan:     { bg:'rgba(51,194,234,0.14)',   bd:'rgba(51,194,234,0.36)',   tx:'#7BD9F1' },
    amber:    { bg:'rgba(242,178,92,0.14)',   bd:'rgba(242,178,92,0.36)',   tx:'#EFC585' },
    violet:   { bg:'rgba(158,123,255,0.14)',  bd:'rgba(158,123,255,0.36)',  tx:'#C0AAFF' },
    neutral:  { bg:'rgba(244,241,234,0.06)',  bd:'rgba(244,241,234,0.16)',  tx:'rgba(244,241,234,0.72)' },
    gradient: { bg:'linear-gradient(90deg, rgba(51,194,234,0.18), rgba(158,123,255,0.18))', bd:'rgba(158,123,255,0.45)', tx:'#EAF7FF' }};
  const s = styles[tone] || styles.neutral;
  return (
    <span className="text-[10px] font-mono uppercase tracking-[0.1em] px-2 py-[3px] rounded-full whitespace-nowrap"
      style={{ background: s.bg, border: `1px solid ${s.bd}`, color: s.tx }}>{label}</span>);
}

function DashboardMockup() {
  const [wrapRef, seen] = useReveal({ threshold: 0.22 });
  const [liveTick, setLiveTick] = useState(0);
  useEffect(() => {
    if (!seen) return;
    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) return;
    const id = setInterval(() => setLiveTick((i) => i + 1), 1000);
    return () => clearInterval(id);
  }, [seen]);
  const event = DASHBOARD_LIVE_EVENTS[liveTick % DASHBOARD_LIVE_EVENTS.length];
  const activeKpi = liveTick % DASHBOARD_KPIS.length;
  const liveKpis = DASHBOARD_KPIS.map((k, i) => {
    const bumps = [
      liveTick * 3 + (event.type === 'mensaje' ? 7 : 0),
      Math.floor(liveTick / 3) + (event.type === 'cliente' ? 1 : 0),
      (liveTick % 10) + (event.type === 'costo' ? 3 : 0),
      Math.floor(liveTick / 2) + (event.type === 'oportunidad' ? 1 : 0)
    ];
    const dynamicTrend = i === activeKpi
      ? (i === 2 ? 'USD' : i === 3 ? 'nueva' : '+1')
      : k.trend;
    return { ...k, numeric: k.numeric + bumps[i], trend: dynamicTrend };
  });
  const clientUpdate = DASHBOARD_CLIENT_UPDATES[liveTick % DASHBOARD_CLIENT_UPDATES.length];
  const liveClients = DASHBOARD_CLIENTES.map((c, i) => i === clientUpdate.idx ? { ...c, ...clientUpdate } : c);
  const visibleOps = [0, 1, 2].map((_, i) => DASHBOARD_OPORTUNIDADES[(liveTick + i) % DASHBOARD_OPORTUNIDADES.length]);
  const costMix = DASHBOARD_COST_MIX[liveTick % DASHBOARD_COST_MIX.length];
  const liveCost = liveKpis[2];
  return (
    <div ref={wrapRef}
      className="rounded-2xl border border-line overflow-hidden relative w-full max-w-full"
      style={{
        background: 'linear-gradient(180deg, rgba(244,241,234,0.025), rgba(244,241,234,0.005))',
        backdropFilter: 'blur(10px) saturate(110%)', WebkitBackdropFilter: 'blur(10px) saturate(110%)',
        boxShadow: '0 0 0 1px rgba(51,194,234,0.08), 0 32px 80px -34px rgba(51,194,234,0.32), 0 20px 48px -28px rgba(0,0,0,0.55)'
      }}>
      <style>{`
        @keyframes ng-live-dot { 0%,100% { opacity:1; transform:scale(1);} 50% { opacity:.5; transform:scale(.78);} }
        @keyframes ng-event-fade { 0% { opacity:0; transform: translateY(2px);} 100% { opacity:1; transform: translateY(0);} }
        @keyframes ng-live-flash { 0% { box-shadow: 0 0 0 0 rgba(51,194,234,0.0); } 45% { box-shadow: 0 0 0 1px rgba(51,194,234,0.36), 0 0 28px -12px rgba(51,194,234,0.95); } 100% { box-shadow: 0 0 0 0 rgba(51,194,234,0.0); } }
        .ng-live-dot{ animation: ng-live-dot 1.6s ease-in-out infinite; }
        .ng-event-text{ animation: ng-event-fade 360ms ease both; }
        .ng-live-flash{ animation: ng-live-flash 900ms ease both; }
        @media (max-width: 379px){
          .ng-dashboard-body{ padding-left: 12px !important; padding-right: 12px !important; }
          .ng-kpi-grid{ grid-template-columns: 1fr !important; }
        }
        @media (prefers-reduced-motion: reduce){ .ng-live-dot, .ng-event-text, .ng-live-flash { animation: none !important; } }
      `}</style>
      <div className="flex items-center justify-center gap-2 px-4 py-3 border-b border-line bg-bg/40">
        <span className="size-2 rounded-full bg-cyan ng-live-dot flex-shrink-0" />
        <span className="text-[9.5px] sm:text-[10.5px] font-mono uppercase tracking-[0.12em] sm:tracking-[0.2em] text-ink/85 whitespace-nowrap text-center">Centro Operativo · Inmobiliaria</span>
      </div>
      <div className="ng-dashboard-body p-5 md:p-7 grid gap-5 md:gap-6 lg:grid-cols-[1.55fr_1fr] min-w-0">
        <div className="flex flex-col gap-5 md:gap-6 min-w-0">
          <div className="ng-kpi-grid grid grid-cols-2 gap-3 md:gap-4 min-w-0">
            {liveKpis.map((k, i) => <KpiCard key={i} k={k} started={seen} delay={i * 80} active={activeKpi === i} />)}
          </div>
          <div className="rounded-xl border border-line bg-bg/40 overflow-hidden">
            <div className="px-4 py-2.5 border-b border-line flex items-center gap-2 text-[10.5px] font-mono uppercase tracking-[0.18em]">
              <span className="text-ink/85">Clientes · estado</span>
              <span className="ml-auto text-dim hidden sm:inline">5 visibles · 47 total</span>
            </div>
            <div>
              {liveClients.map((c, i) => (
                <div key={i} className={`px-4 py-3 flex items-center gap-3 border-t border-line/40 first:border-t-0 transition-colors duration-300 ${clientUpdate.idx === i ? 'bg-cyan/5 ng-live-flash' : ''}`}>
                  <div className="size-7 rounded-full text-[10.5px] font-mono flex items-center justify-center flex-shrink-0 text-ink/85"
                    style={{ background: 'linear-gradient(135deg, rgba(51,194,234,0.28), rgba(158,123,255,0.18))' }}>{c.iniciales}</div>
                  <div className="flex-1 min-w-0">
                    <div className="text-[13px] text-ink/92 truncate leading-tight">{c.nombre}</div>
                    <div className="text-[11px] text-dim truncate leading-tight mt-0.5">{c.intencion}</div>
                  </div>
                  <EstadoChip tone={c.estadoTone} label={c.estado} />
                  <span className="hidden md:inline-flex text-[11px] text-mute min-w-[140px] truncate justify-end">{c.proximo}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
        <div className="flex flex-col gap-4 md:gap-5 min-w-0">
          <div>
            <div className="text-[10.5px] font-mono uppercase tracking-[0.18em] text-ink/85 mb-3">Oportunidades detectadas</div>
            <div className="flex flex-col gap-2.5">
              {visibleOps.map((o, i) => (
                <div key={`${liveTick}-${i}`} className={`rounded-xl border border-cyan/22 px-4 py-3 ${i === 0 ? 'ng-live-flash' : ''}`} style={{ background: 'rgba(51,194,234,0.06)' }}>
                  <div className="text-[12.5px] text-ink/92 leading-[1.4] mb-1">{o.titulo}</div>
                  <div className="text-[11px] text-dim leading-[1.4]"><span className="text-cyan/85 mr-1">→</span>{o.accion}</div>
                </div>
              ))}
            </div>
          </div>
          <div className="rounded-xl border border-line bg-bg/40 p-4">
            <div className="flex items-center text-[10.5px] font-mono uppercase tracking-[0.18em] mb-3">
              <span className="text-ink/85">Costo operativo</span>
              <span className="ml-auto text-cyan tabular">{formatKpi(liveCost, liveCost.numeric)} / mes</span>
            </div>
            <div className="flex h-1.5 rounded-full overflow-hidden mb-3" style={{ background: 'rgba(244,241,234,0.06)' }}>
              <div style={{ width: `${costMix[0]}%`, background: '#33C2EA', transition: 'width 520ms var(--ease)' }} />
              <div style={{ width: `${costMix[1]}%`, background: '#9E7BFF', transition: 'width 520ms var(--ease)' }} />
              <div style={{ width: `${costMix[2]}%`, background: 'rgba(244,241,234,0.40)', transition: 'width 520ms var(--ease)' }} />
              <div style={{ width: `${costMix[3]}%`, background: 'rgba(244,241,234,0.22)', transition: 'width 520ms var(--ease)' }} />
            </div>
            <div className="grid grid-cols-2 gap-x-3 gap-y-1.5 text-[10px] font-mono uppercase tracking-[0.08em] text-dim">
              <span><span className="inline-block size-1.5 rounded-full bg-cyan mr-1.5 align-middle" />Modelo IA · {costMix[0]}%</span>
              <span><span className="inline-block size-1.5 rounded-full bg-violet mr-1.5 align-middle" />WhatsApp/API · {costMix[1]}%</span>
              <span><span className="inline-block size-1.5 rounded-full mr-1.5 align-middle" style={{ background: 'rgba(244,241,234,0.4)' }} />Hosting · {costMix[2]}%</span>
              <span><span className="inline-block size-1.5 rounded-full mr-1.5 align-middle" style={{ background: 'rgba(244,241,234,0.22)' }} />Monitoreo · {costMix[3]}%</span>
            </div>
          </div>
        </div>
      </div>
    </div>);
}

function OportunidadChip({ op, idx }) {
  return (
    <article className="rounded-xl border border-line bg-bg/40 px-4 py-4 transition-all duration-300 hover:border-cyan/35 hover:-translate-y-0.5"
      style={{ boxShadow: '0 0 0 1px rgba(244,241,234,0.02), 0 12px 28px -22px rgba(0,0,0,0.45)' }}>
      <div className="flex items-center gap-2 mb-2.5">
        <span className="size-1.5 rounded-full bg-cyan" />
        <span className="text-[10px] font-mono uppercase tracking-[0.18em] text-ink/82">{op.tag}</span>
        <span className="ml-auto text-[10px] font-mono uppercase tracking-[0.18em] text-dim">0{idx + 1}</span>
      </div>
      <h4 className="font-serif text-[18px] leading-[1.15] text-ink/95 mb-2" style={{ fontFamily: '"Instrument Serif", serif' }}>{op.titulo}</h4>
      <p className="text-[12px] text-mute leading-[1.5]">{op.ejemplo}</p>
    </article>);
}

/* SECTION: Empleados IA + Centro Operativo
   Bloque central de capacidad full del producto: tres sub-bloques
   (Equipo IA / Centro Operativo / Oportunidades). Por decisión de Martin
   en V1, el DashboardMockup se conserva visible (NO se compacta a
   colapsable) — el panel operativo es prueba pesada de capacidad y
   diferenciador clave. ID renombrado a "empleados-ia" para alinear con
   el lenguaje del Nav y los CTAs. */
function EmpleadosCentro() {
  return (
    <section id="empleados-ia" className="relative py-24 md:py-32">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="text-center mb-16 md:mb-20 max-w-[960px] mx-auto">
            <div className="kicker mb-4">Empleados IA + Centro Operativo</div>
            <h2 className="display-lg text-[clamp(38px,4.8vw,72px)] leading-[1.02] mb-7">
              Un equipo de IA conectado a tu negocio. <span className="italic text-cyan">Y un panel para verlos trabajar.</span>
            </h2>
            <p className="text-[16px] md:text-[17.5px] text-mute leading-[1.6] max-w-[760px] mx-auto">
              Después del demo viste una conversación. Acá te mostramos qué más pueden hacer otros compañeros como ese: atender, vender, agendar, revisar documentos, consultar stock, hacer seguimiento y detectar oportunidades que tu negocio todavía no aprovechó.
            </p>
          </div>
        </Reveal>
        <div className="mt-16 md:mt-24">
          <Reveal>
            <div className="flex flex-col md:flex-row md:items-baseline md:gap-6 mb-8 md:mb-10">
              <span className="kicker mb-2 md:mb-0 md:min-w-[180px]">01 · Tu equipo IA</span>
              <h3 className="font-serif text-[clamp(26px,2.8vw,38px)] leading-[1.08] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>
                Cada empleado, <span className="italic">especializado</span>.
              </h3>
            </div>
          </Reveal>
          <div className="md:hidden -mx-6 overflow-hidden">
            <div className="team-ai-rail flex overflow-x-auto snap-x snap-mandatory gap-4 px-6 pb-3"
              style={{ scrollbarWidth: 'none', WebkitOverflowScrolling: 'touch' }}>
              {EMPLEADOS.map((emp, i) => (
                <div key={emp.nombre} className="snap-start flex-shrink-0 flex" style={{ width: 'min(82vw, 340px)' }}>
                  <EmpleadoCard emp={emp} idx={i} />
                </div>
              ))}
              <div aria-hidden="true" className="flex-shrink-0 w-2" />
            </div>
            <div className="swipe-hint mt-3 mx-auto" role="status" aria-label="Deslizá para ver más empleados IA">
              <span className="swipe-hint-track" aria-hidden="true">
                <span className="swipe-hint-finger" />
              </span>
              <span className="swipe-hint-label">Deslizá para ver empleados</span>
            </div>
          </div>
          <div className="hidden md:grid gap-4 md:gap-5 sm:grid-cols-2 lg:grid-cols-3">
            {EMPLEADOS.map((emp, i) => <EmpleadoCard key={emp.nombre} emp={emp} idx={i} />)}
          </div>
          <p className="mt-7 md:mt-8 text-[13px] font-mono uppercase tracking-[0.16em] text-dim text-center">
            Diez empleados más en catálogo · QA · Oportunidades · Asistente Interno · Cobranzas y otros
          </p>
        </div>
        <div className="mt-20 md:mt-32 pt-16 md:pt-20 border-t border-line">
          <Reveal>
            <div className="flex flex-col md:flex-row md:items-baseline md:gap-6 mb-3">
              <span className="kicker mb-2 md:mb-0 md:min-w-[180px]">02 · Centro Operativo</span>
              <h3 className="font-serif text-[clamp(26px,2.8vw,38px)] leading-[1.08] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>
                Todo lo que tu equipo hace, <span className="italic">en un panel</span>.
              </h3>
            </div>
            <div className="md:pl-[204px] mb-10 md:mb-12">
              <p className="text-[14.5px] text-mute leading-[1.55] max-w-[640px]">
                Panel personalizado por proyecto, conectado a los datos que importan. Acá se ven señales operativas del demo de inmobiliaria.
              </p>
            </div>
          </Reveal>
          <Reveal delay={120}><DashboardMockup /></Reveal>
        </div>
        <div className="mt-20 md:mt-32 pt-16 md:pt-20 border-t border-line">
          <Reveal>
            <div className="flex flex-col md:flex-row md:items-baseline md:gap-6 mb-3">
              <span className="kicker mb-2 md:mb-0 md:min-w-[180px]">03 · Oportunidades</span>
              <h3 className="font-serif text-[clamp(26px,2.8vw,38px)] leading-[1.08] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>
                Lo que tu IA detecta y tu negocio <span className="italic">aún no aprovechó</span>.
              </h3>
            </div>
            <div className="md:pl-[204px] mb-10 md:mb-12">
              <p className="text-[14.5px] text-mute leading-[1.55] max-w-[680px]">
                Tu agente no solo atiende. También encuentra señales de demanda, fricciones y oportunidades que antes quedaban perdidas en conversaciones.
              </p>
            </div>
          </Reveal>
          <div className="grid gap-3 md:gap-4 sm:grid-cols-2 lg:grid-cols-5">
            {OPORTUNIDADES_CHIPS.map((op, i) => <OportunidadChip key={op.tag} op={op} idx={i} />)}
          </div>
        </div>
        <Reveal>
          <div className="mt-20 md:mt-28 flex flex-col sm:flex-row gap-3 sm:gap-4 sm:justify-center items-stretch sm:items-center">
            <a href="#contacto" className="btn-cta rounded-full bg-ink text-bg px-7 py-3.5 text-sm font-medium inline-flex items-center justify-center gap-3">
              Armar mi equipo + panel
              <span aria-hidden="true" className="btn-arrow">→</span>
            </a>
            <a href="#proceso" className="btn-cta rounded-full border border-line bg-bg/40 px-7 py-3.5 text-sm text-ink/90 inline-flex items-center justify-center gap-3">
              Ver cómo lo armamos
              <span aria-hidden="true" className="text-cyan btn-arrow">↓</span>
            </a>
          </div>
        </Reveal>
      </div>
    </section>);
}

/* ───────── Verticales · 3D coverflow ───────── */
/* SECTION: Casos (verticales)
   V1 compactada: 5 migraciones representativas en lugar de 9. Las
   mantenidas (Inmobiliaria, Restaurante, Veterinaria, Concesionaria,
   Distribuidora) cubren los verticales más consultados y matchean
   directo con la demo V7. Eliminadas (Estudio contable, Curso online,
   Gimnasio, Spa) quedan disponibles en backlog para reintroducir si
   un prospect específico lo justifica. ID renombrado a "casos" (antes
   "verticales") porque coincide con el label que ya usa el Nav. */
function Verticales() {
  const cases = [
    { biz: 'Inmobiliaria', tag: 'Real estate',
      before: ['WhatsApp saturado con consultas repetidas — zona, precio, garantía','Catálogo actualizado a mano en una planilla','Leads de noche y fin de semana sin respuesta'],
      after: ['Bot que filtra propiedades por dormitorios, zona, precio o ID','Catálogo sincronizado desde tu sistema cada hora','Atiende 24/7 — el lead que escribe a las 22:40 recibe respuesta','Coordina visitas con resumen del lead derivado a tu equipo'],
      win: '0 leads perdidos fuera de horario' },
    { biz: 'Restaurante / gastronomía', tag: 'Gastronomía',
      before: ['Reservas por teléfono y mensajes sueltos','Pedidos para llevar tomados a mano con errores','Cliente sin dato guardado — nunca volvés a contactarlo'],
      after: ['Web con menú actualizado y reservas online','Bot toma pedidos para llevar y los manda a cocina sin errores','Reservas confirmadas con recordatorio el día anterior','Base de clientes para promos del miércoles, eventos privados, novedades'],
      win: 'Mesa llena de martes a domingo' },
    { biz: 'Clínica veterinaria', tag: 'Salud animal',
      before: ['Agenda en papel y llamadas perdidas','Confirmaciones de turno hechas a mano la noche anterior','Triaje informal por la recepcionista'],
      after: ['Web nueva con agenda online y catálogo de servicios','Bot confirma turnos y manda recordatorios automáticos','Triaje básico — deriva urgencias al veterinario correcto','Datos guardados para campañas de vacunación anual'],
      win: '0 turnos perdidos por confirmación olvidada' },
    { biz: 'Concesionaria de autos', tag: 'Automotor',
      before: ['Leads de portales reportados por mail uno por uno','Cotizaciones armadas a mano por un vendedor','Test drives coordinados por teléfono'],
      after: ['Bot identifica el auto consultado y arma cotización inicial','Califica financiación, prenda, plan canje antes de derivar','Coordina test drive con disponibilidad real del vehículo','Cada lead queda registrado con su intención y seguimiento'],
      win: 'Vendedores hablan con leads calificados, no con curiosos' },
    { biz: 'Distribuidora · cajones de banana', tag: 'Comercio mayorista',
      before: ['Pedidos por WhatsApp tomados a mano por una persona','Cargados uno por uno a un Excel','Otro empleado descarga el archivo para armar pedidos'],
      after: ['Bot toma pedidos en WhatsApp 24/7, sin licencias','Catálogo web actualizado en tiempo real','Integración directa al sistema de armado — sin doble carga','Dos personas armando, no una cargando'],
      win: 'Volumen 2× sin sumar gente al equipo' }];
  const [active, setActive] = useState(0);
  const [paused, setPaused] = useState(false);
  const total = cases.length;
  useEffect(() => {
    if (paused) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const id = setInterval(() => setActive((a) => (a + 1) % total), 7500);
    return () => clearInterval(id);
  }, [paused, total]);
  const next = () => setActive((a) => (a + 1) % total);
  const prev = () => setActive((a) => (a - 1 + total) % total);
  return (
    <section id="casos" className="relative py-24 md:py-28 overflow-hidden">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="kicker mb-3">Casos · dónde ya funciona</div>
          <h2 className="display-lg text-[clamp(36px,4.8vw,68px)] max-w-[1100px] leading-[1.06] mb-4">
            De un sistema viejo, a una <span className="italic">empresa moderna con IA asesora.</span>
          </h2>
          <p className="text-ink/72 text-[16.5px] md:text-lg max-w-[720px] mb-12 leading-relaxed">
            Cinco migraciones reales. Web actualizada, integraciones modernas, y un agente que opera la conversación con el cliente. Cliqueá la carta para enfocarla.
          </p>
        </Reveal>
        {/* DESKTOP (md+): carrusel 3D con perspective + rotateY */}
        <div className="hidden md:flex relative md:h-[640px] items-center justify-center"
          style={{ perspective: '1800px' }}
          onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
          {cases.map((c, i) => {
            let rel = i - active;
            if (rel > total / 2) rel -= total;
            if (rel < -total / 2) rel += total;
            const isActive = rel === 0;
            return <Vertical3DCard key={i} {...c} idx={i} rel={rel} active={isActive} onClick={() => setActive(i)} />;
          })}
          <button onClick={prev} aria-label="Anterior"
            className="absolute left-2 md:left-0 top-1/2 -translate-y-1/2 z-30 size-12 rounded-full card-solid-2 flex items-center justify-center hover:border-cyan/40 transition-colors">
            <span className="text-ink text-lg">←</span>
          </button>
          <button onClick={next} aria-label="Siguiente"
            className="absolute right-2 md:right-0 top-1/2 -translate-y-1/2 z-30 size-12 rounded-full card-solid-2 flex items-center justify-center hover:border-cyan/40 transition-colors">
            <span className="text-ink text-lg">→</span>
          </button>
        </div>
        <div className="hidden md:flex mt-4 items-center justify-center gap-2">
          {cases.map((_, i) =>
            <button key={i} onClick={() => setActive(i)} aria-label={`Caso ${i + 1}`}
              className={`h-1 rounded-full transition-all duration-500 ${i === active ? 'w-12 bg-cyan' : 'w-5 bg-line hover:bg-ink/30'}`} />
          )}
        </div>

        {/* MOBILE (<md): rail horizontal con scroll-snap.
            V3 polish ADDENDUM 26 (2026-05-18) — el carrusel 3D usaba
            perspective+rotateY que es pesado para mobile y poco touch-friendly.
            Reemplazado por rail horizontal con `overflow-x: auto` + scroll-snap.
            Mantiene el mismo data y mismo estilo de card (.card-solid-2 +
            radial glow). Hint visual abajo. Scrollbar oculta. */}
        <div className="md:hidden -mx-6">
          <div className="case-rail flex overflow-x-auto snap-x snap-mandatory gap-4 px-6 pb-3"
            style={{ scrollbarWidth: 'none', WebkitOverflowScrolling: 'touch' }}>
            {cases.map((c, i) => (
              <article key={i}
                className="snap-start flex-shrink-0 card-solid-2 rounded-2xl p-6 relative overflow-hidden"
                style={{
                  width: 'min(82vw, 340px)',
                  boxShadow: '0 24px 50px -14px rgba(0,0,0,0.55), 0 0 0 1px rgba(51,194,234,0.18)'
                }}>
                <div aria-hidden="true" className="absolute -top-16 left-1/2 -translate-x-1/2 w-[260px] h-[180px] pointer-events-none"
                  style={{ background: 'radial-gradient(closest-side, rgba(51,194,234,0.18), transparent 70%)' }} />
                <div className="relative flex items-start justify-between mb-2.5">
                  <span className="font-mono text-[10px] tracking-[0.22em] uppercase text-cyan/85">{c.tag}</span>
                  <span className="font-mono text-[10px] tracking-[0.18em] text-dim">caso · 0{i + 1}</span>
                </div>
                <h3 className="relative font-serif text-[22px] leading-[1.1] mb-4">{c.biz}</h3>
                <div className="rounded-xl border border-violet/22 bg-violet/8 p-3 mb-2.5">
                  <div className="font-mono text-[9.5px] uppercase tracking-[0.22em] text-violet/85 mb-1.5">— Antes</div>
                  <ul className="space-y-1">
                    {c.before.map((it, j) => (
                      <li key={j} className="text-[12px] text-ink/70 leading-[1.5] flex gap-1.5">
                        <span className="text-violet/70 mt-1">·</span><span>{it}</span>
                      </li>
                    ))}
                  </ul>
                </div>
                <div className="rounded-xl border border-cyan/22 bg-cyan/8 p-3 mb-3">
                  <div className="font-mono text-[9.5px] uppercase tracking-[0.22em] text-cyan/85 mb-1.5">— Con newGalaxIA</div>
                  <ul className="space-y-1">
                    {c.after.map((it, j) => (
                      <li key={j} className="text-[12px] text-ink/85 leading-[1.5] flex gap-1.5">
                        <span className="text-cyan/85 mt-1">+</span><span>{it}</span>
                      </li>
                    ))}
                  </ul>
                </div>
                <div className="text-[12.5px] font-serif italic text-cyan/95 leading-[1.35]" style={{ fontFamily: '"Instrument Serif", serif' }}>
                  {c.win}
                </div>
              </article>
            ))}
          </div>
          {/* V3 polish ADDENDUM 30 (2026-05-19) — Swipe hint animado.
              Antes (Addendum 26): texto estático con flechas. Ahora: pill
              glass dark/cyan con un "dedo" (dot luminoso) que se desliza
              R→L para sugerir el gesto. CSS-only, scoped a .swipe-hint
              (definido en hero-v7-full.css). Respeta prefers-reduced-motion.
              Reusable: cualquier rail mobile nuevo puede agregar este markup. */}
          <div className="swipe-hint mt-3 mx-auto" role="status" aria-label="Deslizá para ver más casos">
            <span className="swipe-hint-track" aria-hidden="true">
              <span className="swipe-hint-finger" />
            </span>
            <span className="swipe-hint-label">Deslizá para ver casos</span>
          </div>
        </div>
      </div>
    </section>);
}

function Vertical3DCard({ biz, tag, before, after, win, idx, rel, active, onClick }) {
  const absRel = Math.abs(rel);
  const tx = rel * 320;
  const tz = -absRel * 220;
  const ry = rel * -24;
  const scale = active ? 1 : 0.86 - absRel * 0.04;
  const opacity = absRel > 2 ? 0 : 1 - absRel * 0.28;
  return (
    <div className="absolute top-0 left-1/2 w-[min(560px,92%)] h-full cursor-pointer"
      style={{
        transform: `translateX(-50%) translate3d(${tx}px, 0, ${tz}px) rotateY(${ry}deg) scale(${scale})`,
        opacity, pointerEvents: absRel > 1 ? 'none' : 'auto', zIndex: 20 - absRel,
        transition: 'transform 800ms cubic-bezier(0.65,0,0.35,1), opacity 700ms cubic-bezier(0.65,0,0.35,1)',
        transformStyle: 'preserve-3d'
      }}
      onClick={onClick}>
      <div className="card-solid-2 rounded-2xl h-full p-7 md:p-9 flex flex-col relative overflow-hidden"
        style={{
          boxShadow: active ? '0 40px 90px -20px rgba(51,194,234,0.32), 0 0 0 1px rgba(51,194,234,0.40)' : '0 24px 50px -14px rgba(0,0,0,0.65)',
          transition: 'box-shadow 600ms cubic-bezier(0.65,0,0.35,1)'
        }}>
        <div aria-hidden="true" className="absolute -top-20 left-1/2 -translate-x-1/2 w-[300px] h-[200px] pointer-events-none"
          style={{ background: 'radial-gradient(closest-side, rgba(51,194,234,0.16), transparent 70%)', opacity: active ? 1 : 0.4, transition: 'opacity 500ms' }} />
        <div className="relative flex items-start justify-between mb-3">
          <span className="font-mono text-[10.5px] tracking-[0.22em] uppercase text-cyan/85">{tag}</span>
          <span className="font-mono text-[10.5px] tracking-[0.18em] text-dim">caso · 0{idx + 1}</span>
        </div>
        <h3 className="relative font-serif text-[26px] md:text-[30px] leading-[1.08] mb-6">{biz}</h3>
        <div className="rounded-xl border border-violet/22 bg-violet/8 p-4 mb-3">
          <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-violet/85 mb-2">— Antes</div>
          <ul className="space-y-1.5">
            {before.map((it, j) => <li key={j} className="text-[13px] text-ink/72 leading-[1.5] flex gap-2"><span className="text-violet/70 mt-1.5">·</span><span>{it}</span></li>)}
          </ul>
        </div>
        <div className="rounded-xl border border-cyan/30 bg-cyan/8 p-4 flex-1">
          <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-cyan/95 mb-2">— Con newGalaxIA</div>
          <ul className="space-y-1.5">
            {after.map((it, j) => <li key={j} className="text-[13px] text-ink/92 leading-[1.5] flex gap-2"><span className="text-cyan mt-1.5">+</span><span>{it}</span></li>)}
          </ul>
        </div>
        <div className="mt-5 pt-4 border-t border-line flex items-center gap-2">
          <span className="size-1.5 rounded-full bg-cyan pulse-node" />
          <span className="font-serif italic text-[17px] md:text-[19px] text-ink">{win}</span>
        </div>
      </div>
    </div>);
}

/* ───────── Caso real → diagnóstico por WhatsApp ───────── */
function CasoReal() {
  const [secRef] = useReveal({ threshold: 0.2 });
  const samplePreview = [
    { who: 'bot',  t: 'Hola! Soy un agente de newGalaxIA. Cuando esté en línea te voy a preguntar a qué te dedicás y te propongo 3 a 4 automatizaciones concretas para tu operación.' },
    { who: 'user', t: 'Tengo una inmobiliaria chica. WhatsApp explota con consultas repetidas.' },
    { who: 'bot',  t: 'Ahí vamos. Un agente filtra zona, precio y disponibilidad, agenda visitas y deja en tu CRM solo los leads listos para humano — sin perder los que dicen "después te aviso". Cuando lo tengamos en vivo te lo mostramos con tus datos.' }];
  return (
    <section id="caso" ref={secRef} className="relative py-24 md:py-32 border-t border-line">
      <div className="mx-auto max-w-[1100px] px-6 md:px-8">
        <Reveal>
          <div className="text-center mb-14">
            <div className="kicker mb-4 inline-block">05 — Caso real</div>
            <h2 className="display-lg text-[clamp(46px,6.4vw,104px)] max-w-[1000px] mx-auto mb-6">
              Imaginate el potencial<br />
              de tu negocio <span className="italic">conectado con IA.</span>
            </h2>
            <p className="text-ink/82 text-[17px] md:text-[18px] max-w-[860px] mx-auto leading-[1.6]">
              Acá te dejamos un anticipo del agente conversacional que entrega un diagnóstico personalizado a partir de dos o tres preguntas.
              <br /><br />
              <span className="text-cyan font-mono uppercase tracking-[0.18em] text-[13px] md:text-[14px]">Te respondemos por WhatsApp con diagnóstico directo.</span>{' '}
              <span className="text-mute">Nos contás tu operación y te devolvemos automatizaciones concretas.</span>
            </p>
          </div>
        </Reveal>
        <Reveal delay={120}>
          <div className="card-solid-2 rounded-2xl overflow-hidden led-pulse">
            <div className="px-5 md:px-7 pt-5 pb-4 border-b border-line flex flex-col sm:flex-row sm:items-center gap-3">
              <span className="inline-flex items-center gap-2 text-[10.5px] font-mono uppercase tracking-[0.2em] px-2.5 py-1 rounded-full self-start sm:self-center whitespace-nowrap"
                style={{ color: '#EFC585', border: '1px solid rgba(242,178,92,0.4)', background: 'rgba(242,178,92,0.10)' }}>
                <span className="size-1.5 rounded-full" style={{ background: '#EFC585' }} aria-hidden="true" />
                Diagnóstico asistido por IA
              </span>
              <span className="text-[12.5px] md:text-[13px] text-ink/80 leading-[1.5]">
                Vista previa del tipo de conversación que usamos para detectar flujos, reglas internas y oportunidades de automatización.
              </span>
            </div>
            <div className="px-5 md:px-7 py-6">
              <div className="flex flex-col gap-3.5">
                {samplePreview.map((m, i) => <DemoBubble key={i} who={m.who} t={m.t} />)}
                <div className="mt-2 text-[11px] font-mono uppercase tracking-[0.2em] text-dim text-center">
                  Vista previa del diagnóstico
                </div>
              </div>
            </div>
            <div className="px-5 md:px-7 py-4 border-t border-line flex flex-col sm:flex-row sm:items-center gap-3 bg-bg/40">
              <input type="text"
                placeholder="Escribinos por WhatsApp para iniciar el diagnóstico"
                disabled aria-disabled="true" aria-label="Diagnóstico por WhatsApp"
                className="flex-1 bg-transparent text-[14.5px] text-dim placeholder:text-dim outline-none opacity-70 cursor-not-allowed" />
              <a href="https://wa.me/59892499463" target="_blank" rel="noopener noreferrer"
                className="btn-cta rounded-full bg-ink text-bg text-sm font-medium px-5 py-2.5 inline-flex items-center justify-center gap-2 self-stretch sm:self-auto whitespace-nowrap">
                <svg width="14" height="14" viewBox="0 0 32 32" fill="currentColor" aria-hidden="true">
                  <path d="M16 3.2C8.92 3.2 3.2 8.92 3.2 16c0 2.26.6 4.38 1.64 6.22L3.2 28.8l6.74-1.6A12.8 12.8 0 0 0 16 28.8c7.08 0 12.8-5.72 12.8-12.8S23.08 3.2 16 3.2Z" />
                </svg>
                Diagnóstico por WhatsApp
                <span aria-hidden="true" className="btn-arrow">→</span>
              </a>
            </div>
          </div>
        </Reveal>
        <Reveal delay={200}>
          <div className="mt-10 text-center text-[15px]">
            <span className="text-mute">¿Preferís dejarnos los datos? </span>
            <a href="#contacto" className="text-cyan underline-offset-4 hover:underline">Reservá un diagnóstico gratuito →</a>
          </div>
        </Reveal>
      </div>
    </section>);
}

function DemoBubble({ who, t }) {
  const isUser = who === 'user';
  return (
    <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>
      <div className={`max-w-[82%] rounded-2xl px-4 py-3 text-[15px] leading-[1.55] whitespace-pre-line ${isUser ? 'bg-cyan/15 border border-cyan/30 text-ink rounded-br-md' : 'bg-glass border border-line text-ink/95 rounded-bl-md'}`}>{t}</div>
    </div>);
}

/* ───────── TechCard (used in PorQue) ───────── */
function TechCard({ tag, name, d, idx }) {
  const [hover, setHover] = useState(false);
  const [ref, seen] = useReveal({ threshold: 0.18, once: true });
  return (
    <div ref={ref}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      className={`reveal-up ${seen ? 'in' : ''}`}
      style={{ transitionDelay: `${idx % 3 * 80 + Math.floor(idx / 3) * 60}ms` }}>
      <div className="card-solid p-6 md:p-7 aspect-square flex flex-col justify-between relative overflow-hidden transition-colors duration-500">
        <div className="absolute top-0 left-0 right-0 h-[2px] bg-cyan origin-left" style={{ transform: hover ? 'scaleX(1)' : 'scaleX(0)', transition: 'transform 220ms cubic-bezier(0.65,0,0.35,1)', transitionDelay: hover ? '0ms' : '660ms' }} />
        <div className="absolute top-0 right-0 bottom-0 w-[2px] bg-cyan origin-top" style={{ transform: hover ? 'scaleY(1)' : 'scaleY(0)', transition: 'transform 220ms cubic-bezier(0.65,0,0.35,1)', transitionDelay: hover ? '220ms' : '440ms' }} />
        <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-cyan origin-right" style={{ transform: hover ? 'scaleX(1)' : 'scaleX(0)', transition: 'transform 220ms cubic-bezier(0.65,0,0.35,1)', transitionDelay: hover ? '440ms' : '220ms' }} />
        <div className="absolute top-0 left-0 bottom-0 w-[2px] bg-cyan origin-bottom" style={{ transform: hover ? 'scaleY(1)' : 'scaleY(0)', transition: 'transform 220ms cubic-bezier(0.65,0,0.35,1)', transitionDelay: hover ? '660ms' : '0ms' }} />
        <div className="flex items-center justify-between mb-4">
          <span className="font-mono text-[10.5px] uppercase tracking-[0.22em] text-cyan/85">{tag}</span>
          <span className="font-mono text-[10.5px] text-dim tracking-[0.18em]">0{idx + 1}</span>
        </div>
        <h3 className="font-serif text-[22px] md:text-[24px] leading-[1.15] mb-3 text-ink/95">{name}</h3>
        <p className="text-[14.5px] text-ink/78 leading-[1.55]">{d}</p>
      </div>
    </div>);
}

/* ───────── PorQue ───────── */
function PorQue() {
  return (
    <section id="por-que" className="relative py-24 md:py-32 border-t border-line overflow-hidden">
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="kicker mb-6">06 — Por qué nosotros</div>
          <h2 className="display-lg text-[clamp(40px,5.4vw,82px)] max-w-[1100px] leading-[1.04]">
            Utilizamos <span className="italic">todas las herramientas de IA</span> de última generación — para darle a tu empresa el salto que necesita <span className="italic">a la nueva era.</span>
          </h2>
        </Reveal>
        <Reveal delay={140}>
          <p className="mt-8 text-ink/72 text-[16.5px] md:text-[18px] max-w-[760px] leading-relaxed">
            Estas son las tecnologías que ponemos a trabajar para tu negocio. Lo importante no es la sigla, es lo que <span className="italic">significa</span> en tu operación.
          </p>
        </Reveal>
        <div className="mt-16 grid md:grid-cols-2 lg:grid-cols-3 gap-4">
          {[
            { tag: 'LLM frontier', name: 'Cerebros que entienden contexto', d: 'Modelos top — Claude, GPT — que captan intención, memoria de turnos y tono. La diferencia entre "una" respuesta y "la" respuesta correcta.' },
            { tag: 'Visión + audio', name: 'Lee fotos, escucha audios', d: 'Tu bot procesa imágenes de DNI, comprobantes o productos, y entiende mensajes de voz. Tu cliente habla cómodo, vos no perdés un dato.' },
            { tag: 'RAG', name: 'Le enseñamos todo tu negocio', d: 'Le metemos al bot tus manuales, catálogos, FAQs y precios. Responde con TU conocimiento real — no inventa nada genérico.' },
            { tag: 'API + integraciones', name: 'Vive donde ya trabajás', d: 'Lo conectamos a WhatsApp, tu CRM, Sheets, Mercado Pago, calendarios. No es una herramienta separada, es parte de tu sistema.' },
            { tag: 'Tests automatizados', name: 'Calidad medida, no prometida', d: 'Cada flujo crítico tiene un test que lo valida en cada cambio. Si algo se rompe lo sabemos antes de que vos lo notes.' },
            { tag: 'Despliegue versionado', name: 'Vuelta atrás en 30 segundos', d: 'Cada versión queda registrada y desplegable. Si algo no rinde, volvemos a la versión anterior sin drama, sin perder datos.' }
          ].map((it, i) => <TechCard key={i} {...it} idx={i} />)}
        </div>
      </div>
    </section>);
}

/* ───────── Precios ───────── */
function Precios() {
  return (
    <section id="precios" className="relative py-24 md:py-32">
      <div className="mx-auto max-w-[1100px] px-6 md:px-8 text-center">
        <Reveal>
          <div className="kicker mb-5">07 — Inversión</div>
          <h2 className="display-lg text-[clamp(46px,6.5vw,108px)] leading-[1.02]">
            Algunos cambios <span className="italic">no pueden esperar.</span>
          </h2>
          <p className="mt-8 text-lg md:text-xl text-mute max-w-[680px] mx-auto leading-relaxed">
            Reservá un diagnóstico gratuito de 30 minutos y te mostramos qué se puede automatizar en tu operación, cuánto tarda y qué cuesta. Sin compromiso.
          </p>
          <div className="mt-12 flex flex-wrap items-center justify-center gap-4">
            <a href="#contacto" className="btn-cta rounded-full bg-ink text-bg px-7 py-4 text-base font-medium inline-flex items-center gap-3">
              Reservar diagnóstico — 30 min
              <span className="btn-arrow">→</span>
            </a>
          </div>
          <div className="mt-8 text-xs font-mono text-dim uppercase tracking-[0.22em]">sin costo · sin obligación · respondemos en 24h</div>
        </Reveal>
      </div>
    </section>);
}

/* SECTION: FAQ · objeciones típicas
   Seis preguntas que cubren tiempo, número actual, CRM, fallback,
   precio referencial y transparencia bot/humano. */
function Faq() {
  const qs = [
    { q: '¿Cuánto tarda una implementación?', a: 'Un agente conversacional simple (atención, calificación, agenda) tarda entre 3 y 6 semanas desde el kick-off. Casos con integración a CRM o catálogos externos pueden estirarse a 8–10 semanas.' },
    { q: '¿Necesito cambiar de WhatsApp?', a: 'No. Usamos WhatsApp Business API conectada a tu número actual. El bot convive con tu equipo humano: detecta cuando una persona escribe desde el mismo número y se calla.' },
    { q: '¿Se puede conectar con mi CRM?', a: 'Sí. Trabajamos con HubSpot, Pipedrive, Zoho, Salesforce y CRMs custom vía API. Si no tenés CRM, podemos arrancar con Notion o Sheets y migrar después.' },
    { q: '¿Qué pasa si el bot no sabe responder?', a: 'Tiene reglas duras de derivación. Cuando detecta una pregunta fuera de su scope, urgencia personal o frustración del lead, manda un email con resumen completo a quien vos definas, y deja de responder hasta que el humano cierre el caso.' },
    { q: '¿Cómo sabemos si tiene sentido para mi negocio?', a: 'Lo vemos en el diagnóstico. Buscamos procesos donde la IA pueda sumar valor real: tiempo que se libera, consultas que se responden mejor, seguimientos que no se pierden y datos que empiezan a trabajar para vos. La idea no es cobrar por tecnología porque sí; es construir algo que haga que ganemos todos.' },
    { q: '¿Mi cliente se va a dar cuenta que es un bot?', a: 'Si pregunta directamente, sí — el bot lo admite. Esa es una política nuestra (transparencia construye confianza). En la conversación normal, habla con tu tono y no usa frases robóticas.' }];
  const [open, setOpen] = useState(0);
  return (
    <section id="faq" className="relative py-24 md:py-28">
      <SectionDivider />
      <div className="mx-auto max-w-[1080px] px-6 md:px-8">
        <Reveal>
          <div className="kicker mb-3">Preguntas</div>
          <h2 className="display-lg text-[clamp(40px,5.2vw,72px)] mb-14 max-w-[800px]">
            Lo que <span className="italic">siempre</span> se pregunta.
          </h2>
        </Reveal>
        <div className="divide-y divide-line border-y border-line">
          {qs.map((it, i) => <FaqItem key={i} {...it} open={open === i} onToggle={() => setOpen(open === i ? -1 : i)} />)}
        </div>
      </div>
    </section>);
}

function FaqItem({ q, a, open, onToggle }) {
  return (
    <div className="py-6 md:py-7">
      <button onClick={onToggle} className="w-full flex items-start justify-between gap-6 text-left">
        <h3 className="font-serif text-2xl md:text-[28px] leading-[1.1] flex-1">{q}</h3>
        <span className="font-mono text-cyan text-xl translate-y-1 transition-transform duration-500"
          style={{ transform: open ? 'rotate(45deg)' : 'rotate(0)' }}>+</span>
      </button>
      <div className="grid transition-[grid-template-rows] duration-500"
        style={{ gridTemplateRows: open ? '1fr' : '0fr', transitionTimingFunction: 'cubic-bezier(0.65,0,0.35,1)' }}>
        <div className="overflow-hidden">
          <p className="text-[15.5px] md:text-[16px] text-ink/85 leading-[1.6] pt-4 max-w-[800px]">{a}</p>
        </div>
      </div>
    </div>);
}

/* SECTION: Reservar diagnóstico · Contacto
   En V1, el bloque Precios (sólo CTA + copy) se eliminó del render y su
   intro fue absorbida acá como sub-headline + microcopy de cierre
   ("Sin costo · sin obligación · respondemos en 24h"). El form sigue
   igual, los links directos (WhatsApp / Instagram / mail) también. */
function Contacto() {
  /* V3 polish ADDENDUM 15 (2026-05-18) — formulario mailto retirado.
     Antes: <form> con 4 campos + handleSubmit que abría Mail nativo via
     `mailto:?subject=...&body=...`. Problema: en mobile sin cliente de mail
     configurado el lead se perdía sin trazabilidad; en desktop abría Outlook
     o el cliente default que muchos no usan. Decisión de Martín (brief
     remove-contact-form-addendum-2026-05-18.md): retirar el form completo y
     dejar canales directos premium — WhatsApp, Instagram, Email. La sección
     mantiene id="contacto" para el menú, mantiene el SectionDivider unificado
     de Addendum 9, y reemplaza el form por un CTA grande hacia WhatsApp +
     las 3 cards de contacto directo que ya vivían debajo del form. Se removió
     bg-bg para que el canvas de puntitos del fondo se vea continuo hasta el
     footer (preparación de Addendum 16 — background continuity). */
  return (
    <section id="contacto" className="relative py-24 md:py-32">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="text-center mb-14 md:mb-16">
            <div className="kicker mb-4 inline-block">Reservar diagnóstico</div>
            <h2 className="display-lg text-[clamp(40px,5.2vw,80px)] leading-[1.05] max-w-[1100px] mx-auto">
              Algunos cambios <span className="italic">no pueden esperar</span>.
            </h2>
            <p className="mt-6 text-ink/72 text-[16px] md:text-[17px] max-w-[680px] mx-auto leading-relaxed">
              Hablemos 30 minutos por WhatsApp o correo. Te mostramos qué se puede automatizar en tu operación, cuánto tarda y qué cuesta — sin compromiso. Una de cada tres consultas no termina en proyecto, y está bien: el diagnóstico es para ver si tiene sentido.
            </p>
          </div>
        </Reveal>
        <div className="max-w-[760px] mx-auto">
          <Reveal>
            <a href="https://wa.me/59892499463" target="_blank" rel="noopener noreferrer"
              className="btn-cta w-full rounded-full bg-ink text-bg py-4 text-sm font-medium inline-flex items-center justify-center gap-3"
              style={{ textDecoration: 'none' }}>
              Hablemos por WhatsApp <span className="btn-arrow">→</span>
            </a>
          </Reveal>
          <Reveal delay={90}>
            <div className="mt-6 text-center text-[11px] font-mono text-dim uppercase tracking-[0.22em]">
              Sin costo · sin obligación · respondemos en 24h
            </div>
          </Reveal>
          <Reveal delay={140}>
            <div className="mt-8 grid grid-cols-3 gap-3 md:gap-4">
              <a href="https://wa.me/59892499463" aria-label="WhatsApp" target="_blank" rel="noopener noreferrer"
                className="card-solid rounded-xl flex flex-col items-center justify-center text-center gap-2 py-5 hover:border-[#25D36655] transition-colors group">
                <span className="size-12 rounded-full bg-[#25D36622] flex items-center justify-center">
                  <svg width="28" height="28" viewBox="0 0 32 32" fill="none" aria-hidden="true">
                    <path d="M16 3.2C8.92 3.2 3.2 8.92 3.2 16c0 2.26.6 4.38 1.64 6.22L3.2 28.8l6.74-1.6A12.8 12.8 0 0 0 16 28.8c7.08 0 12.8-5.72 12.8-12.8S23.08 3.2 16 3.2Z" fill="#25D366" />
                    <path d="M22.32 19.36c-.26-.13-1.52-.75-1.76-.84-.24-.08-.41-.13-.59.13-.17.26-.67.84-.82 1.01-.15.17-.3.19-.55.06-.26-.13-1.09-.4-2.07-1.28-.77-.69-1.28-1.54-1.43-1.8-.15-.26-.02-.4.11-.52.12-.11.26-.3.39-.45.13-.15.17-.26.26-.43.09-.17.04-.32-.02-.45-.07-.13-.59-1.4-.81-1.92-.21-.5-.42-.43-.59-.44h-.5c-.17 0-.45.06-.69.32-.24.26-.91.89-.91 2.17 0 1.28.93 2.51 1.06 2.68.13.17 1.83 2.79 4.43 3.91.62.27 1.1.43 1.48.55.62.2 1.19.17 1.63.1.5-.07 1.52-.62 1.74-1.22.22-.6.22-1.11.15-1.22-.06-.11-.24-.17-.5-.3Z" fill="#fff" />
                  </svg>
                </span>
                <span className="text-[14px] text-ink font-medium">WhatsApp</span>
              </a>
              <a href="https://www.instagram.com/new_galaxia/" target="_blank" rel="noopener noreferrer" aria-label="Instagram"
                className="card-solid rounded-xl flex flex-col items-center justify-center text-center gap-2 py-5 hover:border-violet/45 transition-colors group relative">
                <span className="size-12 rounded-full bg-violet/12 flex items-center justify-center">
                  <svg width="28" height="28" viewBox="0 0 32 32" fill="none" aria-hidden="true">
                    <defs>
                      <linearGradient id="ig-grad" x1="0%" y1="100%" x2="100%" y2="0%">
                        <stop offset="0%" stopColor="#FEDA75" />
                        <stop offset="25%" stopColor="#FA7E1E" />
                        <stop offset="50%" stopColor="#D62976" />
                        <stop offset="75%" stopColor="#962FBF" />
                        <stop offset="100%" stopColor="#4F5BD5" />
                      </linearGradient>
                    </defs>
                    <rect x="4" y="4" width="24" height="24" rx="6.5" stroke="url(#ig-grad)" strokeWidth="2.2" />
                    <circle cx="16" cy="16" r="5.5" stroke="url(#ig-grad)" strokeWidth="2.2" />
                    <circle cx="23.3" cy="8.7" r="1.5" fill="url(#ig-grad)" />
                  </svg>
                </span>
                <span className="text-[14px] text-ink font-medium">Instagram</span>
              </a>
              <a href="mailto:mmoralesoloriz@gmail.com" aria-label="Correo"
                className="card-solid rounded-xl flex flex-col items-center justify-center text-center gap-2 py-5 hover:border-cyan/45 transition-colors group">
                <span className="size-12 rounded-full bg-cyan/12 flex items-center justify-center">
                  <svg width="28" height="28" viewBox="0 0 32 32" fill="none" aria-hidden="true">
                    <rect x="3" y="6" width="26" height="20" rx="2.5" stroke="#33C2EA" strokeWidth="2" />
                    <path d="M3.8 7 16 17 28.2 7" stroke="#33C2EA" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </span>
                <span className="text-[14px] text-ink font-medium">Correo</span>
              </a>
            </div>
          </Reveal>
          {/* V3 polish ADDENDUM 17 (2026-05-18) — video del mascot reubicado.
              Antes vivía en la columna izquierda del Footer reemplazando al
              logo grande. Martín pidió moverlo bajo el icono/card de Instagram
              porque conceptualmente es la "pieza animada de marca" — y la
              social/Instagram es el canal natural para una pieza de marca
              animada. Lo posicionamos centrado bajo la fila de 3 cards,
              alineado con el card de Instagram (columna del medio del grid 3
              cols). En mobile se queda centrado al ancho de la sección.
              Sin border-box ni fondo extra: el dual-mask del componente
              `GalaxiaMascotVideo` ya difumina los bordes contra el canvas. */}
          <Reveal delay={200}>
            <div className="mt-10 md:mt-12 flex flex-col items-center">
              <div className="text-[10.5px] font-mono text-cyan/55 uppercase tracking-[0.28em] mb-2">
                @new_galaxia
              </div>
              <GalaxiaMascotVideo width={240} height={136} ariaLabel="newGalaxIA — mascot animado para Instagram" />
            </div>
          </Reveal>
        </div>
      </div>
    </section>);
}

/* V3 polish ADDENDUM 15 (2026-05-18) — Field component removido junto con el
   formulario. Era usado solamente dentro de Contacto. Si en algún momento se
   reactiva un form (con backend real), se puede recuperar desde el historial
   de git. */

/* ───────── Footer ───────── */
/* V3 polish ADDENDUM 17 (2026-05-18) — video helper compartido.
   Helper reutilizable que renderiza el video del mascot con dual-mask
   (radial gradient agresivo) + overlay radial bg-color para que los bordes
   se difuminen contra el fondo. Antes vivía hardcoded dentro de Footer.
   Ahora se exporta para usar en Contacto bajo Instagram (donde Martín pidió
   moverlo) y se mantiene disponible si en algún futuro se quisiera volver
   a usar en otro contexto. */
function GalaxiaMascotVideo({ width = 240, height = 136, ariaLabel = 'newGalaxIA — marca animada' }) {
  const mask =
    'radial-gradient(ellipse 58% 62% at 50% 50%,' +
      ' #000 0%, #000 10%,' +
      ' rgba(0,0,0,0.86) 22%, rgba(0,0,0,0.66) 36%,' +
      ' rgba(0,0,0,0.42) 52%, rgba(0,0,0,0.22) 68%,' +
      ' rgba(0,0,0,0.08) 82%, rgba(0,0,0,0.02) 92%,' +
      ' transparent 100%)';
  return (
    <div className="relative pointer-events-none select-none mx-auto"
      style={{ width, height }} aria-label={ariaLabel}>
      <div className="absolute inset-0 overflow-hidden"
        style={{ WebkitMaskImage: mask, maskImage: mask }}>
        <video
          src="assets/galaxia-video.mp4"
          autoPlay muted loop playsInline preload="metadata"
          style={{
            position: 'absolute', top: '50%', left: '50%',
            width: '122%', height: '122%',
            transform: 'translate(calc(-50% - 6%), calc(-50% - 5.5%))',
            objectFit: 'cover',
            filter: 'brightness(0.92) contrast(1.22) saturate(1.08)',
            mixBlendMode: 'screen'
          }} />
      </div>
      <div className="absolute inset-0 pointer-events-none"
        style={{
          background:
            'radial-gradient(ellipse 62% 66% at 50% 50%,' +
              ' rgba(10,10,15,0) 0%, rgba(10,10,15,0) 18%,' +
              ' rgba(10,10,15,0.30) 34%, rgba(10,10,15,0.62) 50%,' +
              ' rgba(10,10,15,0.88) 68%, rgba(10,10,15,1) 86%,' +
              ' rgba(10,10,15,1) 100%)'
        }} />
    </div>
  );
}

function Footer() {
  /* V3 polish ADDENDUM 19 (2026-05-18) — footer reordenado a 3 columnas.
     Antes (Addendum 17): logo + tagline / 4 nav links (Cómo trabajamos, Caso
     real, Quiénes somos, FAQ) / 3 contact links sueltos.
     Ahora (feedback de Martín, brief footer-contact-column-marketing-copy):
     - Columna izquierda: marca (logo + tagline + descripción).
     - Columna media: frase comercial premium para dueños de empresa
       (Codex sugirió 5 opciones, Martín ratificó la opción 1).
     - Columna derecha: TODOS los canales de contacto unificados en una sola
       columna — Contacto (anchor) + WhatsApp + Instagram + Email. Antes la
       columna de nav links era ruido — duplicaba el nav principal que ya
       reorganizamos con dropdowns narrativos (Addendum 14/17). Se elimina
       para limpiar el footer. Background continuo (sin `bg-bg`) preservado
       de Addendum 17. Mascot video sigue en #contacto (Addendum 17), no se
       mueve. */
  return (
    <footer className="relative border-t border-line pt-14 pb-10">
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <div className="grid md:grid-cols-12 gap-8 md:gap-10 items-start">
          {/* COLUMNA 1 · Marca */}
          <div className="md:col-span-4">
            <a href="#top" className="inline-flex items-center mb-5 select-none">
              <img src="./galaxia-logo-clean.png" alt="newGalaxIA" className="h-8 md:h-9 w-auto" />
            </a>
            <p className="font-serif italic text-[20px] md:text-[24px] text-ink/90 mb-3" style={{ fontFamily: '"Instrument Serif", serif' }}>
              Soluciones IA para tu empresa.
            </p>
            <p className="text-mute text-sm max-w-[420px] leading-relaxed">
              Diseñamos e implementamos soluciones de software para negocios reales.
            </p>
          </div>

          {/* COLUMNA 2 · Frase comercial premium (option 1 de Codex). */}
          <div className="md:col-span-5">
            <div className="kicker mb-4" style={{ color: 'rgba(51,194,234,0.85)' }}>Para dueños de empresa</div>
            <p className="font-serif text-[22px] md:text-[28px] leading-[1.18] text-ink/95 max-w-[520px]"
              style={{ fontFamily: '"Instrument Serif", serif' }}>
              Tu negocio ya tiene <span className="italic">procesos</span>. Nosotros los convertimos en{' '}
              <span className="italic text-cyan">inteligencia operativa</span>.
            </p>
            <a href="#contacto"
              className="mt-5 inline-flex items-center gap-2 text-[12.5px] font-mono uppercase tracking-[0.18em] text-cyan/85 hover:text-cyan transition-colors">
              Reservar diagnóstico
              <span aria-hidden="true">→</span>
            </a>
          </div>

          {/* COLUMNA 3 · Canales unificados — Contacto + WhatsApp + Instagram + Email. */}
          <div className="md:col-span-3">
            <div className="kicker mb-4">Canales</div>
            <ul className="space-y-2.5 text-[14px]">
              <li>
                <a className="inline-flex items-center gap-2 text-ink/85 hover:text-cyan transition-colors" href="#contacto">
                  <NavIcon name="calendar" size={14} />
                  <span>Contacto</span>
                </a>
              </li>
              <li>
                <a className="inline-flex items-center gap-2 text-ink/85 hover:text-cyan transition-colors"
                  href="https://wa.me/59892499463" target="_blank" rel="noopener noreferrer">
                  <NavIcon name="phone" size={14} />
                  <span>WhatsApp</span>
                </a>
              </li>
              <li>
                <a className="inline-flex items-center gap-2 text-ink/85 hover:text-cyan transition-colors"
                  href="https://www.instagram.com/new_galaxia/" target="_blank" rel="noopener noreferrer">
                  <NavIcon name="instagram" size={14} />
                  <span>Instagram</span>
                </a>
              </li>
              <li>
                <a className="inline-flex items-center gap-2 text-ink/85 hover:text-cyan transition-colors"
                  href="mailto:mmoralesoloriz@gmail.com">
                  <NavIcon name="mail" size={14} />
                  <span>Correo</span>
                </a>
              </li>
            </ul>
          </div>
        </div>
        <div className="mt-14 pt-6 border-t border-line flex flex-wrap items-center justify-between gap-3 text-[11px] font-mono uppercase tracking-[0.22em] text-dim">
          <span>© 2026 newGalaxIA · todos los derechos respetados</span>
          <span>Built clean. Tested. Boring on purpose.</span>
        </div>
      </div>
    </footer>);
}

/* SECTION: Lo que resuelve la demo
   Bloque de prueba inmediata post-demo V7. V1 compactada: sólo el bloque
   "Lo que resolvió" (7 entradas). Se eliminó el sub-bloque "Por qué importa"
   (A-F) que repetía la idea en otro registro. Mantenemos kicker + headline
   + intro para preservar el anchor narrativo entre demo y bridge. */
function AgentResolvedSummarySection() {
  const resueltos = [
    { tag:'01', t:'Visitas listas para coordinar',                d:'Cada audio o mensaje queda en una visita lista para que tu equipo solo confirme día y hora.' },
    { tag:'02', t:'Seguimientos agendados',                       d:'Las promesas "después te aviso" no caen al vacío: queda un cron con condición de cancelación.' },
    { tag:'03', t:'Documentos leídos y datos extraídos',          d:'DNI, constancias, comprobantes y PDFs llegan al equipo con los datos clave ya estructurados.' },
    { tag:'04', t:'Socios y clientes reconocidos por contexto',   d:'El agente identifica por número, recupera historial y evita preguntar lo que tu CRM ya sabe.' },
    { tag:'05', t:'Reclamos contenidos y reavisados',             d:'Aplica políticas internas con respeto, dispara re-aviso al staff y deja constancia con prioridad.' },
    { tag:'06', t:'Idiomas atendidos sin perder contexto',        d:'Cambia a inglés o portugués midchat y retoma al día siguiente en el mismo idioma.' },
    { tag:'07', t:'Pedido de humano escalado sin fricción',       d:'Cuando un cliente pide hablar con alguien, escala al staff y el bot queda en silencio.' }];

  return (
    <section id="lo-que-resuelve" className="relative py-20 md:py-28">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="max-w-[960px] mb-14 md:mb-16">
            <div className="kicker mb-3">Lo que acabás de ver, en concreto</div>
            <h2 className="display-lg text-[clamp(38px,4.6vw,68px)] leading-[1.04] mb-5">
              Esto no es una conversación bonita. Es <span className="italic text-cyan">trabajo operativo terminado</span>.
            </h2>
            <p className="text-[16px] md:text-[17.5px] text-mute leading-[1.6] max-w-[760px]">
              Cada caso del demo deja una salida real: un aviso al equipo, un seguimiento agendado, una visita lista para coordinar o una oportunidad detectada. Tu equipo recibe el trabajo listo, no la conversación cruda.
            </p>
          </div>
        </Reveal>
        <Reveal>
          <div className="kicker mb-6" style={{ color: 'rgba(51,194,234,0.85)' }}>Lo que resolvió</div>
          <ul className="grid gap-x-10 gap-y-5 md:grid-cols-2 lg:gap-x-14">
            {resueltos.map((r) => (
              <li key={r.tag} className="flex items-start gap-3">
                <span className="font-mono text-[10px] uppercase tracking-[0.18em] text-cyan/75 mt-1 min-w-[22px]">{r.tag}</span>
                <div>
                  <div className="font-serif text-[18px] md:text-[20px] leading-[1.25] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>{r.t}</div>
                  <div className="text-[14px] text-mute leading-[1.55] mt-0.5">{r.d}</div>
                </div>
              </li>))}
          </ul>
        </Reveal>
      </div>
    </section>);
}

/* SECTION: Inteligencia operativa · bridge "no es solo WhatsApp"
   V1 compactada: sólo se renderiza el sub-bloque "01 · Áreas donde puede
   trabajar" (6 áreas). Se eliminaron los sub-bloques "02 · Integraciones"
   (detalle Hoy/Próximo/A medida — demasiado IT para la landing) y
   "03 · Promesa honesta" (defensivo; sus signals se trasladaron a
   QuienesSomos como 3 bullets afirmativos).
   OIB_INTEGRACIONES, OIB_VERDADES y OIBIntegrationColumn quedan en el archivo
   como dead code reversible. */
const OIB_AREAS = [
  { tag: 'VENTAS', n: '01', t: 'Califica y prioriza · sin dejar leads dormidos.',
    bullets: ['Detecta intención y urgencia en cada conversación', 'Cotiza con tu catálogo y reglas de pricing', 'Agenda visitas / demos en tu calendario'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M3 17l5-5 4 4 8-8"/><path d="M14 8h7v7"/></svg>) },
  { tag: 'ATENCIÓN', n: '02', t: 'Responde, contiene y deriva con criterio.',
    bullets: ['Aplica tus políticas internas en cada respuesta', 'Detecta frustración y escala al humano correcto', 'Cierra el ciclo con seguimiento si quedó pendiente'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M4 6.5C4 5.7 4.7 5 5.5 5h13c.8 0 1.5.7 1.5 1.5v8c0 .8-.7 1.5-1.5 1.5H10l-4 3v-3H5.5C4.7 16 4 15.3 4 14.5v-8Z"/></svg>) },
  { tag: 'ADMINISTRACIÓN', n: '03', t: 'Lee, ordena y avisa antes de que duela.',
    bullets: ['Procesa documentos: DNI, comprobantes, contratos', 'Estructura datos en tu sistema sin doble carga', 'Avisa vencimientos y pendientes antes del límite'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6M8 13h8M8 17h5"/></svg>) },
  { tag: 'DIRECCIÓN', n: '04', t: 'Resume, detecta patrones y entrega reportes.',
    bullets: ['Resumen semanal de operación con métricas clave', 'Detecta tendencias en conversaciones del equipo', 'Reportes a medida sin que nadie arme planillas'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M3 21h18M6 17V9M11 17V5M16 17v-7M21 17V12"/></svg>) },
  { tag: 'OPERACIONES', n: '05', t: 'Sigue procesos · alerta pendientes · coordina tareas.',
    bullets: ['Sigue el ciclo completo de cada pedido / caso', 'Alerta a la persona indicada cuando algo se atasca', 'Coordina tareas entre WhatsApp, calendario y equipo'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .3 1.8a2 2 0 0 1-2.83 2.83a1.65 1.65 0 0 0-1.8-.3a1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51a1.65 1.65 0 0 0-1.8.3a2 2 0 0 1-2.83-2.83a1.65 1.65 0 0 0 .3-1.8a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09a1.65 1.65 0 0 0 1.51-1a1.65 1.65 0 0 0-.3-1.8a2 2 0 0 1 2.83-2.83a1.65 1.65 0 0 0 1.8.3a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51a1.65 1.65 0 0 0 1.8-.3a2 2 0 0 1 2.83 2.83a1.65 1.65 0 0 0-.3 1.8a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>) },
  { tag: 'MARKETING', n: '06', t: 'Escucha lo que tu cliente realmente pregunta.',
    bullets: ['Detecta objeciones frecuentes en conversaciones reales', 'Mapea demanda no cubierta para campañas outbound', 'Segmenta tu base por intención y comportamiento'],
    icon: (<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="size-5"><path d="M3 11l18-7v16L3 13v-2Z"/><path d="M11 19v-4"/></svg>) }];

const OIB_INTEGRACIONES = [
  { tone: 'cyan',   kicker: 'Hoy',      title: 'Lo que ya conectamos en producción.',
    desc: 'Stack que usamos hoy en proyectos vivos. Si tu negocio ya corre acá, vamos directo.',
    items: ['WhatsApp Business', 'Base de datos del negocio', 'Catálogo dinámico', 'Email interno al equipo', 'Notion / Supabase', 'CRM cuando aplica'] },
  { tone: 'violet', kicker: 'Próximo',  title: 'Lo que estamos integrando ahora.',
    desc: 'Integraciones en cola corta. Acelerable si tu proyecto las necesita desde día uno.',
    items: ['CRM full (HubSpot · Pipedrive)', 'Calendario (Google · Outlook)', 'Pagos (Mercado Pago · Stripe)', 'Emails masivos', 'Dashboards operativos', 'Documentos (PDF · imágenes)'] },
  { tone: 'amber',  kicker: 'A medida', title: 'Lo que armamos para tu sistema.',
    desc: 'Cuando el negocio corre sobre algo propio o legacy, lo integramos a medida.',
    items: ['APIs propias', 'ERPs internos', 'Sistemas de stock', 'Sistemas de turnos', 'Bases legacy con exportable', 'Lo que tu equipo realmente usa'] }];

const OIB_VERDADES = [
  'Cobertura para casos típicos bien definidos · no respuestas mágicas para todo.',
  'Reglas y frases aprobadas por tu equipo · el agente habla con tu tono.',
  'Derivación inteligente al humano cuando el caso lo amerita.',
  'Monitoreo y QA continuo · revisamos conversaciones reales y proponemos ajustes.',
  'Mejora continua · cada caso nuevo entrena al agente para el siguiente.',
  'Sin porcentajes universales sin medir · sin promesas que no podamos sostener.'];

function OIBAreaCard({ a }) {
  return (
    <article className="card-solid rounded-2xl p-6 md:p-7 group transition-all duration-300 hover:border-cyan/35 hover:-translate-y-0.5 flex flex-col h-full"
      style={{ boxShadow: '0 0 0 1px rgba(244,241,234,0.04), 0 18px 40px -28px rgba(0,0,0,0.55)' }}>
      <div className="flex items-start justify-between mb-5">
        <div className="size-10 rounded-xl bg-cyan/10 border border-cyan/30 text-cyan flex items-center justify-center">{a.icon}</div>
        <span className="text-[10px] font-mono uppercase tracking-[0.2em] text-dim">{a.n}</span>
      </div>
      <div className="kicker mb-2" style={{ color: 'rgba(51,194,234,0.85)' }}>{a.tag}</div>
      <h4 className="font-serif text-[20px] md:text-[22px] leading-[1.15] text-ink/95 mb-4" style={{ fontFamily: '"Instrument Serif", serif' }}>{a.t}</h4>
      <ul className="space-y-1.5 mt-auto">
        {a.bullets.map((b, i) => (
          <li key={i} className="flex items-start gap-2 text-[13px] text-ink/82 leading-[1.5]">
            <span className="text-cyan flex-shrink-0 mt-[1px]" aria-hidden="true">→</span><span>{b}</span>
          </li>))}
      </ul>
    </article>);
}

function OIBIntegrationColumn({ data }) {
  const toneStyles = {
    cyan:   { border: 'rgba(51,194,234,0.28)',  kicker: 'rgba(51,194,234,0.85)',  dot: '#33C2EA' },
    violet: { border: 'rgba(158,123,255,0.32)', kicker: 'rgba(192,170,255,0.95)', dot: '#9E7BFF' },
    amber:  { border: 'rgba(242,178,92,0.32)',  kicker: '#EFC585',                dot: '#F2B25C' }};
  const s = toneStyles[data.tone] || toneStyles.cyan;
  return (
    <div className="rounded-2xl p-6 md:p-7 h-full bg-bg/40 backdrop-blur-md"
      style={{ borderWidth: 1, borderStyle: 'solid', borderColor: s.border, WebkitBackdropFilter: 'blur(10px) saturate(110%)' }}>
      <div className="flex items-center gap-2 mb-4">
        <span className="size-1.5 rounded-full" style={{ background: s.dot, boxShadow: `0 0 8px ${s.dot}` }} />
        <span className="kicker" style={{ color: s.kicker }}>{data.kicker}</span>
      </div>
      <h4 className="font-serif text-[20px] md:text-[22px] leading-[1.15] text-ink/95 mb-3" style={{ fontFamily: '"Instrument Serif", serif' }}>{data.title}</h4>
      <p className="text-[13.5px] text-mute leading-[1.55] mb-5">{data.desc}</p>
      <div className="flex flex-wrap gap-1.5">
        {data.items.map((it, i) => (
          <span key={i} className="text-[10px] font-mono uppercase tracking-[0.14em] text-ink/85 px-2 py-0.5 rounded-full border border-line bg-bg/40">{it}</span>
        ))}
      </div>
    </div>);
}

function OperationalIntelligenceBridge() {
  return (
    <section id="inteligencia-operativa" className="relative py-24 md:py-32">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="max-w-[960px] mb-16 md:mb-20">
            <div className="kicker mb-3">Y esto es solo el primer empleado IA</div>
            <h2 className="display-lg text-[clamp(38px,4.8vw,72px)] leading-[1.02] mb-5">
              Cuando la IA entiende <span className="italic text-cyan">tu lógica</span>, puede trabajar en cualquier área.
            </h2>
            <p className="text-[16px] md:text-[17.5px] text-mute leading-[1.6] max-w-[760px]">
              WhatsApp es el caso visible. El valor real es conectar IA con tus datos, reglas y decisiones — la misma arquitectura puede operar en ventas, atención, administración, dirección, operaciones o marketing.
            </p>
          </div>
        </Reveal>
        <div className="mt-16 md:mt-20">
          <Reveal>
            <div className="flex flex-col md:flex-row md:items-baseline md:gap-6 mb-8 md:mb-10">
              <span className="kicker mb-2 md:mb-0 md:min-w-[180px]">01 · Áreas donde puede trabajar</span>
              <h3 className="font-serif text-[clamp(24px,2.6vw,34px)] leading-[1.1] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>
                Misma arquitectura, <span className="italic">distinta especialidad</span>.
              </h3>
            </div>
          </Reveal>
          <div className="grid gap-4 md:gap-5 sm:grid-cols-2 lg:grid-cols-3">
            {OIB_AREAS.map((a) => <OIBAreaCard key={a.n} a={a} />)}
          </div>
        </div>
      </div>
    </section>);
}

/* SECTION: Quiénes somos
   Tres pilares (Quiénes / Visión / Misión) + un bloque corto "Nuestro
   compromiso" que absorbe en positivo las 6 verdades de la "Promesa
   honesta" del OperationalIntelligenceBridge (defensivas en la base; acá
   en 3 bullets afirmativos). CTAs llevan a contacto + proceso. */
function QuienesSomos() {
  const pillars = [
    { n: '01', tone: 'cyan',
      kicker: 'Quiénes somos',
      title: 'Equipo emprendedor uruguayo, obsesionado con producto.',
      body: 'Dejamos atrás las herramientas viejas para construir con lo que la tecnología actual permite hoy: agentes que entienden, sistemas que aprenden, software que se acomoda a cada negocio. No vendemos plantillas — cada proyecto se diseña con tu operación adentro.' },
    { n: '02', tone: 'violet',
      kicker: 'Visión',
      title: 'Que cualquier empresa tenga su propia inteligencia operativa.',
      body: 'IA conectada a tus reglas, tus datos, tu tono y tu gente. No una herramienta enchufada por arriba, sino una capa que vive dentro del negocio y opera con las prioridades que vos definís.' },
    { n: '03', tone: 'cyan',
      kicker: 'Misión',
      title: 'Devolverle horas a tu equipo y herramientas que se sientan hechas a medida.',
      body: 'Diseñamos empleados IA, paneles y automatizaciones que liberan personas de tareas repetitivas, ordenan la operación y entregan a cada empresa un sistema que sienta — y sea — propio.' }];
  const toneStyles = {
    cyan:   { border: 'rgba(51,194,234,0.28)',  glow: '0 0 0 1px rgba(51,194,234,0.08), 0 18px 40px -28px rgba(51,194,234,0.35)',  badge: 'rgba(51,194,234,0.85)',  badgeBg: 'rgba(51,194,234,0.10)',  badgeBd: 'rgba(51,194,234,0.30)' },
    violet: { border: 'rgba(158,123,255,0.32)', glow: '0 0 0 1px rgba(158,123,255,0.08), 0 18px 40px -28px rgba(158,123,255,0.35)', badge: 'rgba(192,170,255,0.95)', badgeBg: 'rgba(158,123,255,0.12)', badgeBd: 'rgba(158,123,255,0.32)' }};
  return (
    <section id="quienes-somos" className="relative py-24 md:py-32">
      <SectionDivider />
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="text-center mb-16 md:mb-20 max-w-[920px] mx-auto">
            <div className="kicker mb-4 inline-block">Equipo · Visión · Misión</div>
            <h2 className="display-lg text-[clamp(38px,4.8vw,72px)] leading-[1.02] mb-7">
              Construimos en Uruguay <span className="italic text-cyan">la siguiente capa</span> de tu negocio.
            </h2>
            <p className="text-[16px] md:text-[17.5px] text-mute leading-[1.6] max-w-[720px] mx-auto">
              No vendemos cursos ni plantillas. Diseñamos sistemas inteligentes que se sienten hechos específicamente para tu empresa — porque, en serio, lo son.
            </p>
          </div>
        </Reveal>
        <div className="grid gap-4 md:gap-5 lg:gap-6 sm:grid-cols-2 lg:grid-cols-3">
          {pillars.map((p, i) => {
            const s = toneStyles[p.tone] || toneStyles.cyan;
            return (
              <Reveal key={p.n} delay={i * 120}>
                <article className="card-solid rounded-2xl p-6 md:p-7 h-full flex flex-col transition-colors duration-300"
                  style={{ borderColor: s.border, boxShadow: s.glow }}>
                  <div className="flex items-center justify-between mb-5">
                    <span className="text-[10px] font-mono uppercase tracking-[0.22em] px-2 py-1 rounded"
                      style={{ color: s.badge, border: `1px solid ${s.badgeBd}`, background: s.badgeBg }}>
                      {p.n} · {p.kicker}
                    </span>
                    <span className="text-[10px] font-mono uppercase tracking-[0.2em] text-dim">newGalaxIA</span>
                  </div>
                  <h3 className="font-serif text-[22px] md:text-[24px] leading-[1.18] text-ink/95 mb-4" style={{ fontFamily: '"Instrument Serif", serif' }}>{p.title}</h3>
                  <p className="text-[14.5px] md:text-[15px] text-mute leading-[1.6]">{p.body}</p>
                </article>
              </Reveal>);
          })}
        </div>
        <Reveal delay={340}>
          <div className="mt-12 md:mt-14 max-w-[960px] mx-auto">
            <div className="kicker mb-5 text-center" style={{ color: 'rgba(51,194,234,0.85)' }}>Nuestro compromiso</div>
            <ul className="grid gap-3 sm:grid-cols-3">
              {[
                'Reglas y tono aprobados por tu equipo — el agente habla como ustedes.',
                'QA continuo sobre conversaciones reales. Medimos antes de prometer.',
                'Cada caso nuevo entrena al agente para el siguiente — mejora visible.',
              ].map((line, i) => (
                <li key={i} className="flex items-start gap-3 rounded-xl border border-line bg-bg/40 backdrop-blur-md p-4 md:p-5 text-[13.5px] md:text-[14px] text-ink/92 leading-[1.5]"
                    style={{ WebkitBackdropFilter: 'blur(10px) saturate(110%)' }}>
                  <span className="text-cyan flex-shrink-0 mt-[5px] size-1.5 rounded-full bg-cyan" aria-hidden="true" />
                  <span>{line}</span>
                </li>
              ))}
            </ul>
          </div>
        </Reveal>
        <Reveal delay={420}>
          <div className="mt-12 md:mt-14 flex flex-col sm:flex-row gap-3 sm:gap-4 sm:justify-center items-stretch sm:items-center">
            <a href="#contacto" className="btn-cta rounded-full bg-ink text-bg px-7 py-3.5 text-sm font-medium inline-flex items-center justify-center gap-3">
              Hablemos de tu negocio
              <span aria-hidden="true" className="btn-arrow">→</span>
            </a>
            <a href="#proceso" className="btn-cta rounded-full border border-line bg-bg/40 px-7 py-3.5 text-sm text-ink/90 inline-flex items-center justify-center gap-3">
              Ver cómo trabajamos
              <span aria-hidden="true" className="text-cyan btn-arrow">↓</span>
            </a>
          </div>
        </Reveal>
      </div>
    </section>);
}

/* ───────── SeccionUnoIntro · Visión en operación ───────── */
function SeccionUnoIntro() {
  return (
    <section id="vision" className="relative py-20 md:py-28 border-t border-line">
      <div className="mx-auto max-w-[1280px] px-6 md:px-8">
        <Reveal>
          <div className="mb-10 md:mb-14">
            <div className="kicker mb-3 inline-block">01 — Visión en operación</div>
            <h2 className="font-serif text-[clamp(34px,4.6vw,68px)] leading-[1.04] max-w-[920px]"
              style={{ fontFamily: '"Instrument Serif", serif', letterSpacing: '-0.01em' }}>
              Lo que <span className="italic text-cyan">la IA</span> hace por tu negocio cuando lo dejás escalar.
            </h2>
          </div>
        </Reveal>
        <div className="hidden md:grid md:grid-cols-12 gap-10 lg:gap-12 items-stretch">
          <div className="md:col-span-6 lg:col-span-6 flex flex-col justify-between gap-8 md:gap-6 py-2">
            <Reveal>
              <p className="font-serif text-[clamp(25px,8vw,46px)] leading-[1.14] text-ink/95" style={{ fontFamily: '"Instrument Serif", serif' }}>
                Diseñamos software a medida para tu negocio
                {' '}— <span className="italic">agentes de IA conversacionales, webs modernas, apps que viven en tu bolsillo</span>, y sistemas para que manejes todo en tiempo real desde el celular.
              </p>
            </Reveal>
            <Reveal delay={180}>
              <p className="text-[16.5px] md:text-[21px] text-ink/82 leading-[1.5] md:leading-[1.55] max-w-[600px] mt-5 md:mt-7">
                Imaginá tu empresa <span className="italic text-ink">escalando sola</span> — atendiendo, vendiendo, agendando y sincronizando todo 24/7, con el tono de tu marca. Tu equipo deja de copiar y pegar respuestas, y empieza a hacer lo que mueve la aguja.
                <br className="hidden md:block" />
                <span className="text-cyan font-medium">El próximo nivel de tu negocio empieza con una conversación.</span>
              </p>
            </Reveal>
            <Reveal delay={300}>
              <div className="mt-8 md:mt-10 flex flex-col sm:flex-row sm:flex-wrap items-stretch sm:items-center gap-3 md:gap-4">
                <a href="#contacto" className="btn-cta group relative rounded-full bg-ink text-bg px-6 py-3.5 text-sm font-medium inline-flex items-center justify-center gap-3">
                  Reservar diagnóstico
                  <span aria-hidden="true" className="btn-arrow">→</span>
                </a>
                <a href="#casos" className="btn-cta rounded-full border border-line bg-bg/40 px-6 py-3.5 text-sm text-ink/90 inline-flex items-center justify-center gap-3">
                  Ver caso real
                  <span aria-hidden="true" className="text-cyan btn-arrow">↓</span>
                </a>
                {/* V3 polish ADDENDUM 29 (2026-05-18) — menú externo oculto.
                    SeccionUnoIntro tampoco se renderiza en V1/V3 (no está en
                    app.jsx), pero limpiamos por consistencia. */}
                {/* <AIEmployeesMenu variant="hero" /> */}
              </div>
            </Reveal>
          </div>
          <div className="hidden md:block md:col-span-6 lg:col-span-6">
            <HeroChat />
          </div>
        </div>
      </div>
    </section>);
}

Object.assign(window, {
  Nav, Hero, Problema, Proceso, EmpleadosCentro, Verticales, CasoReal,
  PorQue, Precios, Faq, Contacto, Footer, useReveal, Reveal,
  SeccionUnoIntro, AgentResolvedSummarySection, OperationalIntelligenceBridge,
  QuienesSomos,
  /* V3: HeroChat expuesto por si DemoPeek (variantes pipeline/portal
     de hero-v2.jsx) llegan a renderizarse en algún tweak. En orbital (default)
     DemoPeek no se invoca, pero exportarlo previene un undefined latente. */
  HeroChat,
  /* V3 polish (2026-05-18): AIEmployeesMenu expuesto a window para que el
     HeroOrbital del template pueda inyectarlo en su columna izquierda solo
     en mobile (md:hidden), recuperando el menú que tenía el Hero legacy. */
  AIEmployeesMenu
});
