/* global React */
const { useState, useEffect, useRef } = React;

/* ============================================================
   Helpers
   ============================================================ */

const LOGO_SRC = "brand/logo-principal-dark.png";
const LOGO_SRC_LIGHT = "brand/logo-principal.png";

/* ============================================================
   1. NAVBAR
   ============================================================ */

function Navbar({ onNavigate }) {
  const [scrolled, setScrolled] = useState(false);
  const [sheetOpen, setSheetOpen] = useState(false);

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

  const items = [
  { id: 'nosotros', label: 'NOSOTROS' },
  { id: 'problema', label: 'REALIDAD' },
  { id: 'sistema', label: 'SISTEMA' },
  { id: 'servicios', label: 'SERVICIOS' },
  { id: 'proceso', label: 'PROCESO' }];


  const handle = (id) => {
    setSheetOpen(false);
    onNavigate(id);
  };

  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 50,
      background: 'var(--color-surface)',
      borderBottom: 'none'
    }}>
      <div className="container" style={{
        height: 52,
        display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 36
      }}>
        <nav className="velora-nav-desktop" style={{ display: 'flex', alignItems: 'center', gap: 36 }}>
          {items.map((it) =>
          <button key={it.id} className="nav-link"
          onClick={() => handle(it.id)} style={{ fontFamily: "Inter", fontWeight: "700" }}>
              {it.label}
            </button>
          )}
        </nav>

        {/* Nav CTA removed — lives in hero now */}
        <div className="velora-nav-desktop" style={{ display: 'none' }}>
          <button onClick={() => handle('contacto')}
          style={{
            fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 13,
            textTransform: 'uppercase', letterSpacing: '0.5px',
            background: 'var(--color-accent)', color: '#fff',
            borderRadius: 'var(--radius-button)',
            padding: '10px 20px', transition: 'background 150ms ease-out'
          }}
          onMouseEnter={(e) => e.currentTarget.style.background = 'var(--color-accent-hover)'}
          onMouseLeave={(e) => e.currentTarget.style.background = 'var(--color-accent)'}>
            Agenda diagnóstico
          </button>
        </div>

        <button className="velora-nav-mobile" aria-label="Menú"
        onClick={() => setSheetOpen(true)}
        style={{ display: 'none', padding: 10 }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
            <line x1="4" y1="7" x2="20" y2="7" />
            <line x1="4" y1="12" x2="20" y2="12" />
            <line x1="4" y1="17" x2="20" y2="17" />
          </svg>
        </button>
      </div>

      {sheetOpen &&
      <div style={{
        position: 'fixed', inset: 0, zIndex: 60,
        background: 'rgba(26,23,20,0.45)'
      }} onClick={() => setSheetOpen(false)}>
          <aside onClick={(e) => e.stopPropagation()}
        style={{
          position: 'absolute', right: 0, top: 0, bottom: 0,
          width: 'min(360px, 86vw)',
          background: 'var(--color-surface)',
          padding: '28px 24px',
          animation: 'sheet-in 280ms var(--ease-emil) both',
          display: 'flex', flexDirection: 'column', gap: 24
        }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <img src={LOGO_SRC} alt="" style={{ height: 20, color: 'var(--color-text-primary)' }} />
              <button onClick={() => setSheetOpen(false)} aria-label="Cerrar"
            style={{ padding: 6, color: 'var(--color-text-primary)' }}>
                <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
                  <line x1="6" y1="6" x2="18" y2="18" />
                  <line x1="18" y1="6" x2="6" y2="18" />
                </svg>
              </button>
            </div>
            <nav style={{ display: 'flex', flexDirection: 'column', gap: 4, marginTop: 12 }}>
              {items.map((it) =>
            <button key={it.id} onClick={() => handle(it.id)}
            style={{
              fontFamily: 'var(--font-inter)', fontWeight: 500, fontSize: 18,
              textAlign: 'left', padding: '14px 0',
              borderBottom: '1px solid var(--color-border)'
            }}>
                  {it.label}
                </button>
            )}
            </nav>
            <button onClick={() => handle('contacto')}
          style={{
            marginTop: 8,
            fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 13,
            textTransform: 'uppercase', letterSpacing: '0.5px',
            background: 'var(--color-accent)', color: '#fff',
            borderRadius: 'var(--radius-button)',
            padding: '14px 18px'
          }}>
              Agenda diagnóstico
            </button>
          </aside>
        </div>
      }

      <style>{`
        .nav-link {
          font-family: var(--font-inter);
          font-weight: 500;
          font-size: 15px;
          color: var(--color-text-primary);
          position: relative;
          padding: 6px 0;
          transition: color 150ms ease-out;
        }
        .nav-link::after {
          content: '';
          position: absolute; left: 0; right: 100%; bottom: 0;
          height: 1px; background: var(--color-accent);
          transition: right 150ms ease-out;
        }
        .nav-link:hover::after { right: 0; }
        @media (max-width: 880px) {
          .velora-nav-desktop { display: none !important; }
          .velora-nav-mobile { display: inline-flex !important; }
        }
      `}</style>
    </header>);

}

/* ============================================================
   HERO BACKGROUND — floating paths (adapted from framer-motion original)
   ============================================================ */

/* HeroBackground removed */
function HeroBackground() {return null;}

/* ============================================================
   2. HERO
   ============================================================ */

function Hero({ layout = 'left' }) {
  const [p, setP] = useState(0);
  const [animate, setAnimate] = useState(false);

  useEffect(() => {
    const updateAnimate = () => setAnimate(window.innerWidth > 768);
    updateAnimate();

    let raf = null;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        const trigger = Math.max(300, window.innerHeight * 0.55);
        setP(Math.min(1, Math.max(0, window.scrollY / trigger)));
        raf = null;
      });
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', updateAnimate);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', updateAnimate);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  const finalScale = 0.16;
  const initX = 48,initY = 84; // hero left padding below 52px navbar
  const finalX = 24,finalY = 14;
  const scale = animate ? 1 - (1 - finalScale) * p : 1;
  const tx = animate ? (finalX - initX) * p : 0;
  const ty = animate ? (finalY - initY) * p : 0;

  return (
    <section id="top" className="hero-2col" style={{
      width: '100%',
      height: '100vh',
      minHeight: '100vh',
      background: 'var(--color-surface)',
      display: 'grid',
      gridTemplateColumns: '50% 50%',
      gridTemplateRows: '1fr',
      overflow: 'hidden',
      position: 'relative'
    }}>
      <HeroBackground />
      {/* Floating logo — shrinks from hero position to upper-left as user scrolls */}
      {animate &&
      <div aria-hidden={p > 0.95} style={{
        position: 'fixed',
        top: initY,
        left: initX,
        zIndex: 60,
        transformOrigin: 'top left',
        transform: `translate3d(${tx}px, ${ty}px, 0) scale(${scale})`,
        willChange: 'transform',
        pointerEvents: 'none'
      }}>
        <img src={LOGO_SRC} alt="Velora Studio"
        style={{
          width: 'min(calc(50vw - 80px), 540px)',
          height: 'auto',
          display: 'block'
        }} />
      </div>
      }

      {/* LEFT COLUMN */}
      <div className="hero-left" style={{
        gridColumn: 1,
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'space-between',
        padding: '32px 32px 48px 48px'
      }}>
        <div style={{ animation: 'velora-in-y 500ms var(--ease-emil) 200ms both' }}>
          {animate ?
          /* spacer reserves the logo's original space; real logo is rendered fixed below */
          <div aria-hidden="true" style={{
            width: '100%',
            aspectRatio: '1803 / 385'
          }} /> :

          <img src={LOGO_SRC}
          alt="Velora — wordmark"
          className="hero-logo"
          style={{
            width: '100%',
            height: 'auto',
            objectFit: 'contain',
            objectPosition: 'left',
            display: 'block'
          }} />
          }
          <div className="hero-labels" style={{
            display: 'flex',
            justifyContent: 'space-between',
            marginTop: 12
          }}>
            <span style={heroLabelStyle}></span>
            <span style={heroLabelStyle}></span>
          </div>
        </div>

        <div className="hero-middle" style={{
          maxWidth: 360,
          animation: 'velora-in-y 500ms ease-out 550ms both'
        }}>
          <div style={{
            fontFamily: 'var(--font-inter)',
            textTransform: 'uppercase', letterSpacing: '2.5px',
            color: 'var(--color-accent)',
            marginBottom: 16, fontWeight: "700", fontSize: "12px"
          }}>ESTUDIO DE DISEÑO ESTRATÉGICO

          </div>
          <p style={{
            margin: 0,
            fontFamily: 'var(--font-playfair)', fontStyle: 'italic', fontWeight: 400,
            fontSize: 26, lineHeight: 1.25,
            color: 'var(--color-text-primary)'
          }}>Diseñamos la operación que conecta marca, datos y producto en un solo motor.</p>
        </div>

        <p className="hero-descriptor" style={{
          fontFamily: 'var(--font-arimo)', fontWeight: 400,
          fontSize: 14, lineHeight: 1.7,
          color: 'var(--color-text-tertiary)',
          margin: 0,
          maxWidth: 280,
          animation: 'velora-in-y 500ms ease-out 700ms both'
        }}>

        </p>
      </div>

      {/* DIVIDER removed */}

      {/* RIGHT COLUMN */}
      <div className="hero-right" style={{
        gridColumn: 2,
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'flex-end',
        textAlign: 'right',
        padding: '40px 64px 64px 56px'
      }}>
        <div style={{ animation: 'velora-in-y-lg 600ms var(--ease-emil) 350ms both' }}>
          <span style={{
            display: 'block',
            fontFamily: 'var(--font-inter)', fontWeight: 800,
            fontSize: 'clamp(28px, 3.4vw, 44px)',
            lineHeight: 1.05,
            color: 'var(--color-text-primary)',
            letterSpacing: '-1px'
          }}>Tu marca no necesita otra campaña.</span>
          <span style={{
            display: 'block',
            fontFamily: 'var(--font-inter)', fontWeight: 800,
            fontSize: 'clamp(28px, 3.4vw, 44px)',
            lineHeight: 1.05,
            color: 'var(--color-accent)',
            letterSpacing: '-1px',
            marginTop: 0
          }}>Necesita un sistema.</span>

          <div style={{
            display: 'inline-flex',
            flexWrap: 'wrap',
            gap: 12,
            marginTop: 40,
            justifyContent: 'flex-end'
          }}>
            <a href="#sistema"
            onClick={(e) => {e.preventDefault();document.getElementById('sistema')?.scrollIntoView({ behavior: 'smooth', block: 'start' });}}
            className="hero-primary-cta"
            style={{
              display: 'inline-flex',
              alignItems: 'center',
              gap: 8,
              background: 'var(--color-surface-dark)',
              color: 'var(--color-text-inverse)',
              fontFamily: 'var(--font-inter)', fontWeight: 600,
              fontSize: 12,
              letterSpacing: '1px',
              textTransform: 'uppercase',
              padding: '14px 32px',
              borderRadius: 2,
              border: 'none',
              transition: 'background 150ms ease-out'
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = '#000'}
            onMouseLeave={(e) => e.currentTarget.style.background = 'var(--color-surface-dark)'}>
              VER CÓMO OPERA <span aria-hidden="true"></span>
            </a>
            <a href="#contacto"
            onClick={(e) => {e.preventDefault();document.getElementById('contacto')?.scrollIntoView({ behavior: 'smooth', block: 'start' });}}
            style={{
              display: 'inline-flex',
              alignItems: 'center',
              gap: 8,
              background: 'var(--color-accent)',
              color: '#fff',
              fontFamily: 'var(--font-inter)', fontWeight: 600,
              fontSize: 12,
              letterSpacing: '1px',
              textTransform: 'uppercase',
              padding: '14px 32px',
              borderRadius: 2,
              border: 'none',
              transition: 'background 150ms ease-out'
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = 'var(--color-accent-hover)'}
            onMouseLeave={(e) => e.currentTarget.style.background = 'var(--color-accent)'}>AGENDA TU DIAGNÓSTICO  →

            </a>
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 768px) {
          .hero-2col {
            display: flex !important;
            flex-direction: column !important;
            height: auto !important;
            min-height: 100vh !important;
            padding: 32px 24px !important;
          }
          .hero-left { display: contents !important; }
          .hero-left > div:first-child { order: 1; padding: 0 !important; }
          .hero-right { padding: 0 !important; order: 2; margin-top: 32px; }
          .hero-descriptor { order: 3 !important; margin-top: 32px !important; max-width: 100% !important; }
          .hero-divider { display: none !important; }
          .hero-logo { width: 70vw !important; }
          .hero-right span { font-size: 40px !important; }
        }
      `}</style>
    </section>);

}

const heroLabelStyle = {
  fontFamily: 'var(--font-inter)',
  fontWeight: 600,
  fontSize: 10,
  letterSpacing: '2.5px',
  textTransform: 'uppercase',
  color: 'var(--color-accent)'
};

/* ============================================================
   3. PROBLEMA
   ============================================================ */

function Problema() {

  const items = [
  {
    title: 'Tu producto es mejor. Ellos ganan igual.',
    body: 'Tienes un producto sólido y tracción real, pero un competidor con menos sustancia te está ganando por posicionamiento, marca y presencia digital. El mercado percibe lo que ve, no lo que mereces.'
  },
  {
    title: 'Inviertes en marketing. No apareces.',
    body: 'Tienes un negocio que funciona por referidos, pero cuando alguien te busca en Google no te encuentra, tu sitio no convence o tus redes no reflejan lo que realmente eres. Cada cliente que pasa sin verte es dinero que se fue.'
  },
  {
    title: 'Tu equipo ejecuta. La estrategia no avanza.',
    body: 'Tienes agencias, freelancers o equipo interno trabajando — pero sin una dirección integrada, cada uno jala para su lado. Los reportes llegan, los resultados no. El problema no es el talento: es que nadie diseñó el sistema.'
  }];


  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 0,
      paddingBottom: 'var(--spacing-section)'
    }}>
      <div className="container">

        {/* ── QUOTE ── */}
        <FadeUp style={{ marginBottom: 'clamp(48px, 6vw, 72px)' }}>
          <p style={{
            fontFamily: 'var(--font-playfair)', fontStyle: 'italic',
            fontSize: 22, color: 'var(--color-text-secondary)',
            margin: 0, maxWidth: 480
          }}>
            «Más datos, más reuniones, menos claridad.»
          </p>
        </FadeUp>

        {/* ── ITEMS — 3 columnas, respiran ── */}
        <div className="problema-cols" style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gap: 'clamp(24px, 4vw, 48px)'
        }}>
          {items.map((it, i) =>
          <FadeUp key={i} delay={i * 0.1}>
            <div style={{ borderTop: '2px solid var(--color-accent)', paddingTop: 28 }}>
              <div style={{
                fontFamily: 'var(--font-inter)', fontWeight: 800,
                fontSize: 40, lineHeight: 1,
                color: 'var(--color-accent)', marginBottom: 16
              }}>{String(i + 1).padStart(2, '0')}</div>
              <div style={{
                fontFamily: 'var(--font-inter)', fontWeight: 700, fontSize: 18,
                color: 'var(--color-text-primary)', marginBottom: 12, lineHeight: 1.3
              }}>{it.title}</div>
              <div style={{
                fontFamily: 'var(--font-arimo)', fontWeight: 400, fontSize: 16,
                color: 'var(--color-text-secondary)', lineHeight: 1.7
              }}>{it.body}</div>
            </div>
          </FadeUp>
          )}
        </div>
      </div>

      <style>{`
        @media (max-width: 720px) {
          .problema-cols { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </section>);

}

/* ============================================================
   CAPACIDADES — spotlight reel section
   ============================================================ */

function Capacidades() {
  const items = [
  'Diseño Estratégico',
  'Identidad de Marca',
  'Estrategia de Contenido',
  'Presencia Digital',
  'Performance Marketing',
  'Business Intelligence',
  'Automatización',
  'Growth Systems',
  'Customer Journey',
  'Arquitectura de Marca',
  'Decisiones con Datos',
  'Diseño Editorial'];


  const listRef = useRef(null);

  useEffect(() => {
    const list = listRef.current;
    if (!list) return;

    const update = () => {
      const items = list.querySelectorAll('.velora-reel-item');
      const center = window.innerHeight / 2;
      let closest = null;
      let minDist = Infinity;

      items.forEach((item) => {
        const rect = item.getBoundingClientRect();
        const itemCenter = rect.top + rect.height / 2;
        const dist = Math.abs(itemCenter - center);
        if (dist < minDist) {
          minDist = dist;
          closest = item;
        }
      });

      items.forEach((i) => i.classList.remove('is-active'));
      if (closest) closest.classList.add('is-active');
    };

    window.addEventListener('scroll', update, { passive: true });
    update();
    return () => window.removeEventListener('scroll', update);
  }, []);

  return (
    <section id="capacidades" style={{ background: 'var(--color-surface)', position: 'relative' }}>
      <div className="velora-reel-wrap">
        <header className="velora-reel-header">
          <div className="velora-reel-label">
            <span style={{ fontSize: 30, fontWeight: 700 }}>NOSOTROS HACEMOS</span>
          </div>
        </header>
        <ul ref={listRef} className="velora-reel-list" aria-label="Capacidades de Velora Studio">
          {items.map((item, i) =>
          <React.Fragment key={i}>
              <li className="velora-reel-item">{item}</li>
              {i < items.length - 1 &&
            <li className="velora-snap-stop" aria-hidden="true" />
            }
            </React.Fragment>
          )}
        </ul>
      </div>
      <style>{`
        .velora-reel-wrap {
          display: grid; grid-template-columns: 28% 1fr; gap: 0;
          padding-top: clamp(80px, 10vw, 140px);
          padding-bottom: clamp(80px, 10vw, 140px);
          max-width: 1320px; margin: 0 auto;
          padding-left: var(--spacing-container);
          padding-right: var(--spacing-container);
        }
        .velora-reel-header {
          position: sticky; top: 50vh; align-self: start;
          transform: translateY(-50%); padding-right: 40px;
        }
        .velora-reel-label {
          font-family: var(--font-inter); text-transform: uppercase;
          letter-spacing: 2px; color: var(--color-accent);
        }
        .velora-reel-list {
          list-style: none; margin: 0; padding: 0;
          display: flex; flex-direction: column;
          gap: 0;
        }
        .velora-reel-item {
          font-family: var(--font-inter); font-weight: 700;
          font-size: clamp(40px, 4.5vw, 66px);
          line-height: 1.1; letter-spacing: -1.5px; white-space: nowrap;
          padding: clamp(10px, 2vh, 20px) 0;
          color: color-mix(in oklch, var(--color-text-primary), transparent 80%);
          transition: color 280ms cubic-bezier(0.16, 1, 0.3, 1);
          scroll-snap-align: center;
          scroll-snap-stop: always;
        }
        .velora-reel-item.is-active {
          color: #E31E24;
        }
        .velora-snap-stop {
          list-style: none;
          height: clamp(20px, 4vh, 40px);
          scroll-snap-align: center;
          scroll-snap-stop: always;
        }
        @media (max-width: 880px) {
          .velora-reel-wrap { grid-template-columns: 1fr; }
          .velora-reel-header { position: relative; top: auto; transform: none; margin-bottom: 40px; }
          .velora-reel-item { font-size: clamp(36px, 8vw, 64px); }
        }
      `}</style>
    </section>);

}

/* ============================================================
   3.5 NOSOTROS
   ============================================================ */

function Nosotros() {


  const paragraphs = [
  'Velora es un estudio de diseño estratégico, marketing digital e inteligencia de negocios.',
  'Convertimos la complejidad de tu negocio en marca con carácter, presencia digital que genera clientes y decisiones respaldadas por datos reales — no como una agencia que publica contenido, sino como el equipo que diseña el sistema que lo hace funcionar.',
  'Si tienes un negocio establecido que ya vende pero que no tiene la presencia, los sistemas ni la marca que merece — ahí es donde entramos. Construimos la estructura que convierte lo que ya funciona en algo que escala.',
  'Cada proyecto empieza por ver lo que otros no ven: la estructura invisible detrás de tu negocio. Lo que ya funciona, lo que frena, lo que falta conectar. Desde ahí construimos.'];


  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 0,
      paddingBottom: 'clamp(64px, 8vw, 120px)'
    }}>
      <div className="container">
        <div style={{ maxWidth: 680 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 28 }}>
            {paragraphs.map((para, i) =>
            <FadeUp key={i} delay={i * 0.09}>
              <p className="nosotros-para" style={{
                margin: 0,
                fontFamily: 'var(--font-arimo)',
                fontSize: 18, lineHeight: 1.75,
                color: 'var(--color-text-primary)',
                fontWeight: "400"
              }}>{para}</p>
            </FadeUp>
            )}
          </div>
          <FadeUp delay={0.28}>
            <a href="#proceso"
            onClick={(e) => {e.preventDefault();document.getElementById('proceso')?.scrollIntoView({ behavior: 'smooth', block: 'start' });}}
            className="nosotros-cta"
            style={{
              display: 'inline-block',
              marginTop: 32,
              fontFamily: 'var(--font-inter)', fontWeight: 600,
              textTransform: 'uppercase', letterSpacing: '1px',
              color: 'var(--color-accent)',
              fontSize: '15px'
            }}>
              CONOCE EL PROCESO <span className="nosotros-arrow" style={{ display: 'inline-block', marginLeft: 4, transition: 'transform 150ms ease-out' }}>→</span>
            </a>
          </FadeUp>
        </div>
      </div>

      <style>{`
        .nosotros-cta:hover .nosotros-arrow { transform: translateX(4px); }
      `}</style>
    </section>);

}

/* ============================================================
   RADIAL DIAGRAM — spoke system with Velora star center
   ============================================================ */

const VELORA_STAR_PATH = "M422.72,190.05c-.11,2.83-2.4,5.12-5.26,5.19-11.1,.29-22.94,.82-37.33,1.79-35.19,2.33-64.03,5.66-90.81,10.49-17.65,3.22-31.71,6.62-44.28,10.7-15.89,5.15-28.81,13.14-43.27,26.67-44.71,41.91-83.33,91.09-119.09,137.88-1.07,1.36-2.65,2.11-4.26,2.11-1.07,0-2.18-.32-3.11-1-2.36-1.65-2.97-4.87-1.4-7.3,7.12-10.95,13.92-21.94,19.01-30.28,11.38-18.58,26.09-43.24,39.34-69.3,.89-1.72,2.04-3.83,3.36-6.26,6.8-12.53,22.76-41.88,12.99-50.36-10.17-8.84-24.88-11.13-39.12-13.39-1.68-.25-3.36-.5-5.01-.79-33.65-5.51-67.76-8.91-99.58-11.81C2.08,194.13-.04,191.76,0,188.94c.07-2.79,2.29-5.12,5.08-5.26,10.88-.57,22.55-1.4,35.69-2.47,34.79-2.86,63.32-6.26,89.84-10.7,17.68-2.94,31.71-5.91,44.28-9.31,17.22-4.69,29.39-11.28,41.99-22.8,45.71-41.63,85.4-92.17,119.01-136.27,1.72-2.29,4.94-2.79,7.27-1.22,2.36,1.61,3.08,4.8,1.57,7.23-4.44,7.37-8.81,14.78-13.17,22.23-15.71,26.92-27.88,48.89-38.33,69.23-.93,1.75-2.26,4.15-3.87,6.98-6.26,11.13-25.27,44.99-16.97,52.55,7.34,6.62,23.44,9.38,35.22,11.42,2.58,.43,5.01,.86,7.16,1.29,32.14,6.26,64.43,9.63,103.01,12.71,2.83,.21,5.01,2.65,4.94,5.51Z";

const RD_CX = 370, RD_CY = 315, RD_R = 200, RD_INNER = 74;

// angle: degrees clockwise from right (SVG y-down). lx/ly: label anchor point. ta: textAnchor
// Labels = diferenciadores del sistema Velora, no tipos de servicio
const RD_SPOKES = [
  { angle: 0,   label: 'Sistema Propio',     lx: 592, ly: 319, ta: 'start'  },
  { angle: 45,  label: '22 Agentes IA',      lx: 528, ly: 472, ta: 'start'  },
  { angle: 90,  label: 'Datos Integrados',   lx: 370, ly: 538, ta: 'middle' },
  { angle: 135, label: 'Una Sola Voz',       lx: 212, ly: 472, ta: 'end'    },
  { angle: 180, label: 'Sin Dependencias',   lx: 148, ly: 319, ta: 'end'    },
  { angle: 225, label: 'Documentación Viva', lx: 212, ly: 158, ta: 'end'    },
  { angle: 270, label: 'Dirección Humana',   lx: 370, ly: 84,  ta: 'middle' },
  { angle: 315, label: 'Marca + Negocio',    lx: 528, ly: 158, ta: 'start'  },
];

function rdEndpoint(angleDeg) {
  const r = angleDeg * Math.PI / 180;
  return { x: RD_CX + RD_R * Math.cos(r), y: RD_CY + RD_R * Math.sin(r) };
}
// Inner start point — on the ring perimeter, not the center
function rdInner(angleDeg) {
  const r = angleDeg * Math.PI / 180;
  return { x: RD_CX + RD_INNER * Math.cos(r), y: RD_CY + RD_INNER * Math.sin(r) };
}
const RD_LINE_LEN = RD_R - RD_INNER; // 200-74 = 126

function RadialDiagram() {
  const containerRef = useRef(null);
  const lineRefs     = useRef([]);
  const dotRefs      = useRef([]);
  const glowRefs     = useRef([]);
  const glowTweens   = useRef([]);

  useEffect(() => {
    const { gsap, ScrollTrigger } = window;
    if (!gsap || !ScrollTrigger) return;
    const container = containerRef.current;
    if (!container) return;

    const lines = lineRefs.current.filter(Boolean);
    const dots  = dotRefs.current.filter(Boolean);
    const glows = glowRefs.current.filter(Boolean);

    // Initial state
    lines.forEach(l => {
      l.style.strokeDasharray  = String(RD_LINE_LEN);
      l.style.strokeDashoffset = String(RD_LINE_LEN);
    });
    dots.forEach(d => { d.style.opacity = '0'; });
    glows.forEach(g => { g.style.opacity = '0'; });

    const startGlow = () => {
      const interval     = 0.75;             // seconds between each dot — slower radial sweep
      const glowDuration = interval * 8;     // 6s — full radial cycle

      // Dots stay at fixed r=5.5 — no size animation, only the glow halo animates
      glows.forEach((g, i) => {
        // Glow halo: opacity blooms then fades (GaussianBlur softened to stdDeviation=2)
        const gtl = gsap.timeline({ repeat: -1, delay: i * interval });
        gtl
          .to(g, { opacity: 0.55, duration: 0.30, ease: 'power2.out' })
          .to(g, { opacity: 0,    duration: 0.80, ease: 'power2.in' })
          .to(g, { duration: glowDuration - 1.10 });
        glowTweens.current.push(gtl);
      });
    };

    const tl = gsap.timeline({
      scrollTrigger: { trigger: container, start: 'top 88%', toggleActions: 'play none none none' },
      onComplete: startGlow,
    });

    tl.to(lines, { strokeDashoffset: 0, duration: 0.75, ease: 'power2.inOut', stagger: 0.09 })
      .to(dots,  { opacity: 1, duration: 0.3, stagger: 0.09 }, '<0.35');

    return () => {
      glowTweens.current.forEach(tw => tw.kill());
      glowTweens.current = [];
      if (tl.scrollTrigger) tl.scrollTrigger.kill();
      tl.kill();
    };
  }, []);

  return (
    <div ref={containerRef} className="radial-diagram-wrap" style={{
      height: 640,
      position: 'relative',
      background: 'var(--color-surface)',
    }}>
      <svg
        viewBox="0 0 740 630"
        width="100%"
        height="100%"
        aria-hidden="true"
        style={{ display: 'block' }}
      >
        <defs>
          {/* Glow filter for endpoint dots — circles have proper bounding boxes, so feGaussianBlur works */}
          <filter id="dot-glow" x="-150%" y="-150%" width="400%" height="400%">
            <feGaussianBlur stdDeviation="1.5" result="blur" />
            <feMerge><feMergeNode in="blur" /></feMerge>
          </filter>
        </defs>

        {/* Center ring */}
        <circle cx={RD_CX} cy={RD_CY} r={74} fill="none" stroke="#D0CBC3" strokeWidth="1" />

        {/* Spokes — from ring edge to endpoint */}
        {RD_SPOKES.map((s, i) => {
          const ep  = rdEndpoint(s.angle);
          const inn = rdInner(s.angle);
          return (
            <g key={i}>
              {/* Base spoke line */}
              <line
                ref={el => lineRefs.current[i] = el}
                x1={inn.x} y1={inn.y}
                x2={ep.x}  y2={ep.y}
                stroke="#C2BBB4"
                strokeWidth="1.5"
                strokeLinecap="round"
              />
              {/* Glow halo — blurred circle behind the dot */}
              <circle
                ref={el => glowRefs.current[i] = el}
                cx={ep.x} cy={ep.y} r="13"
                fill="#FF2020"
                filter="url(#dot-glow)"
              />
              {/* Endpoint dot — main, crisp */}
              <circle
                ref={el => dotRefs.current[i] = el}
                cx={ep.x} cy={ep.y} r="5.5"
                fill="#E31E24"
              />
              {/* Label */}
              <text
                x={s.lx} y={s.ly}
                textAnchor={s.ta}
                style={{
                  fontFamily: 'Inter, system-ui, sans-serif',
                  fontSize: '11px', fontWeight: '600',
                  fill: '#4A4540', letterSpacing: '0.7px',
                  textTransform: 'uppercase',
                }}
              >{s.label}</text>
            </g>
          );
        })}

        {/* Velora ignition star — centered at (370, 315) */}
        <g transform="translate(335,283) scale(0.1656)">
          <path fill="#E31E24" d={VELORA_STAR_PATH} />
        </g>
      </svg>

      <style>{`
        @media (max-width: 768px) { .radial-diagram-wrap { height: 360px !important; } }
      `}</style>
    </div>
  );
}

/* ============================================================
   4. SISTEMA
   ============================================================ */

function Sistema() {

  const pillars = [
  {
    title: 'Estrategia antes de ejecución',
    body: 'Mapeamos tu modelo de negocio, arquitectura de marca y modelo de datos antes de producir un solo activo. Sin brief estratégico, no hay logo. Sin modelo de datos, no hay campaña.'
  },
  {
    title: '22 agentes, un solo frente',
    body: 'Nuestro sistema Velora opera en paralelo: brand, performance, BI y CRM al mismo tiempo. Tú hablas con un estratega; 22 flujos de trabajo se ejecutan simultáneamente.'
  },
  {
    title: 'Activos que permanecen',
    body: 'Construimos estándares, no entregables. Brand guidelines, modelos entrenados en tu marca, dashboards y playbooks que siguen generando valor cuando terminamos.'
  }];


  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 0,
      paddingBottom: 'var(--spacing-section)'
    }}>
      {/* Diagrama — full container width */}
      <div className="container">
        <div style={{ width: '100%' }}>
          <RadialDiagram />
        </div>
      </div>

      {/* Textos debajo del diagrama */}
      <div className="container" style={{ marginTop: 'clamp(48px, 6vw, 80px)' }}>
        <FadeUp>
          <p style={{
            fontFamily: 'var(--font-playfair)', fontStyle: 'italic',
            fontSize: 22, color: 'var(--color-text-secondary)',
            margin: '0 0 48px', maxWidth: 560
          }}>
            «Sistema que trabaja mientras tú atiendes lo que te necesita.»
          </p>
        </FadeUp>

        <div className="sistema-pillars" style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gap: 0
        }}>
          {pillars.map((p, i) =>
          <FadeUp key={i} delay={i * 0.1}>
            <div className="sistema-item" style={{
              borderTop: '1px solid var(--color-border)',
              paddingTop: 28, paddingBottom: 28,
              paddingRight: i < 2 ? 40 : 0
            }}>
              <div style={{
                fontFamily: 'var(--font-inter)', fontWeight: 700, fontSize: 17,
                color: 'var(--color-text-primary)', letterSpacing: '-0.2px',
                marginBottom: 10
              }}>{p.title}</div>
              <div style={{
                fontFamily: 'var(--font-arimo)', fontWeight: 400, fontSize: 16,
                color: 'var(--color-text-secondary)', lineHeight: 1.7
              }}>{p.body}</div>
            </div>
          </FadeUp>
          )}
        </div>
        <div style={{ borderBottom: '1px solid var(--color-border)' }} />
      </div>

      <style>{`
        @media (max-width: 860px) {
          .sistema-pillars { grid-template-columns: 1fr !important; }
          .sistema-item { padding-right: 0 !important; }
        }
      `}</style>
    </section>);

}

/* ============================================================
   5. SERVICIOS
   ============================================================ */

function Servicios() {
  const services = [
  {
    name: 'DIAGNÓSTICO',
    keywords: ['Análisis estratégico de tu marca en 5 días. El punto de partida antes de cualquier proyecto.'],
    price: '$9,900 MXN · precio fijo',
    tiempo: '5 días hábiles',
    ideal: 'Para negocios que quieren entender su situación real antes de invertir en un proyecto mayor.',
    includes: [
      'PDF de diagnóstico estratégico de 12–15 páginas',
      'Análisis de marca actual: fortalezas y brechas',
      'Benchmark de 3 competidores directos',
      'Propuesta de posicionamiento diferenciador',
      'Recomendación de siguiente paso con justificación',
      'Los $9,900 se descuentan si avanzas a BRAND o LAUNCH en 30 días',
    ]
  },
  {
    name: 'BRAND',
    keywords: ['Identidad de marca que hace que todo lo demás tenga coherencia'],
    price: 'desde $18,000 MXN',
    tiempo: '3–4 semanas',
    ideal: 'Para negocios con producto o servicio claro que necesitan una identidad que comunique lo que realmente son.',
    includes: [
      'Brand Strategy + Dirección Creativa',
      'Logo, Paleta de Color, Tipografía e Iconografía',
      'Manual de Identidad (Brand Guidelines PDF)',
      'Aplicaciones en piezas clave (presentaciones, redes, documentos)',
      'Opcionalmente: Landing Page',
    ]
  },
  {
    name: 'LAUNCH',
    keywords: ['De cero a primer cliente en 90 días. Sistema que crece desde el inicio.'],
    price: 'desde $38,000 MXN',
    tiempo: '3–4 semanas',
    ideal: 'Para founders y negocios listos para activar su sistema de captación digital desde el inicio.',
    includes: [
      'Landing Page de conversión',
      'Configuración de métricas y análisis de datos',
      'Arquitectura de campañas de publicidad digital lista para activar',
      'Opcionalmente: Brand Kit + gestión del primer mes de ads',
      'Reporte de lanzamiento a 30 días',
    ]
  },
  {
    name: 'SCALE',
    keywords: ['Continuar creciendo con un sistema que funciona sin perder margen ni identidad.'],
    price: 'desde $25,000 MXN / mes',
    tiempo: ['Inicio en 1–2 semanas', 'Mínimo 3 meses de gestión'],
    ideal: 'Para negocios con presencia digital que quieren crecer de forma sostenida sin perder el control.',
    includes: [
      'Estrategia de Contenido Mensual + Calendario Editorial',
      'Producción y publicación en 2–3 redes sociales',
      'Gestión de Paid Media (Meta Ads y/o Google Ads)',
      'Reporte mensual con métricas y optimización continua',
      'La pauta publicitaria va aparte — tú la controlas directamente',
    ]
  },
  {
    name: 'ECOSYSTEM',
    keywords: ['Control de tus marcas, para que todo tu sistema hable el mismo idioma.'],
    price: 'desde $38,000 MXN',
    tiempo: '4–6 semanas de implementación',
    ideal: 'Para empresas medianas con herramientas desconectadas que necesitan un solo sistema integrado.',
    includes: [
      'Diagnóstico de sistemas y herramientas actuales',
      'Integración de CRM + automatizaciones',
      'Dashboards conectados a tus fuentes de datos',
      'Flujos comerciales optimizados (onboarding, seguimiento, reportes)',
      'Gestión mensual del ecosistema disponible post-implementación',
    ]
  },
  {
    name: 'TECH',
    keywords: ['Infraestructura que facilita tu operación para que te enfoques en lo que importa.'],
    price: 'desde $30,000 MXN',
    tiempo: 'Desde 8 semanas (primer entregable)',
    ideal: 'Para negocios que necesitan una solución digital propia — no un template adaptado.',
    includes: [
      'Diseño completo de la solución antes de escribir una sola línea de código',
      'Desarrollo por etapas con entregables visibles cada 2 semanas',
      'Tu producto lanzado, documentado y con todos los accesos transferidos',
      'Tecnología elegida según las necesidades reales de tu negocio',
      'Soporte y mantenimiento disponible después del lanzamiento',
    ]
  }];


  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 0,
      paddingBottom: 'var(--spacing-section)'
    }}>
      <div className="container">

        {(() => {
          const [openIndex, setOpenIndex] = useState(null);
          const toggle = (i) => setOpenIndex(prev => prev === i ? null : i);
          return (
            <div>
              {services.map((s, i) =>
                <ServiceRow key={s.name} {...s} index={i} open={openIndex === i} onToggle={() => toggle(i)} />
              )}
              <div style={{ borderBottom: '1px solid var(--color-border)' }} />
            </div>
          );
        })()}

        <div style={{
          fontFamily: 'var(--font-arimo)', fontWeight: 400, fontSize: 14,
          color: 'var(--color-text-tertiary)',
          marginTop: 40,
          maxWidth: 640
        }}>
          ¿No sabes por cuál empezar?{' '}
          <a href="#contacto" onClick={(e) => {e.preventDefault();document.getElementById('contacto')?.scrollIntoView({ behavior: 'smooth' });}}
          style={{ color: 'var(--color-accent)', textDecoration: 'underline', textUnderlineOffset: 3 }}>
            Agenda una llamada de 45 minutos
          </a>{' '}y te orientamos sin costo.
        </div>
      </div>
    </section>);

}

function ServiceRow({ name, keywords, price, tiempo, ideal, includes, open, onToggle }) {
  const [hover, setHover] = useState(false);

  const scrollToContact = (e) => {
    e.stopPropagation();
    document.getElementById('contacto')?.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <div className="service-row-wrap" style={{ borderTop: '1px solid var(--color-border)' }}>
      {/* Header row — clickable to toggle */}
      <div
        onClick={onToggle}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
        style={{
          display: 'grid',
          gridTemplateColumns: 'auto 1fr auto auto',
          alignItems: 'center',
          gap: 32,
          paddingTop: 28, paddingBottom: open ? 16 : 28,
          cursor: 'pointer',
          userSelect: 'none',
        }}
        className="service-grid"
      >
        <div style={{ display: 'flex', alignItems: 'center' }}>
          <span style={{
            fontFamily: 'var(--font-inter)', fontWeight: 700,
            fontSize: 'clamp(20px, 2.5vw, 28px)',
            color: open || hover ? 'var(--color-accent)' : 'var(--color-text-primary)',
            transition: 'color 150ms ease-out'
          }}>{name}</span>
        </div>

        <div className="service-keywords" style={{
          fontFamily: 'var(--font-arimo)', fontWeight: 400, fontSize: 17,
          color: 'var(--color-text-secondary)', textAlign: 'left', lineHeight: 1.5
        }}>
          {keywords.join(' · ')}
        </div>

        {price &&
          <div className="service-price" style={{
            fontFamily: 'var(--font-inter)', fontWeight: 500, fontSize: 13,
            color: 'var(--color-text-tertiary)', whiteSpace: 'nowrap'
          }}>{price}</div>
        }

        <div style={{
          fontFamily: 'var(--font-inter)', fontWeight: 400, fontSize: 20,
          color: 'var(--color-accent)',
          transform: open ? 'rotate(45deg)' : 'rotate(0deg)',
          transition: 'transform 220ms var(--ease-emil)',
          width: 24, textAlign: 'center', lineHeight: 1,
        }}>+</div>
      </div>

      {/* Expandable panel */}
      <div style={{
        overflow: 'hidden',
        maxHeight: open ? '600px' : '0px',
        transition: 'max-height 380ms var(--ease-emil)',
      }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1fr 1fr',
          gap: '24px 48px',
          paddingBottom: 36,
          paddingTop: 4,
        }} className="service-detail-grid">
          {/* Left — includes */}
          <div>
            <div style={{
              fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
              textTransform: 'uppercase', letterSpacing: '1px',
              color: 'var(--color-text-tertiary)', marginBottom: 14
            }}>Qué incluye</div>
            <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
              {(includes || []).map((item, i) => (
                <li key={i} style={{
                  fontFamily: 'var(--font-arimo)', fontSize: 15,
                  color: 'var(--color-text-secondary)', lineHeight: 1.6,
                  paddingBottom: 8, display: 'flex', gap: 10, alignItems: 'flex-start'
                }}>
                  <span style={{ color: 'var(--color-accent)', marginTop: 2, flexShrink: 0 }}>—</span>
                  {item}
                </li>
              ))}
            </ul>
          </div>

          {/* Right — tiempo + ideal + CTA */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            {tiempo && (
              <div>
                <div style={{
                  fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
                  textTransform: 'uppercase', letterSpacing: '1px',
                  color: 'var(--color-text-tertiary)', marginBottom: 6
                }}>Tiempo de entrega</div>
                {Array.isArray(tiempo)
                  ? tiempo.map((t, i) => (
                    <div key={i} style={{
                      fontFamily: 'var(--font-arimo)', fontSize: 15,
                      color: i === 0 ? 'var(--color-text-secondary)' : 'var(--color-text-tertiary)',
                      marginTop: i > 0 ? 4 : 0,
                      fontStyle: i > 0 ? 'italic' : 'normal'
                    }}>{t}</div>
                  ))
                  : <div style={{ fontFamily: 'var(--font-arimo)', fontSize: 15, color: 'var(--color-text-secondary)' }}>{tiempo}</div>
                }
              </div>
            )}
            {ideal && (
              <div>
                <div style={{
                  fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
                  textTransform: 'uppercase', letterSpacing: '1px',
                  color: 'var(--color-text-tertiary)', marginBottom: 6
                }}>Ideal para</div>
                <div style={{
                  fontFamily: 'var(--font-arimo)', fontSize: 15,
                  color: 'var(--color-text-secondary)', lineHeight: 1.6
                }}>{ideal}</div>
              </div>
            )}
            <button
              onClick={scrollToContact}
              style={{
                marginTop: 'auto',
                background: 'var(--color-accent)',
                color: '#fff',
                fontFamily: 'var(--font-inter)', fontWeight: 700,
                fontSize: 13, textTransform: 'uppercase', letterSpacing: '0.8px',
                border: 'none', borderRadius: 'var(--radius-button)',
                padding: '14px 28px', cursor: 'pointer',
                transition: 'background 150ms ease-out',
                alignSelf: 'flex-start',
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--color-accent-hover)'}
              onMouseLeave={e => e.currentTarget.style.background = 'var(--color-accent)'}
            >
              Quiero este paquete →
            </button>
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 720px) {
          .service-grid { grid-template-columns: 1fr auto !important; row-gap: 10px !important; }
          .service-keywords { grid-column: 1 / -1; }
          .service-price { display: none !important; }
          .service-detail-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </div>
  );
}

/* ============================================================
   6. PROCESO
   ============================================================ */

function Proceso() {
  const steps = [
  { n: '01', title: 'Diagnóstico', body: 'Sesión de 45 min con dirección. Mapeamos marca, datos, stack y agencias. Te decimos en qué orden mover qué piezas.' },
  { n: '02', title: 'Diseño', body: 'En 4 semanas construimos tu sistema completo: identidad, presencia digital y las herramientas que lo hacen funcionar. Todo documentado para que tú siempre tengas el control.' },
  { n: '03', title: 'Despliegue', body: 'Activamos todo lo que construimos: campañas, métricas, presencia digital y las herramientas de tu operación. Te entregamos con capacitación completa y todo documentado para que tu equipo opere desde el primer día.' },
  { n: '04', title: 'Dirección', body: 'Revisión mensual. Una sola junta, un solo reporte, un solo responsable. Sin coordinar entre múltiples proveedores — Velora responde por todo.' }];


  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 0,
      paddingBottom: 'var(--spacing-section)'
    }}>
      <div className="container">
        <div className="proceso-row" style={{
          position: 'relative',
          display: 'grid',
          gridTemplateColumns: 'repeat(4, 1fr)',
          gap: 40
        }}>
          {/* connector line */}
          <div className="proceso-line" style={{
            position: 'absolute',
            top: 16, left: 'calc((100% / 8))', right: 'calc((100% / 8))',
            borderTop: '1px solid var(--color-border)',
            zIndex: 0
          }} />
          {steps.map((s, i) => <ProcessStep key={s.n} step={s} index={i} />)}
        </div>
      </div>

      <style>{`
        @media (max-width: 880px) {
          .proceso-row { grid-template-columns: 1fr !important; }
          .proceso-line { display: none; }
        }
      `}</style>
    </section>);

}

function ProcessStep({ step, index }) {
  const [hover, setHover] = useState(false);
  return (
    <div className="proceso-step"
    onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
    style={{ position: 'relative', zIndex: 1 }}>
      <div style={{
        width: 32, height: 32,
        border: `1px solid ${hover ? 'var(--color-accent)' : 'var(--color-border)'}`,
        borderRadius: '50%',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: 'var(--color-surface)',
        transition: 'border-color 150ms ease-out'
      }}>
        <span style={{
          fontFamily: 'var(--font-inter)', fontWeight: 500, fontSize: 14,
          color: hover ? 'var(--color-accent)' : 'var(--color-text-tertiary)',
          transition: 'color 150ms ease-out'
        }}>{step.n}</span>
      </div>
      <div style={{
        fontFamily: 'var(--font-inter)', fontSize: 18,
        color: 'var(--color-text-primary)', marginTop: 20, fontWeight: "700"
      }}>{step.title}</div>
      <div style={{
        fontFamily: 'var(--font-arimo)', fontWeight: 400, fontSize: 15,
        color: 'var(--color-text-secondary)', lineHeight: 1.65, marginTop: 8
      }}>{step.body}</div>
    </div>);

}

/* ============================================================
   8. MARQUEE
   ============================================================ */

function Marquee({ speed = 12 }) {
  const phrases = [
    'Construye el sistema',
    'Ejecuta más',
    'Coordina menos',
  ];
  // Repeat the cycle enough times so the line is always wider than any viewport
  const cycle = phrases.join('  ·  ') + '  ·  ';
  const line = cycle.repeat(8);

  const textStyle = {
    fontFamily: 'var(--font-inter)', fontWeight: 700,
    fontSize: 'clamp(48px, 6vw, 80px)',
    color: 'var(--color-text-primary)',
    lineHeight: 1, letterSpacing: '-1px',
    whiteSpace: 'nowrap',
    flexShrink: 0,
  };

  return (
    <section style={{
      background: 'var(--color-surface)',
      paddingTop: 64, paddingBottom: 64,
      overflow: 'hidden',
    }}>
      {/* width: max-content makes -50% translate = exactly one copy width */}
      <div style={{
        display: 'flex',
        width: 'max-content',
        animation: `marquee ${speed}s linear infinite`,
        willChange: 'transform',
      }}>
        <div style={textStyle}>{line}</div>
        <div style={textStyle} aria-hidden="true">{line}</div>
      </div>
    </section>);

}

/* ============================================================
   9. CONTACTO
   ============================================================ */

function Contacto({ pushToast }) {
  const [form, setForm] = useState({ nombre: '', email: '', empresa: '', servicio: '', mensaje: '' });
  const [errors, setErrors] = useState({});
  const [status, setStatus] = useState('idle'); // idle | loading | success
  const h2Ref = useRef(null);

  useEffect(() => {
    const el = h2Ref.current;
    if (!el || !window.gsap || !window.ScrollTrigger) return;
    const inners = el.querySelectorAll('.contacto-line-inner');
    window.gsap.set(inners, { yPercent: 115 });
    window.gsap.to(inners, {
      yPercent: 0, duration: 1.3, ease: 'power3.out', stagger: 0.16,
      scrollTrigger: { trigger: el, start: 'top 88%', toggleActions: 'play none none none' },
    });
  }, []);

  const set = (k) => (e) => setForm((p) => ({ ...p, [k]: e.target.value }));

  const validate = () => {
    const errs = {};
    if (!form.nombre.trim()) errs.nombre = 'Ingresa tu nombre.';
    if (!form.email.trim()) errs.email = 'Ingresa tu email.';else
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) errs.email = 'Email inválido.';
    if (!form.servicio) errs.servicio = 'Selecciona un servicio.';
    return errs;
  };

  const submit = (e) => {
    e.preventDefault();
    const errs = validate();
    setErrors(errs);
    if (Object.keys(errs).length) return;
    setStatus('loading');
    setTimeout(() => {
      setStatus('success');
      pushToast('Mensaje recibido — te contactamos en menos de 24h.');
      setForm({ nombre: '', email: '', empresa: '', servicio: '', mensaje: '' });
      setTimeout(() => setStatus('idle'), 1200);
    }, 1100);
  };

  const inputBase = {
    width: '100%',
    background: 'rgba(26,23,20,0.03)',
    border: '1px solid var(--color-border)',
    borderRadius: 'var(--radius-input)',
    padding: '12px 14px',
    color: 'var(--color-text-primary)',
    fontFamily: 'var(--font-arimo)',
    fontSize: 15,
    transition: 'border-color 150ms ease-out'
  };

  const labelBase = {
    display: 'block',
    fontFamily: 'var(--font-arimo)', fontWeight: 700, fontSize: 11,
    textTransform: 'uppercase', letterSpacing: '0.8px',
    color: 'var(--color-text-tertiary)',
    marginBottom: 6
  };

  return (
    <section id="contacto" style={{
      background: 'var(--color-surface)',
      paddingTop: 'var(--spacing-section)',
      paddingBottom: 'var(--spacing-section)'
    }}>
      <div className="container">
        <div className="contacto-grid" style={{
          display: 'grid',
          gridTemplateColumns: '45fr 55fr',
          gap: 80
        }}>
          <div>
            <div style={{
              fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
              textTransform: 'uppercase', letterSpacing: '1.2px',
              color: 'var(--color-accent)', marginBottom: 16
            }}>
              Vamos a operar
            </div>
            <h2 ref={h2Ref} style={{
              fontFamily: 'var(--font-inter)', fontWeight: 700,
              fontSize: 'clamp(36px, 4vw, 56px)',
              color: 'var(--color-text-primary)',
              margin: 0, lineHeight: 1.05, letterSpacing: '-0.5px'
            }}>
              {['Agenda una llamada.', 'En 45 minutos sabemos exactamente qué mover primero.'].map((line, i) => (
                <div key={i} style={{ overflow: 'hidden', paddingBottom: '0.22em' }}>
                  <span className="contacto-line-inner" style={{ display: 'block' }}>{line}</span>
                </div>
              ))}
            </h2>
            <button onClick={() => pushToast('Abriría Cal.com popup · velora-studio-nrvneg')}
            style={{
              marginTop: 20,
              fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 13,
              textTransform: 'uppercase', letterSpacing: '0.5px',
              border: '1px solid var(--color-border)',
              color: 'var(--color-text-primary)',
              padding: '12px 24px', borderRadius: 'var(--radius-button)',
              transition: 'border-color 150ms ease-out, color 150ms ease-out',
              display: 'inline-block'
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.borderColor = 'var(--color-accent)';
              e.currentTarget.style.color = 'var(--color-accent)';
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.borderColor = 'var(--color-border)';
              e.currentTarget.style.color = 'var(--color-text-primary)';
            }}>
              ELIGE TU HORARIO DIRECTO →
            </button>
            <p style={{
              fontFamily: 'var(--font-arimo)', fontSize: 16,
              color: 'var(--color-text-secondary)', marginTop: 20, lineHeight: 1.65
            }}>
              O llena el formulario y te escribimos para confirmar fecha y hora — generalmente el mismo día.
            </p>

            <div style={{
              fontFamily: 'var(--font-arimo)', fontSize: 13,
              color: 'var(--color-text-tertiary)', marginTop: 32, lineHeight: 1.7
            }}>
              hola@velorastudio.com.mx<br />
              CDMX · QUERETARO · LATAM
            </div>
          </div>

          <form onSubmit={submit} noValidate style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <div className="form-row-2">
              <div>
                <label style={labelBase} htmlFor="f-nombre">Nombre *</label>
                <input id="f-nombre" className="v-input" style={inputBase}
                type="text" value={form.nombre} onChange={set('nombre')}
                placeholder="Cómo te llamas" />
                {errors.nombre && <FormError msg={errors.nombre} />}
              </div>
              <div>
                <label style={labelBase} htmlFor="f-email">Email *</label>
                <input id="f-email" className="v-input" style={inputBase}
                type="email" value={form.email} onChange={set('email')}
                placeholder="tu@empresa.com" />
                {errors.email && <FormError msg={errors.email} />}
              </div>
            </div>

            <div className="form-row-2">
              <div>
                <label style={labelBase} htmlFor="f-empresa">Empresa</label>
                <input id="f-empresa" className="v-input" style={inputBase}
                type="text" value={form.empresa} onChange={set('empresa')}
                placeholder="Opcional" />
              </div>
              <div>
                <label style={labelBase} htmlFor="f-servicio">Servicio *</label>
                <select id="f-servicio" className="v-select" style={{ ...inputBase, appearance: 'none', paddingRight: 38, backgroundImage: 'linear-gradient(45deg, transparent 50%, rgba(246,248,247,0.5) 50%), linear-gradient(135deg, rgba(246,248,247,0.5) 50%, transparent 50%)', backgroundPosition: 'calc(100% - 18px) 50%, calc(100% - 13px) 50%', backgroundSize: '5px 5px', backgroundRepeat: 'no-repeat' }}
                value={form.servicio} onChange={set('servicio')}>
                  <option value="" style={{ color: '#1A1714' }}>Elige una opción</option>
                  <option value="BRAND" style={{ color: '#1A1714' }}>BRAND</option>
                  <option value="LAUNCH" style={{ color: '#1A1714' }}>LAUNCH</option>
                  <option value="SCALE" style={{ color: '#1A1714' }}>SCALE</option>
                  <option value="ECOSYSTEM" style={{ color: '#1A1714' }}>ECOSYSTEM</option>
                  <option value="TECH" style={{ color: '#1A1714' }}>TECH</option>
                  <option value="NO_SE" style={{ color: '#1A1714' }}>No sé aún</option>
                </select>
                {errors.servicio && <FormError msg={errors.servicio} />}
              </div>
            </div>

            <div>
              <label style={labelBase} htmlFor="f-mensaje">Mensaje</label>
              <textarea id="f-mensaje" className="v-textarea"
              style={{ ...inputBase, height: 120, resize: 'none', fontFamily: 'var(--font-arimo)' }}
              maxLength={500}
              value={form.mensaje} onChange={set('mensaje')}
              placeholder="Cuéntanos dónde estás atascado. Una frase basta." />
              <div style={{
                fontFamily: 'var(--font-arimo)', fontSize: 11,
                color: 'var(--color-text-tertiary)', marginTop: 6, textAlign: 'right'
              }}>{form.mensaje.length}/500</div>
            </div>

            <button type="submit" disabled={status !== 'idle'}
            style={{
              fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 15,
              textTransform: 'uppercase', letterSpacing: '0.5px',
              background: status === 'success' ? 'var(--color-support)' : 'var(--color-accent)',
              color: '#fff',
              padding: 16, width: '100%',
              borderRadius: 'var(--radius-button)',
              transition: 'background 150ms ease-out',
              opacity: status === 'loading' ? 0.9 : 1,
              cursor: status === 'idle' ? 'pointer' : 'default'
            }}
            onMouseEnter={(e) => {if (status === 'idle') e.currentTarget.style.background = 'var(--color-accent-hover)';}}
            onMouseLeave={(e) => {if (status === 'idle') e.currentTarget.style.background = 'var(--color-accent)';}}>
              {status === 'idle' && 'QUIERO MI DIAGNÓSTICO'}
              {status === 'loading' &&
              <span>ENVIANDO<span className="loading-dot">.</span><span className="loading-dot">.</span><span className="loading-dot">.</span></span>
              }
              {status === 'success' && 'ENVIADO ✓'}
            </button>

            <div style={{
              fontFamily: 'var(--font-arimo)', fontSize: 12,
              color: 'var(--color-text-tertiary)', lineHeight: 1.6
            }}>
              Al enviar aceptas que respondamos por email. Sin newsletter, sin secuencia de nurturing, sin sales bots.
            </div>
          </form>
        </div>
      </div>

      <style>{`
        .form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
        @media (max-width: 880px) {
          .contacto-grid { grid-template-columns: 1fr !important; gap: 48px !important; }
          .form-row-2 { grid-template-columns: 1fr !important; }
        }
        .v-input::placeholder, .v-textarea::placeholder { color: rgba(26,23,20,0.30); }
        .v-select option { background: var(--color-surface); }
      `}</style>
    </section>);

}

function FormError({ msg }) {
  return (
    <div style={{
      fontFamily: 'var(--font-arimo)', fontSize: 12,
      color: 'var(--color-accent)', marginTop: 6
    }}>{msg}</div>);

}

/* ============================================================
   10. FOOTER
   ============================================================ */

function Footer() {
  return (
    <footer style={{
      background: 'var(--color-surface)',
      borderTop: '1px solid var(--color-border)',
      paddingTop: 64, paddingBottom: 48
    }}>
      <div className="container">
        <div className="footer-grid" style={{
          display: 'grid',
          gridTemplateColumns: '2fr 1fr 1fr 1fr',
          gap: 48, alignItems: 'start'
        }}>
          <div>
            <img src={LOGO_SRC} alt="Velora Studio"
            className="logo-wordmark logo-wordmark--lg" />
            <div style={{
              fontFamily: 'var(--font-playfair)', fontStyle: 'italic',
              fontSize: 18, color: 'var(--color-text-secondary)',
              marginTop: 12, maxWidth: 380, lineHeight: 1.45
            }}>
              Sistema que trabaja mientras tú atiendes lo que te necesita.
            </div>
          </div>

          <FooterColumn title="Servicios" links={[
          { label: 'BRAND',     href: '#servicios' },
          { label: 'LAUNCH',    href: '#servicios' },
          { label: 'SCALE',     href: '#servicios' },
          { label: 'ECOSYSTEM', href: '#servicios' },
          { label: 'TECH',      href: '#servicios' },
          ]} />
          <FooterColumn title="Navegación" links={[
          { label: 'Nosotros',  href: '#nosotros' },
          { label: 'Sistema', href: '#sistema' },
          { label: 'Servicios', href: '#servicios' },
          { label: 'Proceso',   href: '#proceso'   },
          { label: 'Contacto',  href: '#contacto'  },
          ]} />
          <FooterColumn title="Contacto" links={[
          { label: 'hola@velorastudio.com.mx', href: 'mailto:hola@velorastudio.com.mx' },
          { label: 'Agenda una llamada',        href: '#contacto' },
          { label: 'LinkedIn',  href: 'https://www.linkedin.com/company/velora-studio-mx', external: true },
          { label: 'Instagram', href: 'https://www.instagram.com/studioveloramx/',        external: true },
          ]} />
        </div>

        <div style={{
          marginTop: 64,
          display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 16,
          paddingTop: 32, borderTop: '1px solid var(--color-border)'
        }}>
          <div style={{
            fontFamily: 'var(--font-arimo)', fontSize: 12,
            color: 'rgba(26,23,20,0.35)'
          }}>
            © 2026 Velora Studio
          </div>
          <div style={{
            fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 10,
            color: 'rgba(26,23,20,0.22)', letterSpacing: '1px',
            textTransform: 'uppercase'
          }}>
            Sistema que trabaja mientras tú atiendes lo que te necesita.
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 880px) {
          .footer-grid { grid-template-columns: 1fr 1fr !important; }
        }
        @media (max-width: 560px) {
          .footer-grid { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </footer>);

}

function FooterColumn({ title, links }) {
  const handleClick = (link, e) => {
    if (link.external) return; // let it open normally
    e.preventDefault();
    if (link.href && link.href.startsWith('#')) {
      const id = link.href.slice(1);
      const el = document.getElementById(id);
      if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    } else if (link.href && link.href.startsWith('mailto:')) {
      window.location.href = link.href;
    }
  };

  return (
    <div>
      <div style={{
        fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
        textTransform: 'uppercase', letterSpacing: '1.2px',
        color: 'var(--color-text-tertiary)',
        marginBottom: 18
      }}>{title}</div>
      <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
        {links.map((l) =>
        <li key={l.label}>
            <a
            href={l.href}
            target={l.external ? '_blank' : undefined}
            rel={l.external ? 'noopener noreferrer' : undefined}
            onClick={(e) => handleClick(l, e)}
            className="footer-link"
            style={{
              fontFamily: 'var(--font-arimo)', fontSize: 14,
              color: 'var(--color-text-secondary)',
              transition: 'color 150ms ease-out'
            }}>{l.label}</a>
          </li>
        )}
      </ul>
      <style>{`.footer-link:hover { color: var(--color-text-primary) !important; }`}</style>
    </div>);

}

/* ============================================================
   Toast container
   ============================================================ */

function ToastHost({ toasts }) {
  return (
    <div style={{
      position: 'fixed', bottom: 20, right: 20, zIndex: 80,
      display: 'flex', flexDirection: 'column', gap: 10,
      pointerEvents: 'none'
    }}>
      {toasts.map((t) =>
      <div key={t.id} style={{
        background: 'var(--color-surface)',
        borderLeft: '3px solid var(--color-accent)',
        color: 'var(--color-text-primary)',
        fontFamily: 'var(--font-inter)', fontWeight: 500, fontSize: 14,
        padding: '14px 18px',
        minWidth: 280, maxWidth: 380,
        borderRadius: 'var(--radius-button)',
        boxShadow: '0 8px 24px rgba(26,23,20,0.18)',
        animation: 'toast-in 280ms var(--ease-emil) both',
        pointerEvents: 'auto'
      }}>{t.message}</div>
      )}
    </div>);

}

/* ============================================================
   SECTION TITLE — standalone h2 with curtain-reveal per line
   ============================================================ */

function SectionTitle({ id, label, lines, size = 'clamp(40px, 5.5vw, 76px)' }) {
  const ref = useRef(null);

  useEffect(() => {
    const el = ref.current;
    if (!el || !window.gsap || !window.ScrollTrigger) return;
    const inners = el.querySelectorAll('.st-line-inner');
    window.gsap.set(inners, { yPercent: 115 });
    window.gsap.to(inners, {
      yPercent: 0,
      duration: 1.3,
      ease: 'power3.out',
      stagger: 0.16,
      scrollTrigger: { trigger: el, start: 'top 88%', toggleActions: 'play none none none' },
    });
  }, []);

  return (
    <div ref={ref} id={id} style={{
      paddingTop: 'clamp(56px, 7vw, 96px)',
      paddingBottom: 'clamp(16px, 2vw, 28px)',
      background: 'var(--color-surface)',
    }}>
      <div className="container">
        {label && (
          <div style={{
            fontFamily: 'var(--font-inter)', fontWeight: 600, fontSize: 11,
            textTransform: 'uppercase', letterSpacing: '1.2px',
            color: 'var(--color-accent)', marginBottom: 20,
          }}>{label}</div>
        )}
        <h2 style={{ margin: 0, fontWeight: 800 }}>
          {lines.map((line, i) => (
            <div key={i} style={{ overflow: 'hidden', lineHeight: 1.05, paddingBottom: '0.22em' }}>
              <span className="st-line-inner" style={{
                display: 'block',
                fontFamily: 'var(--font-inter)', fontWeight: 800,
                fontSize: size,
                letterSpacing: '-2px',
                color: line.accent ? 'var(--color-accent)' : 'var(--color-text-primary)',
              }}>{line.text}</span>
            </div>
          ))}
        </h2>
      </div>
    </div>
  );
}

/* ============================================================
   FADE UP — scroll-triggered fade + slide for content blocks
   ============================================================ */

function FadeUp({ children, delay = 0, style: inlineStyle = {} }) {
  const ref = useRef(null);

  useEffect(() => {
    const el = ref.current;
    if (!el || !window.gsap || !window.ScrollTrigger) return;
    window.gsap.fromTo(el,
      { opacity: 0, y: 26 },
      {
        opacity: 1, y: 0,
        duration: 1.1,
        ease: 'power2.out',
        delay,
        scrollTrigger: { trigger: el, start: 'top 93%', toggleActions: 'play none none none' },
      }
    );
  }, []);

  return <div ref={ref} style={inlineStyle}>{children}</div>;
}

/* ============================================================
   EXPORTS
   ============================================================ */

Object.assign(window, {
  Navbar, Hero, Capacidades, Problema, Nosotros, Sistema, Servicios,
  Proceso, Marquee, Contacto, Footer,
  ToastHost, SectionTitle, FadeUp,
});