/* AORYN — sections (services, works, philosophy, tools) */

const { useState: useS2, useEffect: useE2, useRef: useR2 } = React;

// ============================================================================
// SERVICES — sticky stack with fade between cards
// ============================================================================
const SERVICES = [
{
  num: '01',
  title: 'Automatización & IA',
  lead: 'IA práctica y automatizaciones que conectan tus herramientas. Desde chatbots que cualifican leads hasta sistemas que generan facturas solos.',
  points: [
  ['Tiempo recuperado', 'Decenas de horas semanales en tareas administrativas.'],
  ['Atención 24/7', 'Chatbots que filtran clientes mientras duermes.'],
  ['Cero errores', 'Las automatizaciones no se cansan ni se equivocan.'],
  ['Reducción de costes', 'Menos horas humanas en tareas de bajo valor.']],

  visual: 'v4',
  label: 'AI · AUTOMATION',
  icon:
  <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="18" y="20" width="28" height="26" rx="4" />
        <circle cx="26" cy="32" r="2" fill="currentColor" />
        <circle cx="38" cy="32" r="2" fill="currentColor" />
        <path d="M28 38h8M32 14v6M14 30v6M50 30v6" opacity="0.6" />
      </svg>

},
{
  num: '02',
  title: 'Estrategia & Consultoría',
  lead: 'Auditoría operativa profunda. Detectamos cuellos de botella y trazamos una hoja de ruta secuencial para escalar sin romper nada.',
  points: [
  ['Claridad total', 'Entiende qué palancas mueven realmente tu facturación.'],
  ['Limpieza operativa', 'Eliminamos tareas y procesos sin valor.'],
  ['Hoja de ruta', 'Plan paso a paso, ejecutable desde la primera semana.'],
  ['Control financiero', 'Visibilidad real sobre márgenes y rentabilidad.']],

  visual: 'v1',
  label: 'STRATEGY',
  icon:
  <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5">
        <circle cx="32" cy="32" r="22" />
        <path d="M32 10v44M10 32h44" />
        <path d="M22 22l20 20M42 22L22 42" opacity="0.4" />
      </svg>

},
{
  num: '03',
  title: 'Diseño & Audiovisual',
  lead: 'Sistemas visuales y producción audiovisual pensados para explicar, convencer y vender. Lejos de tendencias artísticas vacías.',
  points: [
  ['Identidad funcional', 'Materiales gráficos que tu equipo comercial usará orgulloso.'],
  ['Vídeo estratégico', 'Piezas que explican tus servicios mejor que cualquier texto.'],
  ['Coherencia visual', 'Web, presentaciones y redes hablan el mismo idioma.'],
  ['Herramientas de venta', 'Dosieres y presentaciones diseñados para cerrar.']],

  visual: 'v2',
  label: 'BRAND · FILM',
  icon:
  <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="10" y="14" width="44" height="36" rx="3" />
        <circle cx="32" cy="32" r="8" />
        <path d="M14 22h6M44 22h6M14 42h6M44 42h6" opacity="0.5" />
      </svg>

},
{
  num: '04',
  title: 'Web & Aplicaciones',
  lead: 'Plataformas a medida optimizadas para conversión y velocidad. Sin plantillas pesadas. Tecnología moderna aplicada a problemas reales de negocio.',
  points: [
  ['Velocidad extrema', 'Carga al instante. Nadie espera más de 3 segundos.'],
  ['Autogestionable', 'No dependes de nosotros para cambiar una coma.'],
  ['Escalabilidad', 'Base sólida preparada para crecer cuando crezcas.'],
  ['SEO técnico', 'Estructura optimizada para que Google priorice tu contenido.']],

  visual: 'v3',
  label: 'WEB · APPS',
  icon:
  <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" strokeWidth="1.5">
        <rect x="8" y="12" width="48" height="34" rx="3" />
        <path d="M8 22h48" />
        <circle cx="14" cy="17" r="1.2" fill="currentColor" />
        <circle cx="19" cy="17" r="1.2" fill="currentColor" />
        <path d="M24 52h16M32 46v6" opacity="0.6" />
      </svg>

}];


function Services() {
  return (
    <section id="services" className="section-light" style={{ color: "rgb(0, 0, 0)", backgroundColor: "rgb(231, 231, 231)" }}>
      <div className="container">
        <div className="services-intro">
          <div>
            <div className="section-eyebrow reveal">
              <span className="num">01 —</span>
              <span>Servicios</span>
            </div>
            <h2 className="section-h reveal" style={{ '--reveal-delay': '100ms' }}>
              Pensados para acompañar procesos.{' '}
              <span className="muted">No para vender humo.</span>
            </h2>
          </div>
          <p className="reveal" style={{ '--reveal-delay': '200ms' }}>
            AORYN trabaja con negocios reales que quieren entender mejor lo que hacen,
            comunicarlo con claridad y evolucionar paso a paso. No hacemos branding
            desde cero ni vendemos soluciones cerradas.
          </p>
        </div>

        <div className="services-stack">
          {SERVICES.map((s, i) =>
          <article
            key={s.num}
            className="service-card reveal"
            style={{
              top: `${80 + i * 20}px`,
              zIndex: i + 1
            }}>
            
              <div className="num-tag">{s.num} / 04</div>
              <div>
                <h3>{s.title}</h3>
                <p className="lead">{s.lead}</p>
                <ul className="service-points">
                  {s.points.map(([t, d], k) =>
                <li key={k}>
                      <span><strong>{t}.</strong> {d}</span>
                    </li>
                )}
                </ul>
              </div>
              <div className={`service-visual ${s.visual}`}>
                <div className="vis-noise"></div>
                <div className="vis-symbol"></div>
                <div className="vis-label">{s.label}</div>
                <div className="vis-icon">{s.icon}</div>
              </div>
            </article>
          )}
        </div>
      </div>
    </section>);

}

// ============================================================================
// WORKS — horizontal scroll-snap
// ============================================================================
// Maps CMS store works → component shape; falls back to hardcoded list.
function getCmsWorks() {
  try {
    if (window.AORYN_CMS) {
      const pub = window.AORYN_CMS.getPublicWorks();
      if (pub && pub.length) {
        const ordered = [...pub].sort((a, b) => (b.featured ? 1 : 0) - (a.featured ? 1 : 0));
        return ordered.map(w => ({
          id: w.id,
          title: w.name,
          cat: w.category,
          year: w.deliveryDate ? new Date(w.deliveryDate).getFullYear().toString() : '',
          client: w.client,
          url: w.url,
          img: w.cover,
          hero: w.cover,
          desc: w.description,
          scope: [],
          challenge: w.challenge,
          solution: w.solution,
          result: w.result,
          gallery: w.gallery || [],
          testimonial: (w.testimonial && w.testimonial.quote) ? w.testimonial : null
        }));
      }
    }
  } catch (e) {}
  return WORKS;
}

const WORKS = [
{
  id: '1',
  title: 'Transformación Digital',
  cat: 'Estrategia',
  year: '2024',
  client: 'Cantabria Auto Group',
  url: 'cantabriaautogroup.com',
  img: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?q=80&w=1600',
  hero: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?q=80&w=2400',
  desc: 'Redefinimos la presencia digital de una empresa líder del sector automotriz, modernizando arquitectura, identidad visual y flujos comerciales.',
  scope: ['Estrategia digital', 'Identidad visual', 'Desarrollo web', 'SEO técnico'],
  challenge: 'Web obsoleta con tiempos de carga sobre 8s y una tasa de rebote del 78%. La marca estaba dispersa entre 4 sub-marcas sin sistema unificado.',
  solution: 'Auditoría operativa, sistema de diseño unificado, plataforma Next.js modular y panel de gestión interna para que el equipo pudiera actualizar contenido sin depender de nosotros.',
  result: '+300% conversiones · -68% tasa de rebote · LCP bajo 1.2s',
  gallery: [
  'https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=1400',
  'https://images.unsplash.com/photo-1551434678-e076c223a692?q=80&w=1400',
  'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=1400'],

  testimonial: {
    quote: 'AORYN no nos vendió humo. Nos preguntaron por nuestros números, los analizaron y nos enseñaron por qué nuestra web no convertía. Tres meses después tenemos un sistema que el equipo puede mantener.',
    author: 'María González',
    role: 'Directora de Marketing'
  }
},
{
  id: '2',
  title: 'Plataforma IA',
  cat: 'IA & Datos',
  year: '2024',
  client: 'NorthData Analytics',
  url: 'northdata.io',
  img: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=1600',
  hero: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=2400',
  desc: 'Sistema inteligente que optimiza procesos operativos mediante IA generativa integrada con flujos automatizados.',
  scope: ['Estrategia IA', 'Automatización n8n', 'Integración OpenAI', 'Dashboard a medida'],
  challenge: 'El equipo dedicaba 40+ horas semanales a clasificación manual de leads y respuestas tipo. Datos atrapados en hojas de cálculo.',
  solution: 'Pipeline n8n + OpenAI que cualifica leads en tiempo real, genera respuestas personalizadas y sincroniza con CRM. Panel propio para supervisar y entrenar el sistema.',
  result: '-70% tiempo operativo · 24/7 atención · 0 leads perdidos',
  gallery: [
  'https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=1400',
  'https://images.unsplash.com/photo-1526378722484-cc1ce15de142?q=80&w=1400'],

  testimonial: {
    quote: 'No esperábamos que una IA pudiera escribir con nuestro tono. AORYN entrenó el sistema con tres meses de emails reales y ahora responde mejor que la mitad de mi equipo.',
    author: 'Carlos Mendoza',
    role: 'CEO'
  }
},
{
  id: '3',
  title: 'Campaña Audiovisual 360°',
  cat: 'Audiovisual',
  year: '2023',
  client: 'Studio Verbena',
  url: 'verbena.studio',
  img: 'https://images.unsplash.com/photo-1492619375914-88005aa9e8fb?q=80&w=1600',
  hero: 'https://images.unsplash.com/photo-1492619375914-88005aa9e8fb?q=80&w=2400',
  desc: 'Storytelling visual para lanzamiento de producto innovador — pieza principal, cortes para redes y dosier comercial.',
  scope: ['Dirección creativa', 'Producción audiovisual', 'Edición y post', 'Diseño dosier'],
  challenge: 'Producto técnico difícil de explicar en 30 segundos. Stock visual de marca inexistente. Lanzamiento internacional con plazo de 8 semanas.',
  solution: 'Concepto narrativo en torno a un personaje. Rodaje 3 días, edición ágil con previews semanales y entregas multicanal (cine, redes verticales, sala de ventas).',
  result: '2M+ impresiones · 47% engagement vs. 12% benchmark',
  gallery: [
  'https://images.unsplash.com/photo-1485846234645-a62644f84728?q=80&w=1400',
  'https://images.unsplash.com/photo-1574717024653-61fd2cf4d44d?q=80&w=1400',
  'https://images.unsplash.com/photo-1500917293891-ef795e70e1f6?q=80&w=1400'],

  testimonial: {
    quote: 'Nos costaba explicar nuestro producto y AORYN lo hizo con un vídeo de 60 segundos. Lo seguimos usando 18 meses después.',
    author: 'Lucía Romero',
    role: 'Founder, Studio Verbena'
  }
},
{
  id: '4',
  title: 'Sistema Editorial Digital',
  cat: 'Web · Diseño',
  year: '2024',
  client: 'Revista Aire',
  url: 'aire.media',
  img: 'https://images.unsplash.com/photo-1517694712202-14dd9538aa97?q=80&w=1600',
  hero: 'https://images.unsplash.com/photo-1517694712202-14dd9538aa97?q=80&w=2400',
  desc: 'Identidad y plataforma editorial para medio cultural independiente con foco en lectura larga y archivo profundo.',
  scope: ['Identidad editorial', 'Diseño web', 'CMS a medida', 'Tipografía'],
  challenge: 'Modelo de suscripción frenado por una web heredada de WordPress con UX confuso. Equipo editorial necesitaba autonomía completa.',
  solution: 'Sistema de diseño editorial propio. CMS headless con previsualización en vivo. Tipografía variable optimizada para lectura prolongada.',
  result: '+180% suscriptores · sesiones de 8min+ · 0 dependencia técnica',
  gallery: [
  'https://images.unsplash.com/photo-1481627834876-b7833e8f5570?q=80&w=1400',
  'https://images.unsplash.com/photo-1455390582262-044cdead277a?q=80&w=1400'],

  testimonial: {
    quote: 'Por fin tenemos una web que respeta el oficio editorial. El equipo publica sin pedir permiso a nadie.',
    author: 'Andrés Ruiz',
    role: 'Editor jefe'
  }
},
{
  id: '5',
  title: 'Automatización Comercial',
  cat: 'Automatización',
  year: '2023',
  client: 'Norte Servicios',
  url: 'norteservicios.com',
  img: 'https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=1600',
  hero: 'https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=2400',
  desc: 'Pipeline automatizado que conecta CRM, facturación y soporte. Operación que antes ocupaba 3 personas, ahora 0.',
  scope: ['Auditoría de procesos', 'Automatización Make', 'Integración Stripe', 'Chatbot soporte'],
  challenge: 'Datos en 6 sistemas distintos. Errores diarios al pasar información. Equipo comercial saturado de tareas administrativas.',
  solution: 'Mapa de procesos, fuente única de verdad y orquestación con Make. Bot que resuelve el 80% de soporte L1 antes de que llegue al equipo.',
  result: '120h/semana recuperadas · -94% errores · ROI 4 meses',
  gallery: [
  'https://images.unsplash.com/photo-1556761175-5973dc0f32e7?q=80&w=1400',
  'https://images.unsplash.com/photo-1521791136064-7986c2920216?q=80&w=1400'],

  testimonial: {
    quote: 'Pensábamos que automatizar era despedir gente. AORYN nos demostró lo contrario: ahora el equipo vende, no rellena formularios.',
    author: 'Javier Pereda',
    role: 'Director General'
  }
}];


function Works() {
  const sectionRef = useR2(null);
  const trackRef = useR2(null);
  const progressRef = useR2(null);
  const canvasRef = useR2(null);
  const [selected, setSelected] = useS2(null);
  const [items, setItems] = useS2(() => getCmsWorks());

  // Live-sync with the shared CMS store (changes made in Admin reflect here)
  useE2(() => {
    if (!window.AORYN_CMS) return;
    return window.AORYN_CMS.onChange(() => setItems(getCmsWorks()));
  }, []);

  // Lock body scroll while modal open
  useE2(() => {
    document.body.style.overflow = selected ? 'hidden' : '';
    const onEsc = (e) => {if (e.key === 'Escape') setSelected(null);};
    if (selected) document.addEventListener('keydown', onEsc);
    return () => {
      document.body.style.overflow = '';
      document.removeEventListener('keydown', onEsc);
    };
  }, [selected]);

  // Pinned horizontal scroll
  useE2(() => {
    const section = sectionRef.current;
    const track = trackRef.current;
    const bar = progressRef.current;
    if (!section || !track) return;

    let isMobile = window.matchMedia('(max-width: 800px)').matches;
    if (isMobile) return;

    // Dynamically size the section so vertical scroll == translation distance
    const sizeSection = () => {
      const distance = Math.max(0, track.scrollWidth - window.innerWidth + 80);
      // total height = viewport + distance, so the sticky pins exactly long enough
      section.style.height = `${window.innerHeight + distance}px`;
    };
    sizeSection();

    let ticking = false;
    const update = () => {
      const rect = section.getBoundingClientRect();
      const vh = window.innerHeight;
      const total = section.offsetHeight - vh;
      const scrolled = Math.max(0, Math.min(total, -rect.top));
      const p = total > 0 ? scrolled / total : 0;
      const distance = track.scrollWidth - window.innerWidth + 80;
      track.style.transform = `translate3d(${-p * distance}px, 0, 0)`;
      if (bar) bar.style.transform = `scaleX(${p})`;
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        window.requestAnimationFrame(update);
        ticking = true;
      }
    };
    const onResize = () => {sizeSection();update();};
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onResize);
    update();
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onResize);
    };
  }, []);

  // Canvas animated background — flowing wind lines
  useE2(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let raf;
    let w = 0,h = 0,dpr = Math.min(2, window.devicePixelRatio || 1);

    const resize = () => {
      const rect = canvas.parentElement.getBoundingClientRect();
      w = canvas.width = rect.width * dpr;
      h = canvas.height = window.innerHeight * dpr;
      canvas.style.width = rect.width + 'px';
      canvas.style.height = window.innerHeight + 'px';
    };
    resize();
    window.addEventListener('resize', resize);

    // Particle system: dots that follow flow-field defined by a noise-like function
    const N = 220;
    const particles = Array.from({ length: N }, () => ({
      x: Math.random() * w,
      y: Math.random() * h,
      vx: 0, vy: 0,
      life: Math.random() * 200
    }));

    const colors = ['#1ec8ff', '#2b48f5', '#7a2bd9', '#e0298a', '#ff3a2e', '#ff8a1a'];

    let t = 0;
    const draw = () => {
      t += 0.003;
      // soft trail fade
      ctx.fillStyle = 'rgba(7,7,10,0.08)';
      ctx.fillRect(0, 0, w, h);

      ctx.globalCompositeOperation = 'lighter';
      for (let i = 0; i < particles.length; i++) {
        const p = particles[i];
        // flow field: angle based on position + time
        const nx = p.x * 0.0015;
        const ny = p.y * 0.0015;
        const angle = (Math.sin(nx + t) + Math.cos(ny - t * 0.7)) * Math.PI;
        const speed = 0.8 * dpr;
        p.vx = Math.cos(angle) * speed;
        p.vy = Math.sin(angle) * speed;
        const px = p.x,py = p.y;
        p.x += p.vx;
        p.y += p.vy;
        p.life -= 1;

        if (p.x < 0 || p.x > w || p.y < 0 || p.y > h || p.life <= 0) {
          p.x = Math.random() * w;
          p.y = Math.random() * h;
          p.life = 150 + Math.random() * 150;
        }

        const c = colors[i % colors.length];
        ctx.strokeStyle = c;
        ctx.lineWidth = 1 * dpr;
        ctx.globalAlpha = 0.35;
        ctx.beginPath();
        ctx.moveTo(px, py);
        ctx.lineTo(p.x, p.y);
        ctx.stroke();
      }
      ctx.globalCompositeOperation = 'source-over';
      ctx.globalAlpha = 1;

      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
    };
  }, []);

  return (
    <section ref={sectionRef} id="works" className="works-section" style={{ backgroundColor: "rgb(1, 1, 197)" }}>
      <canvas ref={canvasRef} className="works-canvas-bg" />
      <div className="works-vignette"></div>
      <div className="works-sticky">
        <div className="works-header">
          <div>
            <div className="section-eyebrow reveal">
              <span className="num">02 —</span>
              <span>Selected Works</span>
            </div>
            <h2 className="section-h reveal" style={{ '--reveal-delay': '100ms' }}>
              Resultados reales.<br />
              <span className="muted">Nada de relleno.</span>
            </h2>
          </div>
          <a className="btn-secondary reveal" style={{ '--reveal-delay': '200ms' }} href="#contact" onClick={(e) => {e.preventDefault();document.getElementById('contact')?.scrollIntoView({ behavior: 'smooth' });}}>
            Ver todo el archivo
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7" /></svg>
          </a>
        </div>

        <div className="works-track-wrap">
          <div ref={trackRef} className="works-track">
            {items.map((w, i) =>
            <div key={w.id} className="work-card" onClick={() => setSelected(w)}>
                <div className="img" style={{ backgroundImage: `url(${w.img})` }}></div>
                <div className="grad"></div>
                <div className="arrow">
                  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M7 17L17 7M7 7h10v10" /></svg>
                </div>
                <div className="meta">
                  <div className="tags">
                    <span className="t">{w.cat}</span>
                    <span>{w.year}</span>
                  </div>
                  <h4>{w.title}</h4>
                </div>
              </div>
            )}
          </div>
        </div>

        <div className="works-progress">
          <div ref={progressRef} className="bar"></div>
        </div>
        <div className="works-progress-labels">
          <span>01 / {items.length.toString().padStart(2, '0')}</span>
          <span>arrastra o desliza</span>
        </div>
      </div>
      <WorkDetail work={selected} onClose={() => setSelected(null)} />
    </section>);

}

// ============================================================================
// WORK DETAIL — fullscreen case study modal
// ============================================================================
function WorkDetail({ work, onClose }) {
  if (!work) return null;
  return (
    <div className="work-detail open" onClick={onClose}>
      <div className="work-detail-inner" onClick={(e) => e.stopPropagation()}>
        <button className="work-detail-close" onClick={onClose} aria-label="Cerrar">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M18 6L6 18M6 6l12 12" /></svg>
        </button>

        <div className="wd-hero" style={{ backgroundImage: `url(${work.hero || work.img})` }}>
          <div className="wd-hero-grad"></div>
          <div className="wd-hero-content">
            <div className="wd-tags">
              <span className="t">{work.cat}</span>
              <span>· {work.year}</span>
              {work.client && <span>· {work.client}</span>}
            </div>
            <h1>{work.title}</h1>
            {work.url &&
            <a className="wd-url" href={`https://${work.url}`} target="_blank" rel="noopener noreferrer">
                {work.url}
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M7 17L17 7M7 7h10v10" /></svg>
              </a>
            }
          </div>
        </div>

        <div className="wd-body">
          <section className="wd-intro">
            <div className="wd-label">Resumen</div>
            <p className="wd-lead">{work.desc}</p>
            {work.scope &&
            <div className="wd-scope">
                {work.scope.map((s, i) => <span key={i} className="chip">{s}</span>)}
              </div>
            }
          </section>

          <section className="wd-process">
            {work.challenge &&
            <div className="wd-block">
                <div className="wd-label">El reto</div>
                <p>{work.challenge}</p>
              </div>
            }
            {work.solution &&
            <div className="wd-block">
                <div className="wd-label">La solución</div>
                <p>{work.solution}</p>
              </div>
            }
            {work.result &&
            <div className="wd-block highlight">
                <div className="wd-label">Resultado</div>
                <p className="wd-result">{work.result}</p>
              </div>
            }
          </section>

          {work.gallery && work.gallery.length > 0 &&
          <section className="wd-gallery">
              <div className="wd-label">Capturas del proyecto</div>
              <div className="wd-gallery-grid">
                {work.gallery.map((src, i) =>
              <div key={i} className="wd-shot" style={{ backgroundImage: `url(${src})` }}></div>
              )}
              </div>
            </section>
          }

          {work.testimonial &&
          <section className="wd-testimonial">
              <div className="wd-quote-mark">"</div>
              <blockquote>{work.testimonial.quote}</blockquote>
              <div className="wd-author">
                <div className="dot"></div>
                <div>
                  <div className="name">{work.testimonial.author}</div>
                  <div className="role">{work.testimonial.role}{work.client && ` · ${work.client}`}</div>
                </div>
              </div>
            </section>
          }

          <section className="wd-cta">
            <h3>¿Un proyecto similar en mente?</h3>
            <a className="btn-primary" href="#contact" onClick={(e) => {e.preventDefault();onClose();setTimeout(() => document.getElementById('contact')?.scrollIntoView({ behavior: 'smooth' }), 300);}}>
              Iniciar conversación
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7" /></svg>
            </a>
          </section>
        </div>
      </div>
    </div>);

}

// ============================================================================
// PHILOSOPHY — illuminated word-by-word on scroll
// ============================================================================
function Philosophy() {
  const ref = useR2(null);
  const [teamOpen, setTeamOpen] = useS2(false);
  const text = "No vendemos transformaciones mágicas ni promesas vacías. Trabajamos desde la escucha, el respeto y la construcción progresiva. Diseñamos sistemas que respiran, que se adaptan y que permanecen. El buen diseño no es decoración: es estructura, coherencia y cuidado.";
  const words = text.split(' ');

  useE2(() => {
    document.body.style.overflow = teamOpen ? 'hidden' : '';
    const onEsc = (e) => { if (e.key === 'Escape') setTeamOpen(false); };
    if (teamOpen) document.addEventListener('keydown', onEsc);
    return () => {
      document.body.style.overflow = '';
      document.removeEventListener('keydown', onEsc);
    };
  }, [teamOpen]);

  useE2(() => {
    const el = ref.current;
    if (!el) return;
    const onScroll = () => {
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const start = vh * 0.65;
      const end = vh * 0.15;
      const total = start - end;
      const p = Math.max(0, Math.min(1, (start - rect.top) / total));
      const span = el.querySelectorAll('.word');
      const upTo = Math.floor(p * span.length);
      span.forEach((w, i) => {
        if (i <= upTo) w.classList.add('lit');else w.classList.remove('lit');
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <section id="philosophy" className="philosophy">
      <div className="philosophy-bg"></div>
      <div className="philosophy-grid">
        <div className="philosophy-label">Filosofía / 03</div>
        <div>
          <p ref={ref} className="philosophy-prose">
            {words.map((w, i) => <span key={i} className="word">{w} </span>)}
          </p>
          <div className="philosophy-quote">
            <span className="text-gradient">"El buen diseño es invisible. Solo se nota cuando falta."</span>
          </div>
          <button className="studio-card" onClick={() => setTeamOpen(true)}>
            <div className="studio-card-portrait">
              <span className="studio-card-symbol"></span>
              <div className="studio-card-pulse">
                <span className="pulse"></span>
              </div>
            </div>
            <div className="studio-card-body">
              <div className="studio-card-label">Detrás de AORYN</div>
              <div className="studio-card-h">
                Una sola persona, por ahora — <span className="text-gradient">conoce al equipo</span>
              </div>
              <div className="studio-card-meta">
                <span>10+ años de trayectoria</span>
                <span>·</span>
                <span>Disponible 2026</span>
              </div>
            </div>
            <div className="studio-card-arrow">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
            </div>
          </button>
          <div className="philosophy-signature">
            <span className="ln"></span>
            <span>AORYN Studio</span>
          </div>
        </div>
      </div>
      <TeamModal open={teamOpen} onClose={() => setTeamOpen(false)} />
    </section>);

}

// ============================================================================
// TEAM MODAL — bio sheet
// ============================================================================
function TeamModal({ open, onClose }) {
  if (!open) return null;
  return (
    <div className="team-modal open" onClick={onClose}>
      <div className="team-inner" onClick={(e) => e.stopPropagation()}>
        <button className="team-close" onClick={onClose} aria-label="Cerrar">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
        </button>

        <div className="team-layout">
          <div className="team-portrait">
            <image-slot
              id="team-portrait-1"
              shape="rect"
              radius="20"
              placeholder="Tu foto aquí — arrastra una imagen"
            ></image-slot>
            <div className="team-portrait-tag">
              <span className="pulse"></span>
              <span>Disponible para nuevos proyectos</span>
            </div>
          </div>

          <div className="team-content">
            <div className="team-eyebrow">
              <span>★ —</span>
              <span>El estudio</span>
            </div>
            <h2 className="team-h">
              Detrás de AORYN <span className="text-gradient">hay una sola persona</span> — por ahora.
            </h2>
            <p className="team-lead">
              Llevo más de una década trabajando en la intersección entre estrategia,
              diseño y tecnología. He pasado por agencias, startups y proyectos propios.
              AORYN es el resultado de querer hacer las cosas <em>despacio y bien</em>,
              sin atajos, sin humo y sin promesas mágicas.
            </p>

            <div className="team-blocks">
              <div className="team-block">
                <div className="team-label">Por qué AORYN</div>
                <p>
                  Demasiados negocios contratan diseño como si fuera maquillaje. Yo creo
                  que es estructura — la forma en que comunicas determina cómo te perciben,
                  qué cobras y a quién atraes. AORYN existe para acompañar negocios reales
                  en esa transformación.
                </p>
              </div>

              <div className="team-block">
                <div className="team-label">Trayectoria</div>
                <ul className="team-list">
                  <li><strong>10+ años</strong> diseñando producto digital y branding para PyMEs.</li>
                  <li><strong>Estrategia operativa</strong> en proyectos de transformación digital.</li>
                  <li><strong>Producción audiovisual</strong> end-to-end: dirección, rodaje y post.</li>
                  <li><strong>Automatizaciones e IA</strong> aplicadas a flujos comerciales y soporte.</li>
                </ul>
              </div>

              <div className="team-block">
                <div className="team-label">Cómo trabajo</div>
                <p>
                  Procesos cortos, conversaciones abiertas, entregas iterativas. Sin
                  contratos opacos, sin disclaimers de "siguiente fase". Si en mes uno no
                  vemos progreso real, lo decimos.
                </p>
              </div>
            </div>

            <div className="team-stack">
              <div className="team-label">Stack actual</div>
              <div className="team-chips">
                <span>Figma</span>
                <span>Next.js</span>
                <span>Webflow</span>
                <span>Supabase</span>
                <span>n8n · Make</span>
                <span>OpenAI · Claude</span>
                <span>Premiere · After Effects</span>
              </div>
            </div>

            <div className="team-quote">
              <span className="text-gradient">"Hago lo que prometo. Y prometo poco."</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// TOOLS — marquee
// ============================================================================
const TOOLS = [
{ name: 'ChatGPT', icon: 'logos:openai-icon', clr: '#10A37F' },
{ name: 'Claude', icon: 'logos:claude', clr: '#D97757' },
{ name: 'Gemini', icon: 'logos:google-gemini', clr: '#4285F4' },
{ name: 'Figma', icon: 'logos:figma', clr: '#F24E1E' },
{ name: 'Photoshop', icon: 'logos:adobe-photoshop', clr: '#31A8FF' },
{ name: 'Premiere Pro', icon: 'logos:adobe-premiere', clr: '#9999FF' },
{ name: 'After Effects', icon: 'logos:adobe-after-effects', clr: '#9999FF' },
{ name: 'Illustrator', icon: 'logos:adobe-illustrator', clr: '#FF9A00' },
{ name: 'Webflow', icon: 'logos:webflow', clr: '#146EF5' },
{ name: 'Supabase', icon: 'logos:supabase-icon', clr: '#3ECF8E' },
{ name: 'Notion', icon: 'logos:notion-icon', clr: '#FFFFFF' },
{ name: 'Slack', icon: 'logos:slack-icon', clr: '#4A154B' },
{ name: 'Gmail', icon: 'logos:google-gmail', clr: '#EA4335' },
{ name: 'Drive', icon: 'logos:google-drive', clr: '#4285F4' },
{ name: 'WhatsApp', icon: 'logos:whatsapp-icon', clr: '#25D366' },
{ name: 'Spotify', icon: 'logos:spotify-icon', clr: '#1DB954' },
{ name: 'Vercel', icon: 'logos:vercel-icon', clr: '#FFFFFF' },
{ name: 'React', icon: 'logos:react', clr: '#61DAFB' }];


function Tools() {
  const all = [...TOOLS, ...TOOLS];
  return (
    <section className="tools">
      <div className="tools-header">
        <div className="eyebrow reveal">Stack tecnológico</div>
        <p className="reveal" style={{ '--reveal-delay': '100ms' }}>
          Potenciado por las mejores herramientas del mercado.
        </p>
      </div>
      <div className="tools-marquee">
        <div className="tools-track">
          {all.map((t, i) =>
          <div key={i} className="tool-chip" style={{ '--clr': t.clr }}>
              <div className="box">
                <img
                src={`https://api.iconify.design/${t.icon.replace(':', '/')}.svg`}
                alt={t.name}
                loading="lazy"
                onError={(e) => {e.target.style.display = 'none';e.target.parentElement.classList.add('fallback');e.target.parentElement.dataset.letter = t.name.charAt(0);}} />
              
              </div>
              <div className="lbl">{t.name}</div>
            </div>
          )}
        </div>
      </div>
    </section>);

}

Object.assign(window, { Services, Works, Philosophy, Tools });