// Services (8) + How it works (3 steps)

const { useState: uS2, useEffect: uE2, useRef: uR2 } = React;

// ---------------- WhatsApp icon (official) ----------------
const WA_PATH = "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.885 3.488";

// ---------------- Services ----------------
const SERVICES = [
  { id: 'limpieza-regular', scene: BroomScene, title: 'Limpieza regular', tag: 'Semanal o quincenal',
    copy: 'Mantén tu hogar impecable sin pensar en ello. Equipo asignado, insumos incluidos.',
    includes: ['Barrer y trapear', 'Baños completos', 'Cocina y loza', 'Ropa de cama', 'Polvo en superficies'],
    from: 110000, accent: 'var(--coral)',
    pricing: { type: 'jornada', jornadaCompleta: 110000, hasFrequency: true,
      note: '1 jornada completa (~8 h) con equipo asignado e insumos incluidos.' } },
  { id: 'limpieza-profunda', scene: SparkleScene, title: 'Limpieza profunda', tag: 'Mudanzas y eventos',
    copy: 'Rincones, zócalos, ventanas y electrodomésticos. Lo que una limpieza normal no alcanza.',
    includes: ['Ventanas y vidrios', 'Horno y nevera', 'Ductos y zócalos', 'Mobiliario a fondo', 'Desinfección'],
    from: 180000, accent: 'var(--coral)',
    pricing: { type: 'jornada', jornadaCompleta: 180000,
      note: '1 jornada completa (~8 h) con técnicos especializados e insumos para limpieza profunda.' } },
  { id: 'cortinas', scene: CurtainScene, title: 'Instalación y lavado de cortinas y persianas', shortTitle: 'Cortinas y persianas', tag: 'En sitio o taller',
    copy: 'Descuelgue, lavado especializado por tipo de tela e instalación. Cortinas, persianas y blackouts.',
    includes: ['Instalación nueva', 'Descuelgue y entrega', 'Anti-ácaros', 'Telas delicadas', 'Persianas y blackouts'],
    from: 60000, accent: 'var(--sky)',
    pricing: { type: 'm2', porM2: 20000, m2Min: 3, m2Max: 80, m2Default: 15, note: 'Tarifa para instalación. El lavado se cotiza aparte por cantidad y tipo de tela.' } },
  { id: 'fontaneria', scene: TapScene, title: 'Fontanería', tag: 'Urgencias 24/7',
    copy: 'Fugas, tuberías, sanitarios, grifería. Diagnóstico claro y precio cerrado antes de empezar.',
    includes: ['Detección de fugas', 'Cambio de grifería', 'Desagües', 'Calentadores', 'Instalación sanitarios'],
    from: 90000, accent: 'var(--sky)',
    pricing: { type: 'visita', visita: 90000, note: 'Visita 90.000 con diagnóstico en sitio. El trabajo se cierra ahí mismo según el problema.' } },
  { id: 'cerrajeria', scene: KeyScene, title: 'Cerrajería', tag: 'Apertura en 40 min',
    copy: 'Apertura de puertas, cambio de cilindros, cerraduras electrónicas. Sin dañar tu puerta.',
    includes: ['Apertura sin daño', 'Cilindros de seguridad', 'Cerraduras electrónicas', 'Copias de llaves', 'Rejas'],
    from: 90000, accent: 'var(--coral)',
    pricing: { type: 'visita', visita: 90000, note: 'Visita 90.000 con diagnóstico en sitio. El trabajo se cierra ahí mismo según el problema.' } },
  { id: 'electricidad', scene: BoltScene, title: 'Electricidad', tag: 'Técnicos certificados',
    copy: 'Tomacorrientes, breakers, iluminación, puntos nuevos. Trabajo limpio y normativa al día.',
    includes: ['Diagnóstico de fallas', 'Puntos nuevos', 'Iluminación', 'Tableros', 'Automatización'],
    from: 90000, accent: 'var(--sun)',
    pricing: { type: 'visita', visita: 90000, note: 'Visita 90.000 con diagnóstico en sitio. El trabajo se cierra ahí mismo según el problema.' } },
  { id: 'carpinteria', scene: HammerScene, title: 'Carpintería', tag: 'Reparación y a medida',
    copy: 'Puertas, muebles, ensambles, cajones atascados, closets. Lo que esté roto, vuelve a servir.',
    includes: ['Reparación de muebles', 'Bisagras y cajones', 'Puertas', 'Closets a medida', 'Pulido y lacado'],
    from: 90000, accent: 'var(--coral)',
    pricing: { type: 'visita', visita: 90000, note: 'Visita 90.000 con diagnóstico. Cotización según tamaño del mueble y trabajo.' } },
  { id: 'obra-civil', scene: TrowelScene, title: 'Obra civil', tag: 'Remodelaciones menores',
    copy: 'Enchape, resane, pintura, pisos. Obras pequeñas que cambian por completo un espacio.',
    includes: ['Enchape y azulejo', 'Resanes y pintura', 'Pisos', 'Impermeabilización', 'Demolición menor'],
    from: 250000, accent: 'var(--coral-deep)',
    pricing: { type: 'm2', porM2: 50000, m2Min: 5, m2Max: 5000, m2Default: 30, m2Step: 5, note: 'Tarifa promedio por m². Incluye mano de obra; materiales se cotizan aparte. Sirve para casas, bodegas u oficinas.' } },
  { id: 'fumigacion', scene: FogScene, title: 'Fumigación', tag: 'Garantía 6 meses',
    copy: 'Control de cucarachas, hormigas, roedores y plagas urbanas. Productos seguros para mascotas y niños.',
    includes: ['Cucarachas y hormigas', 'Roedores', 'Mosquitos y zancudos', 'Productos seguros', 'Garantía 6 meses'],
    from: 90000, accent: 'var(--sun)',
    pricing: { type: 'visita', visita: 90000, note: 'Visita 90.000. Fumigación normal para zancudos en casa campestre: $180.000. Otros casos se cotizan según complejidad.' } },
  { id: 'jardineria', scene: PlantScene, title: 'Jardinería', tag: 'Mantenimiento periódico',
    copy: 'Poda, riego, abono y diseño de espacios verdes. Mantenimiento mensual o trabajo único.',
    includes: ['Poda y corte', 'Diseño y siembra', 'Abono y riego', 'Control de maleza', 'Mantenimiento mensual'],
    from: 90000, accent: 'var(--sage)',
    pricing: { type: 'visita', visita: 90000, note: 'Corte de pasto: $90.000. Otros trabajos cotizados según tamaño del lote y trabajo requerido.' } },
];

function ServiceCard({ s, idx, expanded, onToggle }) {
  const [hover, setHover] = uS2(false);
  const Scene = s.scene;

  // Action button styling per state
  let actionBg, actionIconColor;
  if (expanded) {
    actionBg = 'var(--coral)';
    actionIconColor = 'white';
  } else if (hover) {
    actionBg = '#25D366';
    actionIconColor = 'white';
  } else {
    actionBg = 'var(--cream-2)';
    actionIconColor = '#25D366';
  }

  return (
    <div
      onMouseEnter={() => { if (!window.IS_TOUCH) setHover(true); }}
      onMouseLeave={() => setHover(false)}
      onClick={onToggle}
      style={{
        background: 'var(--cream)',
        border: '1px solid var(--line)',
        borderRadius: 'var(--radius-lg)',
        padding: 24,
        cursor: 'pointer',
        transition: 'all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1)',
        transform: hover ? 'translateY(-4px)' : 'translateY(0)',
        boxShadow: hover ? 'var(--shadow-lift)' : 'var(--shadow-card)',
        gridColumn: expanded ? 'span 2' : 'span 1',
        position: 'relative', overflow: 'hidden',
        display: 'flex', flexDirection: 'column',
      }}
      className="service-card"
    >
      <div style={{
        position: 'absolute', top: 16, right: 16,
        fontSize: 12, color: 'var(--mute-2)', fontWeight: 500,
      }}>0{idx + 1}</div>

      <div style={{
        width: '100%', height: 140, marginBottom: 18,
        background: hover ? `linear-gradient(135deg, ${s.accent}15, transparent)` : 'var(--cream-2)',
        borderRadius: 16, overflow: 'hidden',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        transition: 'background 0.3s',
      }}>
        <div style={{ width: 120, height: 120 }}>
          <Scene animate={hover || expanded} />
        </div>
      </div>

      <div style={{
        display: 'inline-block', padding: '3px 10px',
        background: `${s.accent}18`, color: s.accent,
        borderRadius: 999, fontSize: 11, fontWeight: 500,
        marginBottom: 10, alignSelf: 'flex-start',
      }}>{s.tag}</div>

      <h3 style={{
        fontFamily: 'var(--font-display)', fontSize: 24, fontWeight: 500,
        letterSpacing: '-0.02em', marginBottom: 6, color: 'var(--ink)',
      }}>{s.title}</h3>
      <p style={{ fontSize: 14, color: 'var(--mute)', lineHeight: 1.5, marginBottom: 14 }}>{s.copy}</p>

      <div style={{
        maxHeight: expanded ? 400 : 0,
        overflow: 'hidden',
        transition: 'max-height 0.5s cubic-bezier(0.2, 0.8, 0.2, 1)',
      }}>
        <div style={{ paddingTop: 12, borderTop: '1px solid var(--line)' }}>
          <p style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'var(--mute)', marginBottom: 10, fontWeight: 600 }}>Qué incluye</p>
          <ul style={{ listStyle: 'none', display: 'grid', gap: 8 }}>
            {s.includes.map((item, i) => (
              <li key={i} style={{
                display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--ink-2)',
                opacity: expanded ? 1 : 0,
                transform: expanded ? 'translateX(0)' : 'translateX(-8px)',
                transition: `all 0.3s ${i * 60}ms`,
              }}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={s.accent} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M20 6L9 17l-5-5"/>
                </svg>
                {item}
              </li>
            ))}
          </ul>
        </div>
      </div>

      <div style={{
        marginTop: 'auto', paddingTop: 16, display: 'flex',
        justifyContent: 'space-between', alignItems: 'center',
      }}>
        <div>
          <span style={{ fontSize: 11, color: 'var(--mute)' }}>Desde</span>
          <div style={{ fontFamily: 'var(--font-price)', fontStyle: 'italic', fontSize: 22, fontWeight: 500, color: 'var(--ink)', letterSpacing: '-0.02em' }}>
            ${s.from.toLocaleString('es-CO')}
          </div>
        </div>
        <div style={{
          width: 36, height: 36, borderRadius: '50%',
          background: actionBg,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          transition: 'all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1)',
          transform: hover && !expanded ? 'scale(1.05)' : 'scale(1)',
        }}>
          {expanded ? (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={actionIconColor} strokeWidth="2.5" strokeLinecap="round">
              <path d="M6 6l12 12M18 6L6 18"/>
            </svg>
          ) : (
            <svg width="16" height="16" viewBox="0 0 24 24" fill={actionIconColor}>
              <path d={WA_PATH}/>
            </svg>
          )}
        </div>
      </div>
    </div>
  );
}

function ServicesSection() {
  const [expanded, setExpanded] = uS2(null);
  return (
    <section id="sec-0" style={{ padding: '120px 32px', position: 'relative' }}>
      <div style={{ maxWidth: 1280, margin: '0 auto' }}>
        <div style={{ maxWidth: 680, marginBottom: 56 }}>
          <Reveal>
            <div style={{
              display: 'inline-block', padding: '4px 12px',
              background: 'var(--coral-whisper)', color: 'var(--coral-deep)',
              borderRadius: 999, fontSize: 12, fontWeight: 500, marginBottom: 20,
              letterSpacing: '0.02em',
            }}>Servicios</div>
          </Reveal>
          <Reveal delay={100}>
            <h2 style={{
              fontFamily: 'var(--font-display)', fontSize: 'clamp(36px, 5vw, 56px)',
              fontWeight: 500, lineHeight: 1.02, letterSpacing: '-0.03em',
              marginBottom: 16,
            }}>
              Todo lo que tu hogar <em style={{ fontStyle: 'italic', color: 'var(--coral)' }}>necesita</em>,
              en un solo lugar.
            </h2>
          </Reveal>
          <Reveal delay={200}>
            <p style={{ fontSize: 17, color: 'var(--mute)', lineHeight: 1.5 }}>
              Diez especialidades con técnicos verificados. Toca una tarjeta para ver qué incluye.
            </p>
          </Reveal>
        </div>

        <div style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fit, minmax(min(260px, 100%), 1fr))',
          gap: 16,
        }} className="services-grid">
          {SERVICES.map((s, i) => (
            <ServiceCard key={s.id} s={s} idx={i}
              expanded={expanded === s.id}
              onToggle={() => setExpanded(expanded === s.id ? null : s.id)} />
          ))}
        </div>
      </div>
      <style>{`
        @media (max-width: 600px) {
          .services-grid { grid-template-columns: 1fr !important; }
          .services-grid > * { grid-column: auto !important; }
        }
      `}</style>
    </section>
  );
}

// ---------------- How it works (static, 3-step reveal) ----------------
function HowItWorks() {
  const steps = [
    { n: '01', title: 'Escríbenos por WhatsApp',
      copy: 'Cuéntanos qué necesitas. Una foto o un audio bastan. Sin formularios largos.',
      time: 'En 1 minuto' },
    { n: '02', title: 'Cotización en minutos',
      copy: 'Te enviamos precio cerrado con técnico asignado y ventana horaria. Tú confirmas.',
      time: 'Respuesta en 15 min' },
    { n: '03', title: 'Servicio en tu hogar',
      copy: 'Técnico verificado, uniformado y con ID. Llega, trabaja limpio y se va.',
      time: 'Mismo día o agendado' },
  ];

  return (
    <section id="sec-1" style={{
      background: 'var(--ink)', color: 'var(--cream)',
      position: 'relative',
      padding: '120px 32px',
      overflow: 'hidden',
    }}>
      <div aria-hidden style={{
        position: 'absolute', top: '20%', right: '-10%', width: 600, height: 600,
        background: 'radial-gradient(circle, rgba(236,106,77,0.18), transparent 60%)',
        filter: 'blur(80px)',
        pointerEvents: 'none',
      }}/>

      <div style={{ maxWidth: 1280, margin: '0 auto', position: 'relative', textAlign: 'center' }}>
        <div style={{ maxWidth: 720, margin: '0 auto', marginBottom: 80 }}>
          <Reveal>
            <div style={{
              display: 'inline-block', padding: '4px 12px',
              background: 'rgba(236,106,77,0.2)', color: 'var(--coral-soft)',
              borderRadius: 999, fontSize: 12, fontWeight: 500, marginBottom: 20,
            }}>Cómo funciona</div>
          </Reveal>
          <Reveal delay={100}>
            <h2 style={{
              fontFamily: 'var(--font-display)', fontSize: 'clamp(36px, 5vw, 56px)',
              fontWeight: 400, lineHeight: 1.02, letterSpacing: '-0.03em',
              marginBottom: 16, color: 'var(--cream)',
            }}>
              Del mensaje al técnico en tu puerta, en <em style={{ fontStyle: 'italic', color: 'var(--coral)' }}>tres pasos</em>.
            </h2>
          </Reveal>
        </div>

        <HowToSteps steps={steps} />

        <ChatPreview />
      </div>

      <style>{`
        @media (max-width: 860px) {
          .howto-grid { grid-template-columns: 1fr !important; gap: 56px !important; }
          .howto-line, .howto-line-fill { display: none !important; }
        }
        @keyframes chatBubblePop {
          0% { opacity: 0; transform: translateY(8px) scale(0.96); }
          100% { opacity: 1; transform: translateY(0) scale(1); }
        }
        .chat-bubble-pop {
          animation: chatBubblePop 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
        }
      `}</style>
    </section>
  );
}

function HowToSteps({ steps }) {
  const [inViewRef, inView] = useInView();
  const parallax = useMouseParallax(18);
  const containerRef = uR2(null);
  const [mouseX, setMouseX] = uS2(0);
  uE2(() => {
    const el = containerRef.current;
    if (!el) return;
    const onMove = (e) => {
      const rect = el.getBoundingClientRect();
      const x = (e.clientX - rect.left) / rect.width;
      setMouseX(Math.min(1, Math.max(0, x)));
    };
    const onLeave = () => setMouseX(0);
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, []);
  // Map mouse X (0..1 across grid) to fill width along the line span (16.67%..83.33%)
  const fillProgress = Math.min(1, Math.max(0, (mouseX - 0.1667) / 0.6666));
  const setRefs = (node) => { containerRef.current = node; if (typeof inViewRef === 'function') inViewRef(node); else if (inViewRef) inViewRef.current = node; };
  return (
    <div ref={setRefs} className="howto-grid" style={{
      display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0,
      position: 'relative', marginBottom: 96, textAlign: 'center',
    }}>
      {/* Background track: from circle 1 center (16.67%) to circle 3 center (83.33%) */}
      <div aria-hidden className="howto-line" style={{
        position: 'absolute', top: 32, left: '16.67%', right: '16.67%', height: 2,
        background: 'rgba(255,255,255,0.12)', zIndex: 0,
      }}/>
      {/* Coral fill that follows the mouse X position across the line */}
      <div aria-hidden className="howto-line-fill" style={{
        position: 'absolute', top: 32, left: '16.67%', height: 2,
        background: 'var(--coral)', zIndex: 1,
        width: `${fillProgress * 66.66}%`,
        boxShadow: '0 0 12px rgba(236,106,77,0.6)',
        transition: 'width 0.25s cubic-bezier(0.2, 0.8, 0.2, 1)',
      }}/>
      {steps.map((s, i) => (
        <div key={i} style={{
          position: 'relative', zIndex: 2,
          padding: '0 16px',
          opacity: inView ? 1 : 0,
          transform: inView ? 'translateY(0)' : 'translateY(20px)',
          transition: `opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) ${i * 180}ms, transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) ${i * 180}ms`,
        }}>
          <div style={{
            width: 64, height: 64, borderRadius: '50%',
            background: 'var(--coral)',
            border: '2px solid var(--coral)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            margin: '0 auto 24px', fontFamily: 'var(--font-price)',
            fontStyle: 'italic', fontSize: 22, fontWeight: 500,
            color: 'var(--cream)',
            boxShadow: '0 0 0 8px rgba(236,106,77,0.18), 0 12px 30px -8px rgba(236,106,77,0.45)',
            transform: `translate(${parallax.x * (1 - i * 0.3)}px, ${parallax.y * (1 - i * 0.3)}px)`,
            transition: 'transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1)',
          }}>{s.n}</div>
          <div style={{
            fontSize: 14, fontFamily: 'var(--font-body)',
            color: 'var(--coral-soft)', marginBottom: 12, fontWeight: 500,
          }}>{s.time}</div>
          <h3 style={{
            fontFamily: 'var(--font-display)', fontSize: 24,
            fontWeight: 400, letterSpacing: '-0.02em', marginBottom: 12,
            color: 'var(--cream)',
          }}>{s.title}</h3>
          <p style={{ fontSize: 15, color: 'rgba(250,246,242,0.65)', lineHeight: 1.55, maxWidth: 280, margin: '0 auto' }}>{s.copy}</p>
        </div>
      ))}
    </div>
  );
}

function ChatPreview() {
  const [ref, inView] = useInView();
  const messages = [
    { side: 'user', text: 'Hola, tengo una fuga en el baño', delay: 600 },
    { side: 'user', text: '[foto]', delay: 1100 },
    { side: 'homli', text: '¡Hola! Vemos una fuga en el sifón del lavamanos. Enviamos a Carlos hoy entre 2 y 4 pm. Precio cerrado $85.000.', delay: 2400 },
    { side: 'user', text: 'Perfecto, confirmado', delay: 3700 },
    { side: 'homli', text: 'Carlos va en camino. Llega en 20 min.', delay: 4900 },
  ];
  // Loop counter: each tick re-mounts bubbles using a key, restarting the staggered fade-in
  const [tick, setTick] = uS2(0);
  uE2(() => {
    if (!inView) return;
    const cycleMs = 7200;
    const id = setInterval(() => setTick(t => t + 1), cycleMs);
    return () => clearInterval(id);
  }, [inView]);
  return (
    <div ref={ref} style={{
      maxWidth: 460, margin: '0 auto',
      background: '#EAE4D9', borderRadius: 24, padding: 20,
      boxShadow: '0 40px 80px -20px rgba(0,0,0,0.4)',
      border: '1px solid rgba(255,255,255,0.08)',
      opacity: inView ? 1 : 0,
      transform: inView ? 'translateY(0)' : 'translateY(20px)',
      transition: 'opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1), transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1)',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16,
        paddingBottom: 12, borderBottom: '1px solid rgba(0,0,0,0.08)',
      }}>
        <div style={{
          width: 36, height: 36, borderRadius: '50%', background: 'var(--coral)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: 'white', fontFamily: 'var(--font-display)', fontWeight: 400,
        }}>H</div>
        <div>
          <div style={{ fontSize: 13, fontWeight: 600, color: '#1A1410' }}>Homli</div>
          <div style={{ fontSize: 11, color: '#25B560' }}>en línea</div>
        </div>
      </div>
      <div key={tick} style={{ display: 'flex', flexDirection: 'column', gap: 10, minHeight: 240 }}>
        {messages.map((m, i) => (
          <ChatBubbleLoop key={i} side={m.side} show={inView} delay={m.delay}>{m.text}</ChatBubbleLoop>
        ))}
      </div>
    </div>
  );
}

function ChatBubble({ side, show, delay = 0, children }) {
  const isUser = side === 'user';
  return (
    <div style={{
      alignSelf: isUser ? 'flex-end' : 'flex-start',
      maxWidth: '82%',
      padding: '9px 13px',
      background: isUser ? '#D9FDD3' : 'white',
      borderRadius: isUser ? '14px 14px 2px 14px' : '14px 14px 14px 2px',
      fontSize: 13.5, color: '#1A1410', lineHeight: 1.4,
      boxShadow: '0 1px 2px rgba(0,0,0,0.08)',
      opacity: show ? 1 : 0,
      transform: show ? 'translateY(0) scale(1)' : 'translateY(8px) scale(0.96)',
      transition: `opacity 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) ${delay}ms, transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) ${delay}ms`,
    }}>{children}</div>
  );
}

function ChatBubbleLoop({ side, show, delay = 0, children }) {
  const isUser = side === 'user';
  if (!show) return null;
  return (
    <div className="chat-bubble-pop" style={{
      alignSelf: isUser ? 'flex-end' : 'flex-start',
      maxWidth: '82%',
      padding: '9px 13px',
      background: isUser ? '#D9FDD3' : 'white',
      borderRadius: isUser ? '14px 14px 2px 14px' : '14px 14px 14px 2px',
      fontSize: 13.5, color: '#1A1410', lineHeight: 1.4,
      boxShadow: '0 1px 2px rgba(0,0,0,0.08)',
      opacity: 0,
      animationDelay: `${delay}ms`,
    }}>{children}</div>
  );
}

Object.assign(window, { SERVICES, ServicesSection, HowItWorks, WA_PATH });
