// Shared components: Nav, Footer, icons, solution card — v2

// Favicon
(function () {
  const link = document.querySelector("link[rel~='icon']") || document.createElement('link');
  link.rel = 'shortcut icon';
  link.type = 'image/png';
  link.href = 'assets/logo_line_branco.png';
  document.head.appendChild(link);
})();

// Mobile-only CSS fixes
(function () {
  const style = document.createElement('style');
  style.textContent = `
    /* Garante tamanho idêntico para as logos no desktop/tablet ignorando cache do CSS */
    .brands .row .brand-logo-wrapper img,
    .brands .row .brand-logo-wrapper:nth-child(1) img,
    .brands .row .brand-logo-wrapper:nth-child(2) img,
    .brands .row .brand-logo-wrapper:nth-child(3) img,
    .brands .row .brand-logo-wrapper:nth-child(4) img {
      height: 85px !important;
      width: 220px !important;
      object-fit: contain !important;
    }

    @media (max-width: 768px) {
      /* Logos de marcas — empilha verticalmente */
      .brands .row {
        flex-direction: column !important;
        align-items: center !important;
        gap: 32px !important;
      }
      /* Garante tamanho idêntico para as logos no mobile ignorando cache */
      .brands .row .brand-logo-wrapper img,
      .brands .row .brand-logo-wrapper:nth-child(1) img,
      .brands .row .brand-logo-wrapper:nth-child(2) img,
      .brands .row .brand-logo-wrapper:nth-child(3) img,
      .brands .row .brand-logo-wrapper:nth-child(4) img {
        height: 75px !important;
        width: 180px !important;
        object-fit: contain !important;
      }
      /* Tabs desktop ocultas no mobile */
      .tabs-desktop { display: none !important; }
      /* Dropdown mobile visível */
      .tabs-mobile-wrap { display: block !important; }
    }
    /* Dropdown mobile oculto no desktop */
    .tabs-mobile-wrap { display: none; }
  `;
  document.head.appendChild(style);
})();

// Hook: detecta se está em mobile (≤768px)
function useIsMobile() {
  const [isMobile, setIsMobile] = React.useState(() => window.innerWidth <= 768);
  React.useEffect(() => {
    const handler = () => setIsMobile(window.innerWidth <= 768);
    window.addEventListener('resize', handler);
    return () => window.removeEventListener('resize', handler);
  }, []);
  return isMobile;
}

// Register GSAP plugins once at load time
if (window.gsap) {
  [window.ScrollTrigger, window.SplitText,
  window.Flip, window.Observer, window.CustomEase]
    .filter(Boolean)
    .forEach(p => window.gsap.registerPlugin(p));
}

// Word-by-word mask reveal — wraps any children and animates each word on scroll entry.
// For accessibility: aria-label carries the full text; word spans are aria-hidden.
function WordReveal({ children, as: Tag = 'h2', ...props }) {
  const ref = React.useRef(null);

  function flatten(node) {
    if (node == null) return '';
    if (typeof node === 'string') return node;
    if (Array.isArray(node)) return node.map(flatten).join('');
    if (!React.isValidElement(node)) return '';
    if (node.type === 'br') return ' ';
    return flatten(node.props.children);
  }

  let _kid = 0;
  function split(node) {
    if (node == null || node === false || node === true) return [];
    if (typeof node === 'number') return [<React.Fragment key={_kid++}>{node}</React.Fragment>];
    if (typeof node === 'string') {
      return node.split(/(\s+)/).reduce((acc, part) => {
        if (!part) return acc;
        if (/^\s+$/.test(part)) {
          acc.push(<React.Fragment key={_kid++}>{part}</React.Fragment>);
        } else {
          const k = _kid++;
          acc.push(
            <span key={k} className="word-outer" aria-hidden="true">
              <span className="word-inner">{part}</span>
            </span>
          );
        }
        return acc;
      }, []);
    }
    if (Array.isArray(node)) return node.flatMap(split);
    if (!React.isValidElement(node)) return [node];
    if (node.type === 'br') return [<br key={_kid++} aria-hidden="true" />];
    return [React.cloneElement(node, {
      key: _kid++,
      'aria-hidden': 'true',
      children: split(node.props.children),
    })];
  }

  React.useEffect(() => {
    if (!window.gsap || !ref.current) return;
    const inners = Array.from(ref.current.querySelectorAll('.word-inner'));
    if (!inners.length) return;
    // Esconde imediatamente
    window.gsap.set(inners, { yPercent: 140 });
    const obs = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting) return;
      obs.disconnect();
      window.gsap.to(inners, { yPercent: 0, duration: 1.6, ease: 'expo.out', stagger: 0.08 });
    }, { threshold: 0.05, rootMargin: '0px 0px -8% 0px' });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);

  const label = flatten(children);
  const rendered = split([].concat(children));
  return (
    <Tag ref={ref} aria-label={label} {...props}>
      {rendered}
    </Tag>
  );
}

// Utilitário: observa um elemento e roda um callback GSAP quando entra na tela
function onVisible(el, callback, opts = {}) {
  if (!el) return () => { };
  const obs = new IntersectionObserver(([entry]) => {
    if (!entry.isIntersecting) return;
    obs.disconnect();
    callback(el);
  }, { threshold: opts.threshold ?? 0.08, rootMargin: opts.rootMargin ?? '0px 0px -8% 0px' });
  obs.observe(el);
  return () => obs.disconnect();
}

function FadeUp({ children, as: Tag = 'div', delay = 0, ...props }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el || !window.gsap) return;
    window.gsap.set(el, { opacity: 0, y: 40 });
    return onVisible(el, () =>
      window.gsap.to(el, { opacity: 1, y: 0, duration: 1.6, delay, ease: 'power3.out' })
    );
  }, []);
  return <Tag ref={ref} {...props}>{children}</Tag>;
}

function Footer() {
  const [instaHover, setInstaHover] = React.useState(false);

  return (
    <footer className="footer">
      <div>
        <WordReveal as="h3">Será um prazer colaborar com você</WordReveal>
        <div className="contacts">
          <HoverBorderGradient pill>comercialine@gmail.com</HoverBorderGradient>
          <HoverBorderGradient pill onClick={() => window.open('https://wa.me/5551989236353?text=Gostaria%20de%20mais%20informa%C3%A7%C3%B5es%20sobre%20os%20servi%C3%A7os%20da%20Line', '_blank')}>51 9 8923.6353</HoverBorderGradient>
        </div>
        <div className="insta"
          onClick={() => window.open('https://www.instagram.com/line.produtora/', '_blank')}
          onMouseEnter={() => setInstaHover(true)}
          onMouseLeave={() => setInstaHover(false)}
          style={{ cursor: 'pointer', position: 'relative', overflow: 'hidden' }}>
          <div style={{
            position: 'absolute',
            inset: 0,
            background: 'radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%)',
            opacity: instaHover ? 1 : 0,
            transition: 'opacity 0.4s ease',
            zIndex: 0
          }} />
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ position: 'relative', zIndex: 1 }}>
            <rect x="3" y="3" width="18" height="18" rx="5" />
            <circle cx="12" cy="12" r="4" />
            <circle cx="17.5" cy="6.5" r="1" fill="white" />
          </svg>
        </div>
      </div>
      <div className="meta">
        <span>Privacy Policy</span>
        <span className="muted">2026, Line</span>
      </div>
    </footer>
  );
}

// Icon set — coherent outline family (1.6 stroke, round caps, 24x24 grid)
function SvcIcon({ name }) {
  const c = { width: 28, height: 28, viewBox: "0 0 24 24", fill: "none", stroke: "#0e0e0e", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" };
  const svgs = {
    // Smartphone — Social Media
    social: <svg {...c}><rect width="14" height="20" x="5" y="2" rx="2" ry="2" /><path d="M12 18h.01" /></svg>,
    // Paintbrush — Design
    design: <svg {...c}><path d="m9.06 11.9 8.07-8.06a2.85 2.85 0 1 1 4.03 4.03l-8.06 8.08" /><path d="M7.07 14.94c-1.66 0-3 1.35-3 3.02 0 1.33-2.5 1.52-2 2.02 1.08 1.1 2.49 2.02 4 2.02 2.2 0 4-1.8 4-4.04a3.01 3.01 0 0 0-3-3.02z" /></svg>,
    // Browser — Sites
    sites: <svg {...c}><rect x="3" y="4" width="18" height="16" rx="2" /><path d="M3 9h18" /><circle cx="6.5" cy="6.5" r="0.6" fill="#0e0e0e" /><circle cx="9" cy="6.5" r="0.6" fill="#0e0e0e" /></svg>,
    // Bar chart with arrow — Tráfego
    trafego: <svg {...c}><path d="M4 20V10" /><path d="M10 20V4" /><path d="M16 20v-7" /><path d="M3 20h18" /><path d="m18 8 3-3-3-3" /></svg>,
    // Server stack — Sistemas
    sistemas: <svg {...c}><rect x="3" y="4" width="18" height="6" rx="1.5" /><rect x="3" y="14" width="18" height="6" rx="1.5" /><circle cx="7" cy="7" r="0.6" fill="#0e0e0e" /><circle cx="7" cy="17" r="0.6" fill="#0e0e0e" /></svg>,
    // SMS Bubble — IA
    ia: <svg {...c}><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /></svg>,
    // Play in frame — Vídeo
    video: <svg {...c}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="m10 9 5 3-5 3z" fill="#0e0e0e" stroke="#0e0e0e" /></svg>,
  };
  return svgs[name] || svgs.sites;
}

function SolutionCard({ icon, title, desc, onClick }) {
  return (
    <div className="sol-card" onClick={onClick}>
      <div className="icon"><SvcIcon name={icon} /></div>
      <div className="t">{title}</div>
      <div className="d">{desc}</div>
    </div>
  );
}

function HoverBorderGradient({ children, onClick, inverse = false, pill = false }) {
  const [hovered, setHovered] = React.useState(false);
  const btnRef = React.useRef(null);
  const sweepRef = React.useRef(null);

  const baseBg = inverse ? '#ffffff' : '#0e0e0e';
  const sweepBg = inverse ? '#0e0e0e' : '#ffffff';
  const baseText = inverse ? '#0e0e0e' : '#ffffff';
  const hoverText = inverse ? '#ffffff' : '#0e0e0e';

  function handleMouseEnter(e) {
    const btn = btnRef.current;
    const sweep = sweepRef.current;
    if (!btn || !sweep) return;
    const rect = btn.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    // Diameter large enough to cover button from any entry corner
    const size = Math.sqrt(rect.width ** 2 + rect.height ** 2) * 2.2;
    // Snap circle to entry point at scale 0 (no transition), then expand
    sweep.style.transition = 'none';
    sweep.style.width = size + 'px';
    sweep.style.height = size + 'px';
    sweep.style.left = (x - size / 2) + 'px';
    sweep.style.top = (y - size / 2) + 'px';
    sweep.style.transform = 'scale(0)';
    sweep.getBoundingClientRect(); // force reflow
    sweep.style.transition = 'transform 1.6s cubic-bezier(0.16, 1, 0.3, 1)';
    sweep.style.transform = 'scale(1)';
    setHovered(true);
  }

  function handleMouseLeave() {
    const sweep = sweepRef.current;
    if (!sweep) return;
    sweep.style.transition = 'transform 0.35s cubic-bezier(0.4, 0, 1, 1)';
    sweep.style.transform = 'scale(0)';
    setHovered(false);
  }

  return (
    <button
      ref={btnRef}
      onClick={onClick}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      style={{
        position: 'relative', display: 'inline-flex', alignItems: 'center',
        justifyContent: 'center', borderRadius: pill ? 18 : 100,
        border: pill ? '1.5px solid #ffffff' : 'none',
        background: baseBg, cursor: 'pointer', overflow: 'hidden',
        minWidth: pill ? 'auto' : 'min(406px, calc(100vw - 48px))',
        padding: pill ? '12px 20px' : '14px 40px',
        fontFamily: 'Urbanist', fontWeight: 700,
        fontSize: pill ? 20 : 18, letterSpacing: '-0.002em',
        color: hovered ? hoverText : baseText,
        transition: 'color 0.4s ease',
        whiteSpace: 'nowrap',
      }}
    >
      {/* Circle expands from the exact mouse entry point — clipped by overflow:hidden */}
      <div
        ref={sweepRef}
        style={{
          position: 'absolute', borderRadius: '50%',
          background: sweepBg, transform: 'scale(0)',
          willChange: 'transform', pointerEvents: 'none',
        }}
      />
      <span style={{ position: 'relative', zIndex: 1 }}>{children}</span>
    </button>
  );
}

function WebGLShader() {
  const isMobile = useIsMobile();
  const canvasRef = React.useRef(null);
  const sceneRef = React.useRef({
    scene: null,
    camera: null,
    renderer: null,
    mesh: null,
    uniforms: null,
    animationId: null,
  });
  const physicsRef = React.useRef({
    targetX: 0.5,
    targetY: 0.5,
    currentX: 0.5,
    currentY: 0.5,
  });

  React.useEffect(() => {
    if (!canvasRef.current || !window.THREE) return;

    const THREE = window.THREE;
    const canvas = canvasRef.current;
    const { current: refs } = sceneRef;

    const vertexShader = `
      attribute vec3 position;
      void main() {
        gl_Position = vec4(position, 1.0);
      }
    `;

    const fragmentShader = `
      precision highp float;
      uniform vec2 resolution;
      uniform float time;
      uniform vec2 mouse; // 0.0 a 1.0
      uniform float mobile; // 1.0 em mobile, 0.0 em desktop

      float random(vec2 st) {
          return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
      }

      void main() {
        vec2 uv = gl_FragCoord.xy / resolution.xy;
        vec2 p = uv * 2.0 - 1.0;
        p.x *= resolution.x / resolution.y;
        
        // Mouse com proporção de tela
        vec2 m = mouse * 2.0 - 1.0;
        m.x *= resolution.x / resolution.y;
        
        float t = time * 0.4;
        
        // INTERAÇÃO COM MOUSE: O mouse mistura o fluido criando um "redemoinho" mais forte
        vec2 mouseDir = p - m;
        float mouseDist = length(mouseDir);
        float mouseEffect = exp(-mouseDist * 2.0); // Raio de ação maior
        p += vec2(-mouseDir.y, mouseDir.x) * mouseEffect * 1.5; // Efeito giratório muito mais forte
        p += mouseDir * mouseEffect * 0.8; // Repulsão mais visível
        
        // Distorção de domínio (Efeito de fluido/Lava Lamp)
        p.x += sin(p.y * 2.5 + t) * 0.3;
        p.y += cos(p.x * 2.0 + t * 0.8) * 0.3;
        
        // Raio X adaptado ao aspect ratio: em portrait mobile o range visível de X
        // é pequeno (ex: 0.46 para 390x844), então escalamos os raios proporcionalmente.
        float axr = min(resolution.x / resolution.y, 1.0);
        // 4 focos principais de luz (Orbs) orbitando lentamente
        vec2 pos1 = vec2(sin(t)*0.8*axr, cos(t*1.2)*0.5);
        vec2 pos2 = vec2(cos(t*1.3)*0.9*axr, sin(t*0.9)*0.6);
        vec2 pos3 = vec2(sin(t*0.7 - 2.0)*0.7*axr, cos(t*1.5)*0.4);
        vec2 pos4 = vec2(cos(t*1.1 + 1.0)*0.6*axr, sin(t*0.8 + 3.0)*0.5);
        
        // O mouse "puxa" e "empurra" as cores com mais força
        pos1 += (m - pos1) * 0.40 * mouseEffect;
        pos2 += (m - pos2) * -0.30 * mouseEffect;
        pos3 += (m - pos3) * 0.30 * mouseEffect;
        pos4 += (m - pos4) * -0.40 * mouseEffect;

        // Caída exponencial para as luzes se misturarem até o infinito
        float b1 = exp(-length(p - pos1) * 1.5);
        float b2 = exp(-length(p - pos2) * 1.3);
        float b3 = exp(-length(p - pos3) * 1.8);
        float b4 = exp(-length(p - pos4) * 1.4);

        // Cores puras da paleta Line
        vec3 c1 = vec3(0.000, 0.486, 0.988); // Azul claro #007CFC
        vec3 c2 = vec3(1.000, 0.569, 0.733); // Rosa #FF91BB
        vec3 c3 = vec3(0.957, 0.718, 0.039); // Amarelo #F4B70A
        vec3 c4 = vec3(0.933, 0.035, 0.016); // Vermelho #EE0904
        
        vec3 bg = vec3(0.0549); // Fundo #0e0e0e
        
        // Mobile: cores mais escuras e sem noise; desktop: brilho original com grain
        float brightness = mix(0.85, 0.32, mobile);
        vec3 color = bg + (c1*b1 + c2*b2 + c3*b3 + c4*b4) * brightness;

        // Vinheta: Escurece suavemente as bordas da tela para ancorar no fundo
        float vignette = 1.0 - smoothstep(0.5, 2.5, length(uv * 2.0 - 1.0));
        color = mix(bg, color, vignette);

        // Brilho extra no local exato do mouse para destacar o movimento
        float mouseGlow = mix(0.08, 0.01, mobile);
        color += vec3(mouseGlow) * exp(-mouseDist * 3.0);

        // Noise/grain animado — apenas no desktop
        float noise = (random(uv + time) - 0.5) * 0.12 * (1.0 - mobile);
        color += noise;
        
        gl_FragColor = vec4(color, 1.0);
      }
    `;

    const initScene = () => {
      refs.scene = new THREE.Scene();
      refs.renderer = new THREE.WebGLRenderer({ canvas });
      refs.renderer.setPixelRatio(isMobile ? 1 : Math.min(window.devicePixelRatio, 2));
      refs.renderer.setClearColor(new THREE.Color(0x0e0e0e));

      refs.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, -1);

      refs.uniforms = {
        resolution: { value: [window.innerWidth, window.innerHeight] },
        time: { value: 0.0 },
        mouse: { value: [0.5, 0.5] },
        mobile: { value: isMobile ? 1.0 : 0.0 },
      };

      const position = [
        -1.0, -1.0, 0.0,
        1.0, -1.0, 0.0,
        -1.0, 1.0, 0.0,
        1.0, -1.0, 0.0,
        -1.0, 1.0, 0.0,
        1.0, 1.0, 0.0,
      ];

      const positions = new THREE.BufferAttribute(new Float32Array(position), 3);
      const geometry = new THREE.BufferGeometry();
      geometry.setAttribute("position", positions);

      const material = new THREE.RawShaderMaterial({
        vertexShader,
        fragmentShader,
        uniforms: refs.uniforms,
        side: THREE.DoubleSide,
      });

      refs.mesh = new THREE.Mesh(geometry, material);
      refs.scene.add(refs.mesh);

      handleResize();
    };

    const animate = () => {
      const phys = physicsRef.current;
      const lerp = (a, b, t) => a + (b - a) * t;

      // Interpolação super sedosa para o mouse
      phys.currentX = lerp(phys.currentX, phys.targetX, 0.05);
      phys.currentY = lerp(phys.currentY, phys.targetY, 0.05);

      if (refs.uniforms) {
        refs.uniforms.time.value += 0.01;
        refs.uniforms.mouse.value = [phys.currentX, phys.currentY];
      }

      if (refs.renderer && refs.scene && refs.camera) {
        refs.renderer.render(refs.scene, refs.camera);
      }
      refs.animationId = requestAnimationFrame(animate);
    };

    const handleResize = () => {
      if (!refs.renderer || !refs.uniforms || !canvasRef.current) return;
      const parent = canvasRef.current.parentElement;
      const width = parent ? parent.clientWidth : window.innerWidth;
      // Aumentamos 300px na altura total para vazar para a próxima seção (só desktop)
      const height = (parent ? parent.clientHeight : window.innerHeight) + (isMobile ? 0 : 300);
      refs.renderer.setSize(width, height, false);
      refs.uniforms.resolution.value = [width, height];
    };

    // No mobile, adia o início do WebGL para o browser terminar o primeiro paint
    // e a animação da logo entrar sem concorrência de GPU
    let startTimer;
    const start = () => {
      initScene();
      animate();
      if (isMobile && canvasRef.current) {
        canvasRef.current.style.transition = 'opacity 1.4s ease';
        canvasRef.current.style.opacity = '1';
      }
    };
    if (isMobile) {
      startTimer = setTimeout(start, 1000);
    } else {
      start();
    }
    window.addEventListener("resize", handleResize);

    // Passa as interações do mouse dinamicamente apenas quando está em cima do Hero
    const handleMouseMove = (e) => {
      const parent = canvasRef.current?.parentElement;
      if (!parent) return;
      const rect = parent.getBoundingClientRect();

      if (e.clientY >= rect.top && e.clientY <= rect.bottom) {
        physicsRef.current.targetX = (e.clientX - rect.left) / rect.width;
        // Invertemos o Y pois o WebGL lê de baixo para cima
        physicsRef.current.targetY = 1.0 - ((e.clientY - rect.top) / rect.height);
      }
    };
    const handleMouseOut = () => {
      physicsRef.current.targetX = 0.5;
      physicsRef.current.targetY = 0.5;
    };
    window.addEventListener("mousemove", handleMouseMove);
    window.addEventListener("mouseout", handleMouseOut);

    return () => {
      clearTimeout(startTimer);
      if (refs.animationId) cancelAnimationFrame(refs.animationId);
      window.removeEventListener("resize", handleResize);
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseout", handleMouseOut);
      if (refs.mesh) {
        refs.scene?.remove(refs.mesh);
        refs.mesh.geometry.dispose();
        if (refs.mesh.material.dispose) refs.mesh.material.dispose();
      }
      refs.renderer?.dispose();
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      style={{
        position: 'absolute',
        top: isMobile ? '0' : '-150px',
        left: 0,
        width: '100%',
        height: isMobile ? '100%' : 'calc(100% + 300px)',
        display: 'block', pointerEvents: 'none', zIndex: 0,
        opacity: isMobile ? 0 : 1,
        WebkitMaskImage: 'linear-gradient(to bottom, #000 85%, transparent 100%)',
        maskImage: 'linear-gradient(to bottom, #000 85%, transparent 100%)'
      }}
    />
  );
}

function TestimonialCarousel() {
  const trackRef = React.useRef(null);
  const isDragging = React.useRef(false);
  const startX = React.useRef(0);
  const scrollLeft = React.useRef(0);

  const baseItems = [
    { name: 'Cliente 1', role: 'Escreva feedback aqui', q: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.' },
    { name: 'Cliente 2', role: 'Escreva feedback aqui', q: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' },
    { name: 'Cliente 3', role: 'Escreva feedback aqui', q: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.' },
  ];

  // Duplicamos a lista múltiplas vezes para criar um efeito de loop suave
  const items = [...baseItems, ...baseItems, ...baseItems, ...baseItems];

  React.useEffect(() => {
    let reqId;
    const track = trackRef.current;
    const play = () => {
      if (!isDragging.current && track && track.children.length > baseItems.length) {
        track.scrollLeft += 0.8; // Velocidade suave do auto-scroll

        // Loop contínuo
        const singleSetWidth = track.children[baseItems.length].offsetLeft - track.children[0].offsetLeft;
        if (track.scrollLeft >= singleSetWidth) {
          track.scrollLeft -= singleSetWidth;
        }
      }
      reqId = requestAnimationFrame(play);
    };
    reqId = requestAnimationFrame(play);
    return () => cancelAnimationFrame(reqId);
  }, [baseItems.length]);

  const onMouseDown = (e) => {
    isDragging.current = true;
    startX.current = e.pageX - trackRef.current.offsetLeft;
    scrollLeft.current = trackRef.current.scrollLeft;
  };
  const onMouseLeave = () => {
    isDragging.current = false;
  };
  const onMouseUp = () => { isDragging.current = false; };
  const onMouseMove = (e) => {
    if (!isDragging.current) return;
    e.preventDefault();
    const x = e.pageX - trackRef.current.offsetLeft;
    const walk = (x - startX.current) * 1.5; // Aceleração do arrasto
    trackRef.current.scrollLeft = scrollLeft.current - walk;
  };

  return (
    <div
      className="testi"
      ref={trackRef}
      onMouseDown={onMouseDown}
      onMouseLeave={onMouseLeave}
      onMouseUp={onMouseUp}
      onMouseMove={onMouseMove}
      onTouchStart={() => { isDragging.current = true; }}
      onTouchEnd={() => { isDragging.current = false; }}
    >
      {items.map((t, i) => (
        <div key={i} className="card">
          <div className="row">
            <div className="avatar" />
            <div>
              <div className="name">{t.name}</div>
              <div className="role">{t.role}</div>
            </div>
          </div>
          <hr />
          <div className="q">{t.q}</div>
        </div>
      ))}
    </div>
  );
}

// Grade de Reels (3 por coluna)
function ReelsGrid() {
  const items = [
    { id: '1194100027', title: 'Reel 10', platform: 'vimeo' },
    { id: '1189239634', title: 'Reel 11', platform: 'vimeo' },
    { id: '1194147383', title: 'Reel 08', platform: 'vimeo' },
    { id: 'J323thLmh5A', title: 'Reel 01' },
    { id: 'W-5Szihyq7Q', title: 'Reel 02' },
    { id: 'y6Tgp3P-xC8', title: 'Reel 03' },
    { id: '8e8LagmNCcI', title: 'Reel 04' },
    { id: 'wVjYrR3MIZc', title: 'Reel 05' },
    { id: '1194147946', title: 'Reel 06', platform: 'vimeo' },
  ];

  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: 'repeat(auto-fill, minmax(min(320px, 100%), 1fr))',
      gap: '28px',
      padding: '0 clamp(16px, 10vw, 149px)',
      margin: '96px 0'
    }}>
      {items.map((item, i) => (
        <div key={i} style={{ borderRadius: 24, overflow: 'hidden', background: '#000', aspectRatio: '9/16' }}>
          {item.platform === 'vimeo' ? (
            <iframe
              width="100%"
              height="100%"
              src={`https://player.vimeo.com/video/${item.id}?autoplay=1&loop=1&muted=1&autopause=0`}
              title={item.title}
              frameBorder="0"
              allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media"
              allowFullScreen
            ></iframe>
          ) : (
            <iframe
              width="100%"
              height="100%"
              src={`https://www.youtube.com/embed/${item.id}?autoplay=1&mute=1&loop=1&playlist=${item.id}&controls=1&modestbranding=1&playsinline=1&rel=0`}
              title={item.title}
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          )}
        </div>
      ))}
    </div>
  );
}

// Home page — based on /UI/Desktop---2/index.jsx (figma node 104:29)
// Hook: esconde targets imediatamente, anima quando o triggerRef entra na tela
function useReveal(triggerRef, getTargets, fromVars, toVars) {
  React.useEffect(() => {
    if (!window.gsap) return;
    const triggerEl = triggerRef?.current;
    if (!triggerEl) return;
    const rawTargets = typeof getTargets === 'function' ? getTargets() : getTargets;
    const targets = (Array.isArray(rawTargets) ? rawTargets : [rawTargets]).filter(Boolean);
    if (!targets.length) return;
    window.gsap.set(targets, fromVars);
    return onVisible(triggerEl, () => window.gsap.to(targets, toVars));
  }, []);
}

function HomePage({ setRoute }) {
  const isMobile = useIsMobile();
  const heroLogoRef = React.useRef(null);
  const solGridRef = React.useRef(null);
  const cardsRef = React.useRef(null);
  const videosTitleRef = React.useRef(null);
  const curvedBodyRef = React.useRef(null);
  const arcoRef = React.useRef(null);
  const videosGridRef = React.useRef(null);
  const solCtaRef = React.useRef(null);
  const curvedCtaRef = React.useRef(null);
  const videosCtaRef = React.useRef(null);
  const artCtaRef = React.useRef(null);
  const testiRef = React.useRef(null);
  const testiCtaRef = React.useRef(null);

  // Hero entrance — CSS animation no mobile (compositor thread, imune ao WebGL)
  // GSAP com subida completa apenas no desktop
  React.useEffect(() => {
    if (isMobile || !window.gsap) return;
    window.gsap.fromTo(heroLogoRef.current,
      { opacity: 0, y: 100, scale: 0.9 },
      { opacity: 1, y: 0, scale: 1, duration: 2.6, ease: 'power4.out', delay: 0.3 }
    );
  }, []);

  // Sol-cards stagger
  useReveal(solGridRef,
    () => solGridRef.current ? [...solGridRef.current.querySelectorAll('.sol-card')] : [],
    { opacity: 0, y: 60 },
    { opacity: 1, y: 0, duration: 1.4, stagger: 0.13, ease: 'power3.out', clearProps: 'transform' });

  // CTA soluções
  useReveal(solCtaRef, () => solCtaRef.current,
    { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' });

  // Parágrafo curved
  useReveal(curvedBodyRef, () => curvedBodyRef.current,
    { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 1.6, ease: 'power3.out' });

  // Arco (diagrama de processo)
  useReveal(arcoRef, () => arcoRef.current,
    { opacity: 0, y: 50, scale: 0.97 }, { opacity: 1, y: 0, scale: 1, duration: 1.9, ease: 'expo.out' });

  // CTA curved
  useReveal(curvedCtaRef, () => curvedCtaRef.current,
    { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' });

  // "Todo grande vídeo" título — word-by-word mask reveal
  useReveal(videosTitleRef,
    () => videosTitleRef.current ? [...videosTitleRef.current.querySelectorAll('.word-inner')] : [],
    { yPercent: 140 },
    { yPercent: 0, duration: 1.6, ease: 'expo.out', stagger: 0.08 });

  // Videos grid items stagger
  useReveal(videosGridRef,
    () => videosGridRef.current ? [...videosGridRef.current.querySelectorAll('.ph')] : [],
    { opacity: 0, y: 40, scale: 0.98 },
    { opacity: 1, y: 0, scale: 1, duration: 1.4, stagger: 0.14, ease: 'power3.out' });

  // CTA vídeos
  useReveal(videosCtaRef, () => videosCtaRef.current,
    { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' });

  // Art images stagger
  useReveal(cardsRef,
    () => cardsRef.current ? [...cardsRef.current.querySelectorAll('img')] : [],
    { opacity: 0, y: 50, scale: 0.97 },
    { opacity: 1, y: 0, scale: 1, duration: 1.6, stagger: 0.17, ease: 'expo.out', clearProps: 'transform' });

  // CTA arte
  useReveal(artCtaRef, () => artCtaRef.current,
    { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' });

  // Testimonials
  useReveal(testiRef, () => testiRef.current,
    { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 1.6, ease: 'power3.out' });
  useReveal(testiCtaRef, () => testiCtaRef.current,
    { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' });

  return (
    <div className="page-dark">
      {/* HERO */}
      <section className="hero" style={{ position: 'relative', overflow: 'visible', padding: 0, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {isMobile && <style>{`@keyframes hero-logo-fade { from { opacity: 0 } to { opacity: 1 } }`}</style>}
        <WebGLShader />
        <h1 ref={heroLogoRef} className="title" style={{ position: 'relative', zIndex: 10, margin: 0, opacity: 0, ...(isMobile && { animation: 'hero-logo-fade 1.4s ease 0.3s forwards' }) }}>
          <img src="assets/logo.png" alt="Line" style={{ width: '520px', maxWidth: '90vw', height: 'auto', display: 'block' }} />
        </h1>
      </section>

      {/* NOSSAS SOLUÇÕES */}
      <section className="sol-section">
        <WordReveal as="h2" className="h-lg" style={{ margin: 0, fontSize: 'clamp(32px, 6vw, 88px)', lineHeight: '1.0' }}>Nossas soluções</WordReveal>
        <div className="sol-grid" ref={solGridRef}>
          <div className="sol-row">
            <SolutionCard icon="social" title="Social Media" desc="Gestão de redes sociais com criação de estratégia, planejamento de conteúdo, produção de posts e acompanhamento de resultados." onClick={() => setRoute('social')} />
            <SolutionCard icon="design" title="Design" desc="Identidade visual, cards, carrosséis e manipulações com IA, com uma estética consistente que traduz a sua marca em cada peça." onClick={() => setRoute('design')} />
            <SolutionCard icon="trafego" title="Tráfego Pago" desc="Configuração, gestão e otimização de campanhas no Meta Ads e Google Ads, com criativos e relatórios completos." onClick={() => setRoute('trafego')} />
            <SolutionCard icon="sistemas" title="Criação de Sistemas" desc="ERPs, CRMs, plataformas web e apps sob medida para o jeito único que o seu negócio funciona." onClick={() => setRoute('sistemas')} />
          </div>
          <div className="sol-row">
            <SolutionCard icon="sites" title="Criação de Sites" desc="Desenvolvimento de sites profissionais, modernos e estratégicos para fortalecer a presença digital e gerar mais oportunidades de negócio." onClick={() => setRoute('sites')} />
            <SolutionCard icon="ia" title="Atendimento por IA" desc="Uma IA treinada com a identidade e o tom da sua marca, atendendo 24h no WhatsApp, Instagram, site e e-mail." onClick={() => setRoute('ia')} />
            <SolutionCard icon="video" title="Criação de Vídeos" desc="Captação e edição de vídeos pensados com intenção — cor, trilha, motion e ritmo para que cada instante permaneça." onClick={() => setRoute('videos')} />
          </div>
        </div>
        <div ref={solCtaRef} className="center" style={{ marginTop: 56 }}>
          <HoverBorderGradient inverse onClick={() => setRoute('social')}>Conheça todos os nossos serviços</HoverBorderGradient>
        </div>
      </section>

      {/* Pare de postar por postar — white curved */}
      <section className="curved">
        <WordReveal as="h2" className="h-lg" style={{ color: '#0e0e0e', fontSize: 'clamp(32px, 6vw, 88px)', lineHeight: '1.0', margin: '0 0 16px' }}>
          Pare de <em style={{ fontStyle: 'italic' }}>postar por postar.</em><br />
          Comece a construir presença.
        </WordReveal>
        <p ref={curvedBodyRef} className="body-lg" style={{ textAlign: 'center', maxWidth: 720, margin: '0 auto', color: '#0e0e0e' }}>
          Um processo pensado em cinco etapas para transformar sua presença digital em algo que permanece.
        </p>

        <div ref={arcoRef} style={{ display: 'flex', justifyContent: 'center', margin: '80px 0' }}>
          <img
            src="assets/arco.png"
            alt="Nosso Processo"
            style={{ maxWidth: '100%', width: '800px', height: 'auto', objectFit: 'contain' }}
          />
        </div>

        <div ref={curvedCtaRef} className="center" style={{ marginTop: 96 }}>
          <HoverBorderGradient onClick={() => setRoute('social')}>Construa agora a sua presença</HoverBorderGradient>
        </div>
      </section>

      {/* Todo grande vídeo */}
      <section style={{ background: '#0e0e0e', color: '#fff', padding: 'clamp(64px,8vw,120px) clamp(16px,2vw,32px) 96px', borderRadius: 'clamp(48px,8vw,128px) clamp(48px,8vw,128px) 0 0' }}>
        <style>
          {`
            @keyframes gradientMove {
              0% { background-position: 100% 50%; }
              100% { background-position: 0% 50%; }
            }
          `}
        </style>
        <h2 ref={videosTitleRef} className="h-xxl" style={{ fontSize: 'clamp(32px, 6vw, 88px)', lineHeight: '1.0', margin: 0 }} aria-label="Todo grande vídeo tem algo em comum: intenção.">
          {['Todo', 'grande', 'vídeo'].map((w, i) => (
            <React.Fragment key={`vt1-${i}`}>{i > 0 && ' '}<span className="word-outer" aria-hidden="true"><span className="word-inner">{w}</span></span></React.Fragment>
          ))}
          <br aria-hidden="true" />
          {['tem', 'algo', 'em', 'comum:'].map((w, i) => (
            <React.Fragment key={`vt2-${i}`}>{i > 0 && ' '}<span className="word-outer" aria-hidden="true"><span className="word-inner">{w}</span></span></React.Fragment>
          ))}
          <br aria-hidden="true" />
          <em aria-hidden="true" style={{ fontStyle: 'italic' }}>
            <span className="word-outer"><span className="word-inner">intenção.</span></span>
          </em>
        </h2>
        <div ref={videosGridRef} className="videos-grid" style={{ padding: '96px 0 0' }}>
          <div className="ph dark tall" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://www.youtube.com/embed/8-cR-1HoPrw?autoplay=1&mute=1&loop=1&playlist=8-cR-1HoPrw&controls=1&modestbranding=1&playsinline=1&rel=0"
              title="Line Video Showcase"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark tall" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://www.youtube.com/embed/ZmE22jld5_4?autoplay=1&mute=1&loop=1&playlist=ZmE22jld5_4&controls=1&modestbranding=1&playsinline=1&rel=0"
              title="Line Video Showcase 2"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark tall" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://www.youtube.com/embed/mmfyIhA2pSk?autoplay=1&mute=1&loop=1&playlist=mmfyIhA2pSk&controls=1&modestbranding=1&playsinline=1&rel=0"
              title="Line Video Showcase 3"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://player.vimeo.com/video/1194100027?autoplay=1&loop=1&muted=1&autopause=0"
              title="Vídeo da Fel"
              frameBorder="0"
              allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://www.youtube.com/embed/W-5Szihyq7Q?autoplay=1&mute=1&loop=1&playlist=W-5Szihyq7Q&controls=1&modestbranding=1&playsinline=1&rel=0"
              title="Line Reel 2"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://www.youtube.com/embed/J323thLmh5A?autoplay=1&mute=1&loop=1&playlist=J323thLmh5A&controls=1&modestbranding=1&playsinline=1&rel=0"
              title="Tchê ChalEira"
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
              allowFullScreen
            ></iframe>
          </div>
          <div className="ph dark" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
            <iframe
              width="100%"
              height="100%"
              src="https://player.vimeo.com/video/1194147946?autoplay=1&loop=1&muted=1&autopause=0"
              title="Line Reel 4"
              frameBorder="0"
              allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media"
              allowFullScreen
            ></iframe>
          </div>
        </div>
        <div ref={videosCtaRef} className="center" style={{ marginTop: 56 }}>
          <HoverBorderGradient inverse onClick={() => setRoute('videos')}>Veja nossos vídeos</HoverBorderGradient>
        </div>
      </section>

      {/* Todo pedaço de arte */}
      <section className="todo-pedaco" style={{ background: '#0e0e0e', color: '#fff' }}>
        <WordReveal as="h2" className="h-xxl" style={{ fontSize: 'clamp(32px, 6vw, 88px)', lineHeight: '1.0', textAlign: 'center', margin: '0 0 72px' }}>
          Todo pedaço de arte<br />nos conta uma história.
        </WordReveal>
        <div className="cards" ref={cardsRef}>
          <img src="assets/páscoa.jpg" alt="Páscoa" />
          <InteractiveSiteMockup image="assets/idv_zuno.png" previewImage="assets/idv_zuno_preview.jpg" title="Zuno" previewZoom={isMobile ? '160%' : '1167px'} previewOffsetY={isMobile ? '-35px' : '-180px'} containerStyle={isMobile ? { width: '100%', height: 'auto', aspectRatio: '1/1', borderRadius: 24 } : { height: '75vh', maxHeight: '75vh', width: 'auto', aspectRatio: '1/1', borderRadius: 24 }} />
          <img src="assets/imobiliária.jpg" alt="Imobiliária" />
          <img src="assets/oneb.jpg" alt="OneB" />
          <img src="assets/natal.jpg" alt="Natal" />
          <InteractiveSiteMockup image="assets/idv_padaria.png" previewImage="assets/idv_padaria_preview.jpg" title="Padaria" previewZoom={isMobile ? '160%' : '1167px'} previewOffsetY={isMobile ? '-35px' : '-180px'} containerStyle={isMobile ? { width: '100%', height: 'auto', aspectRatio: '1/1', borderRadius: 24 } : { height: '75vh', maxHeight: '75vh', width: 'auto', aspectRatio: '1/1', borderRadius: 24 }} />
        </div>
        <div ref={artCtaRef} className="center" style={{ marginTop: 56 }}>
          <HoverBorderGradient inverse onClick={() => setRoute('design')}>Conheça o nosso trabalho</HoverBorderGradient>
        </div>
      </section>

      {/* Testimonials */}
      <section style={{ background: '#0e0e0e', padding: '120px 0 64px' }}>
        <WordReveal as="h2" className="h-lg" style={{ marginBottom: 56, fontSize: 'clamp(32px, 6vw, 88px)', lineHeight: '1.0', padding: '0 clamp(20px, 6vw, 96px)' }}>A transformação que a Line gera no seu negócio</WordReveal>
        <div ref={testiRef}><TestimonialCarousel /></div>
        <div ref={testiCtaRef} className="center" style={{ marginTop: 24, padding: '0 32px' }}>
          <HoverBorderGradient inverse onClick={() => window.open('https://wa.me/5551989236353?text=Gostaria%20de%20mais%20informa%C3%A7%C3%B5es%20sobre%20os%20servi%C3%A7os%20da%20Line', '_blank')}>Quero solicitar um orçamento!</HoverBorderGradient>
        </div>
      </section>

      <Footer />
    </div>
  );
}

// Service pages — map: todos, social, videos, design, sites, sistemas, ia, trafego, contato
function ServiceTabs({ route, setRoute }) {
  const [dropOpen, setDropOpen] = React.useState(false);
  const items = [
    { id: 'social', label: 'Social Media' },
    { id: 'videos', label: 'Criação de Vídeos' },
    { id: 'design', label: 'Design' },
    { id: 'sites', label: 'Criação de Site' },
    { id: 'trafego', label: 'Tráfego Pago' },
    { id: 'ia', label: 'Atendimento de IA' },
    { id: 'sistemas', label: 'Criação de Sistemas' },
  ];
  const current = items.find(it => it.id === route) || items[0];

  return (
    <div>
      <div className="heading">Nossos serviços</div>

      {/* Desktop: carrossel de tabs */}
      <div className="tabs tabs-desktop">
        {items.map(it => (
          <button
            key={it.id}
            className={route === it.id ? 'active' : ''}
            onClick={() => setRoute(it.id)}
          >{it.label}</button>
        ))}
      </div>

      {/* Mobile: dropdown */}
      <div className="tabs-mobile-wrap" style={{ position: 'relative', margin: '0 clamp(16px, 5vw, 32px) 40px' }}>
        <button
          onClick={() => setDropOpen(o => !o)}
          style={{
            width: '100%', display: 'flex', alignItems: 'center',
            justifyContent: 'space-between', padding: '11px 16px',
            background: '#fff', border: '1.5px solid rgba(14,14,14,0.18)',
            borderRadius: dropOpen ? '12px 12px 0 0' : 12,
            fontFamily: 'Urbanist', fontSize: 16, fontWeight: 600,
            color: '#0e0e0e', cursor: 'pointer', letterSpacing: '-0.01em',
          }}
        >
          <span>{current.label}</span>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
            stroke="#0e0e0e" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"
            style={{ transform: dropOpen ? 'rotate(180deg)' : 'none', transition: 'transform 0.22s ease', flexShrink: 0 }}
          >
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </button>
        {dropOpen && (
          <div style={{
            position: 'absolute', top: '100%', left: 0, right: 0, zIndex: 200,
            background: '#fff', border: '1.5px solid rgba(14,14,14,0.18)',
            borderTop: 'none', borderRadius: '0 0 12px 12px', overflow: 'hidden',
          }}>
            {items.filter(it => it.id !== route).map(it => (
              <button
                key={it.id}
                onClick={() => { setRoute(it.id); setDropOpen(false); }}
                style={{
                  width: '100%', padding: '11px 16px',
                  background: 'transparent', border: 'none',
                  borderTop: '1px solid rgba(14,14,14,0.08)',
                  fontFamily: 'Urbanist', fontSize: 15, fontWeight: 500,
                  color: '#0e0e0e', cursor: 'pointer', textAlign: 'left',
                  letterSpacing: '-0.01em',
                }}
              >{it.label}</button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function PageFrame({ children, setRoute, route }) {
  const frameRef = React.useRef(null);

  React.useEffect(() => {
    if (!window.gsap) return;
    const el = frameRef.current;
    if (!el) return;
    const cleanups = [];

    // Helper: esconde e observa; quando entra na tela, anima com stagger
    const reveal = (targets, from, to, triggerEl) => {
      const arr = (Array.isArray(targets) ? targets : [targets]).filter(Boolean);
      if (!arr.length) return;
      window.gsap.set(arr, from);
      cleanups.push(onVisible(triggerEl || arr[0], () => window.gsap.to(arr, to)));
    };

    // .big title — anima no mount (sem esperar scroll)
    const big = el.querySelector('.big');
    if (big) {
      window.gsap.set(big, { opacity: 0, y: 50 });
      const t = window.gsap.to(big, { opacity: 1, y: 0, duration: 1.5, ease: 'power3.out', delay: 0.2 });
      cleanups.push(() => t.kill());
    }

    // two-col: stagger nas colunas
    const twoCol = el.querySelector('.two-col');
    if (twoCol) reveal([...twoCol.children],
      { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 1.4, stagger: 0.22, ease: 'power3.out' }, twoCol);

    // media-strip items
    const mediaStrip = el.querySelector('.media-strip');
    if (mediaStrip) reveal([...mediaStrip.children],
      { opacity: 0, y: 60, scale: 0.98 }, { opacity: 1, y: 0, scale: 1, duration: 1.6, stagger: 0.17, ease: 'expo.out' }, mediaStrip);

    // design-gallery e design-hero
    const gallery = el.querySelector('.design-gallery');
    if (gallery) reveal([...gallery.children],
      { opacity: 0, y: 40, scale: 0.97 }, { opacity: 1, y: 0, scale: 1, duration: 1.4, stagger: 0.14, ease: 'power3.out', clearProps: 'transform' }, gallery);

    const designHero = el.querySelector('.design-hero');
    if (designHero) reveal([...designHero.children],
      { opacity: 0, y: 40, scale: 0.97 }, { opacity: 1, y: 0, scale: 1, duration: 1.4, stagger: 0.14, ease: 'power3.out', clearProps: 'transform' }, designHero);

    // brands
    const brandsRow = el.querySelector('.brands .row');
    if (brandsRow) reveal([...brandsRow.children],
      { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 1.4, stagger: 0.17, ease: 'power3.out' }, el.querySelector('.brands'));

    // partners, traf-highlight, closing, closing-cta
    [
      [el.querySelector('.partners'), { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 1.6, ease: 'power3.out' }],
      [el.querySelector('.traf-highlight'), { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 1.6, ease: 'power3.out' }],
      [el.querySelector('.closing'), { opacity: 0, y: 30 }, { opacity: 1, y: 0, duration: 1.6, ease: 'power3.out' }],
      [el.querySelector('.closing-cta'), { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 1.3, ease: 'power3.out' }],
    ].forEach(([target, from, to]) => { if (target) reveal([target], from, to); });

    return () => cleanups.forEach(fn => fn());
  }, [route]);

  return (
    <div ref={frameRef} className="page-light" style={{ position: 'relative' }}>
      <button
        onClick={() => setRoute('home')}
        style={{
          position: 'absolute',
          top: '32px',
          left: '32px',
          width: '48px',
          height: '48px',
          backgroundColor: '#0e0e0e',
          borderRadius: '50%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          border: 'none',
          cursor: 'pointer',
          zIndex: 50
        }}
        title="Voltar para a Home"
      >
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M19 12H5" />
          <path d="M12 19l-7-7 7-7" />
        </svg>
      </button>
      <section className="svc">
        <ServiceTabs route={route} setRoute={setRoute} />
        {children}
      </section>
      <div style={{ background: '#0e0e0e' }}>
        <Footer />
      </div>
    </div>
  );
}

// ====== SOCIAL ======
function SocialPage({ setRoute }) {
  return (
    <PageFrame route="social" setRoute={setRoute}>
      <WordReveal as="div" className="big">Presença que permanece, conteúdo que conecta</WordReveal>
      <div style={{ padding: '0 clamp(16px, 8vw, 125px)' }}>
        <div className="ph" style={{ height: 575, borderRadius: 28 }}>feed · identidade social</div>
      </div>
      <div className="two-col" style={{ marginTop: 120 }}>
        <div>
          <WordReveal as="h3">A sua história merece ser contada todos os dias</WordReveal>
          <p>{`As redes sociais são onde a história da sua empresa acontece. Mas poucos sabem transformá-los em algo que fica. Na Line, cada publicação é pensada para ir além do feed, para criar um laço entre a sua marca e as pessoas que um dia vão escolhê-la.\nDesenvolvemos estratégia de conteúdo, identidade visual para redes sociais, calendário editorial, produção de copies e gestão completa dos perfis. Tudo para que a sua presença digital não seja apenas frequente, mas seja memorável.`}</p>
        </div>
        <div className="media">
          <div className="ph" style={{ height: '100%', borderRadius: 28 }}>case · social</div>
        </div>
      </div>

      <div className="brands">
        <WordReveal as="h2">Marcas que já eternizamos</WordReveal>
        <div className="row">
          <div className="brand-logo-wrapper"><img src="assets/partner_logo.png" alt="partner" /></div>
          <div className="brand-logo-wrapper"><img src="assets/eurohome_logo.png" alt="eurohome" /></div>
          <div className="brand-logo-wrapper"><img src="assets/shopping_logo.png" alt="shopping" /></div>
          <div className="brand-logo-wrapper"><img src="assets/space_logo.png" alt="space" /></div>
        </div>
      </div>

      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20construir%20a%20minha%20presen%C3%A7a%20no%20digital%20com%20a%20Line', '_blank')}>Quero construir minha presença</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== DESIGN ======
function DesignPage({ setRoute }) {
  const isMobile = useIsMobile();
  const imgStyle = isMobile
    ? { width: '100%', height: 'auto', display: 'block', borderRadius: '24px' }
    : { width: '100%', height: '676px', objectFit: 'cover', borderRadius: '39px' };
  return (
    <PageFrame route="design" setRoute={setRoute}>
      <WordReveal as="div" className="big">Cada peça, uma história para contar.</WordReveal>
      <div className="design-hero">
        <img src="assets/páscoa.jpg" alt="Páscoa" style={imgStyle} />
        <img src="assets/hamburguer.jpg" alt="Hamburguer" style={imgStyle} />
      </div>
      <div className="two-col">
        <div>
          <WordReveal as="h3">Design não é só um post bonito.</WordReveal>
          <p>{`O visual de uma marca é o seu primeiro idioma. Antes de qualquer palavra, é a estética que diz quem você é e se vale a pena ficar.\nCriamos cards estáticos para feed com identidade consistente, carrosséis pensados para engajar, salvar e compartilhar. E para composições que desafiam o ordinário, usamos Manipulação com IA para criar imagens, cenários e elementos únicos que só existem porque foram imaginados primeiro.`}</p>
        </div>
      </div>

      <WordReveal as="div" className="big" style={{ marginTop: 120, marginBottom: 12, maxWidth: 'none', whiteSpace: isMobile ? 'normal' : 'nowrap' }}>A sua marca tem o visual que merece?</WordReveal>
      <p style={{ textAlign: 'center', width: '100%', margin: '0 0 64px', fontSize: 'clamp(16px, 1.4vw, 20px)', color: '#0e0e0e' }}>Para marcas que estão nascendo ou se reinventando, desenvolvemos a Identidade Visual completa.</p>

      <div className="design-gallery">
        {[
          'idv_angulo.png',
          'idv_zuno.png',
          'idv_padaria.png',
          'idv_flare.png',
        ].map((file, i, arr) => (
          <div key={file}>
            <InteractiveSiteMockup image={`assets/${file}`} previewImage={`assets/${file.replace('.png', '_preview.jpg')}`} title="" previewZoom={isMobile ? '160%' : '1167px'} previewOffsetY={isMobile ? '-35px' : '-120px'} containerStyle={isMobile ? { width: '100%', height: 'auto', aspectRatio: '1/1', borderRadius: 24 } : {}} />
          </div>
        ))}
      </div>

      <div className="closing-cta" style={{ marginTop: 96 }}><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20que%20minha%20empresa%20tenha%20um%20design%20que%20permanece', '_blank')}>Quero um design que permanece</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== SITES ======
function InteractiveSiteMockup({ image, previewImage, title, previewZoom = '100%', previewOffsetY = '0px', containerStyle = {} }) {
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const [isHovered, setIsHovered] = React.useState(false);
  const cardBg = previewImage || image;

  // Travar o scroll da página de fundo enquanto estiver em tela cheia
  React.useEffect(() => {
    if (isFullscreen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }
    return () => { document.body.style.overflow = ''; };
  }, [isFullscreen]);

  return (
    <>
      {/* Hero / Miniatura Estática */}
      <div
        onMouseEnter={() => setIsHovered(true)}
        onMouseLeave={() => setIsHovered(false)}
        onClick={() => setIsFullscreen(true)}
        style={{
          position: 'relative', width: '100%', height: '688px',
          borderRadius: '28px', overflow: 'hidden', background: '#0e0e0e',
          cursor: 'pointer',
          boxShadow: isHovered ? '0 20px 40px rgba(0,0,0,0.2)' : '0 10px 30px rgba(0,0,0,0.1)',
          transition: 'all 0.4s ease',
          ...containerStyle
        }}
      >
        {/* Imagem de Fundo (com animação de zoom) */}
        <div style={{
          position: 'absolute', inset: 0,
          backgroundImage: `url(${cardBg})`, backgroundSize: previewZoom === 'contain' ? 'contain' : `${previewZoom} auto`,
          backgroundPosition: `center ${previewOffsetY}`, backgroundRepeat: 'no-repeat',
          transform: isHovered ? 'scale(1.03)' : 'scale(1)',
          transition: 'transform 0.6s cubic-bezier(0.16, 1, 0.3, 1)'
        }} />

        {/* Overlay Escuro ao passar o mouse */}
        <div style={{
          position: 'absolute', inset: 0,
          background: isHovered ? 'rgba(0,0,0,0.3)' : 'rgba(0,0,0,0.05)',
          transition: 'background 0.4s ease', zIndex: 10
        }} />

        {/* Ícone de Tela Cheia */}
        <div style={{
          position: 'absolute', top: 24, right: 24, zIndex: 20,
          width: 48, height: 48, borderRadius: '50%',
          background: 'rgba(14,14,14,0.6)', backdropFilter: 'blur(8px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          opacity: isHovered ? 1 : 0, transform: isHovered ? 'scale(1)' : 'scale(0.8)',
          transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)'
        }}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M15 3h6v6"></path>
            <path d="M9 21H3v-6"></path>
            <path d="M21 3l-7 7"></path>
            <path d="M3 21l7-7"></path>
          </svg>
        </div>
      </div>

      {/* Tela Cheia Interativa */}
      {isFullscreen && (
        <div style={{
          position: 'fixed', inset: 0, zIndex: 99999, background: '#0e0e0e', overflowY: 'auto', padding: '40px 0'
        }}>
          <button
            onClick={() => setIsFullscreen(false)}
            style={{
              position: 'fixed', top: '32px', left: '32px', width: '48px', height: '48px',
              backgroundColor: '#0e0e0e', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center',
              border: 'none', cursor: 'pointer', zIndex: 100000,
              boxShadow: '0 4px 12px rgba(0,0,0,0.3)'
            }}
            title="Fechar site"
          >
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <line x1="18" y1="6" x2="6" y2="18"></line>
              <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
          </button>
          <img
            src={image}
            alt={title}
            style={{ width: '90%', height: 'auto', maxWidth: 'none', maxHeight: 'none', objectFit: 'unset', display: 'block', margin: '0 auto' }}
          />
        </div>
      )}
    </>
  );
}

function SitesPage({ setRoute }) {
  const isMobile = useIsMobile();
  const siteCardStyle = isMobile ? { height: '220px' } : {};
  return (
    <PageFrame route="sites" setRoute={setRoute}>
      <WordReveal as="div" className="big">O seu site à altura do que você entrega.</WordReveal>
      <div className="media-strip">
        <InteractiveSiteMockup image="assets/introdução_site.png" previewImage="assets/introdução_site_preview.jpg" title="Introdução Site" containerStyle={siteCardStyle} />
        <InteractiveSiteMockup image="assets/partner_site.png" previewImage="assets/partner_site_preview.jpg" title="Partner Site" containerStyle={siteCardStyle} />
        <InteractiveSiteMockup image="assets/burguer_site.png" previewImage="assets/burguer_site_preview.jpg" title="Burger" containerStyle={siteCardStyle} />
      </div>
      <div className="two-col">
        <div>
          <WordReveal as="h3">Um site que conta quem você é antes de você falar</WordReveal>
          <p>{`Criamos sites institucionais que posicionam e geram credibilidade, landing pages construídas para converter visitantes em clientes, e-commerces pensados para transformar navegação em venda, e portfólios que traduzem visualmente o valor do seu trabalho.\nCada projeto nasce de um briefing profundo e termina em uma entrega que une estética, performance e identidade, criando uma linha que conecta a sua marca a quem a acessa.`}</p>
        </div>
      </div>
      <div className="media-strip">
        <InteractiveSiteMockup image="assets/heitor_site.png" previewImage="assets/heitor_site_preview.jpg" title="Heitor" previewZoom="125%" containerStyle={siteCardStyle} />
      </div>
      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20criar%20um%20site%20que%20me%20representa', '_blank')}>Quero um site que me representa</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== CHATBOT COMPONENT ======

// Substitua pelo valor da sua chave de API — console.anthropic.com
const ANTHROPIC_API_KEY = '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';

const CHAT_SYSTEM_PROMPT = `Você é a Lia, parte da equipe da Line, uma agência de marketing digital em Porto Alegre.

Sobre a Line:
- Serviços: Social Media, Design, Tráfego Pago (Meta Ads / Google Ads), Criação de Sites, Criação de Sistemas, Vídeos e Atendimento por IA
- Contato: WhatsApp 51 9 8923.6353 | comercialine@gmail.com | Instagram @line.produtora
- Em sistemas e IA, a Line trabalha em parceria com a Navena (tecnologia)

Como você escreve:
- Escreve como uma pessoa real digitando numa conversa, sem formalidade
- Português brasileiro natural, às vezes com gírias leves quando cabe
- Respostas curtas e diretas, sem enrolação
- NUNCA usa travessão (esse símbolo: —). Jamais. Use vírgula, ponto ou reescreva a frase
- Sem frases de efeito, sem filosofar, sem encerrar com reflexões bonitas
- Nunca diz "Como uma IA..." ou "Sou programada para..." ou "Como assistente virtual..."
- Não começa respostas com "Claro!", "Certamente!", "Ótima pergunta!", "Com certeza!" ou similares
- Você pode responder QUALQUER pergunta, não só sobre marketing
- Quando falar da Line, faz de forma natural, sem soar como propaganda
- Para orçamentos e valores, diz pra entrar em contato pelo WhatsApp`;

function IAChatBot() {
  const [messages, setMessages] = React.useState([
    { role: 'assistant', text: 'Olá, como a Line pode te ajudar hoje?' }
  ]);
  const [input, setInput] = React.useState('');
  const [isStreaming, setIsStreaming] = React.useState(false);
  const chatWindowRef = React.useRef(null);

  const scrollToBottom = () => {
    if (chatWindowRef.current) {
      chatWindowRef.current.scrollTo({
        top: chatWindowRef.current.scrollHeight,
        behavior: "smooth"
      });
    }
  };

  React.useEffect(() => {
    scrollToBottom();
  }, [messages]);

  const handleSend = async () => {
    if (!input.trim() || isStreaming) return;
    const userText = input.trim();

    const history = [...messages, { role: 'user', text: userText }];
    setMessages(history);
    setInput('');
    setIsStreaming(true);

    // Adiciona mensagem vazia do assistente que vai receber o stream
    setMessages(prev => [...prev, { role: 'assistant', text: '' }]);

    try {
      const response = await fetch('https://api.anthropic.com/v1/messages', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': ANTHROPIC_API_KEY,
          'anthropic-version': '2023-06-01',
          'anthropic-dangerous-direct-browser-access': 'true',
        },
        body: JSON.stringify({
          model: 'claude-haiku-4-5-20251001',
          max_tokens: 500,
          system: CHAT_SYSTEM_PROMPT,
          stream: true,
          messages: history.map(m => ({ role: m.role, content: m.text }))
        })
      });

      if (!response.ok) throw new Error(`${response.status}`);

      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let accumulated = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const lines = decoder.decode(value).split('\n');
        for (const line of lines) {
          if (!line.startsWith('data: ')) continue;
          const data = line.slice(6).trim();
          if (!data || data === '[DONE]') continue;
          try {
            const parsed = JSON.parse(data);
            if (parsed.type === 'content_block_delta' && parsed.delta?.text) {
              accumulated += parsed.delta.text;
              setMessages(prev => {
                const updated = [...prev];
                updated[updated.length - 1] = { role: 'assistant', text: accumulated };
                return updated;
              });
              scrollToBottom();
            }
          } catch (_) { /* ignora linhas malformadas */ }
        }
      }
    } catch (err) {
      const msg = ANTHROPIC_API_KEY === 'SUA_CHAVE_AQUI'
        ? 'Configure a chave de API para ativar o chat real.'
        : 'Tive um probleminha aqui. Tenta de novo em instantes!';
      setMessages(prev => {
        const updated = [...prev];
        updated[updated.length - 1] = { role: 'assistant', text: msg };
        return updated;
      });
    }

    setIsStreaming(false);
  };

  return (
    <div className="chatbot">
      <style>{`@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }`}</style>
      <div className="chat-window" ref={chatWindowRef}>
        {messages.map((m, i) => {
          const isLast = i === messages.length - 1;
          const showCursor = isLast && isStreaming && m.role === 'assistant';
          return (
            <div key={i} className={`chat-bubble ${m.role}`}>
              {m.text}
              {showCursor && (
                <span style={{ display: 'inline-block', width: 2, height: '1em', background: 'currentColor', marginLeft: 2, verticalAlign: 'text-bottom', animation: 'blink 1s step-end infinite', borderRadius: 1 }} />
              )}
            </div>
          );
        })}
        {isStreaming && messages[messages.length - 1]?.text === '' && (
          <div className="chat-typing">digitando...</div>
        )}
      </div>
      <div className="chat-input-area">
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          placeholder="Pergunte qualquer coisa"
          onKeyDown={e => e.key === 'Enter' && handleSend()}
          disabled={isStreaming}
        />
        <button onClick={handleSend} disabled={isStreaming}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
        </button>
      </div>
    </div>
  );
}

// ====== SISTEMAS ======
function SistemasPage({ setRoute }) {
  return (
    <PageFrame route="sistemas" setRoute={setRoute}>
      <WordReveal as="div" className="big">Tecnologia construída do zero para o jeito único que o seu negócio funciona</WordReveal>
      <div className="two-col">
        <div>
          <WordReveal as="h3">Um sistema que nasce do seu negócio, não o contrário</WordReveal>
          <p>{`A maioria das empresas tenta adaptar o seu negócio a um sistema pronto. Na Line em parceria com a Navena, fazemos o inverso e construímos do zero uma solução que se encaixa exatamente na forma como você opera, cresce e pensa.\nDesenvolvemos sistemas de gestão completos como ERPs e CRMs, plataformas web personalizadas para operações específicas, aplicativos mobile que colocam o seu negócio na palma da mão dos seus clientes, e automações e integrações que conectam ferramentas, eliminam processos manuais e fazem o seu time ganhar tempo para o que realmente importa. Cada sistema é único, porque cada negócio é único.`}</p>
        </div>
        <div className="media"><div className="ph" style={{ height: '100%', borderRadius: 28 }}>dashboard · ERP</div></div>
      </div>

      <div className="partners">
        <img src="assets/logo_line_navena.png" alt="Line e Navena" />
      </div>

      <div className="closing">Este serviço nasce da união entre duas especialidades. A Line traz o olhar estratégico, a identidade de marca e o posicionamento. A Navena traz a tecnologia, a robustez técnica e a inteligência por trás de cada automação. Juntas, entregamos uma solução que é ao mesmo tempo sofisticada e humana.</div>

      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20um%20sistema%20100%25%20personalizado%20para%20a%20minha%20empresa', '_blank')}>Quero um sistema feito para mim</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== IA ======
function IAPage({ setRoute }) {
  const isMobile = useIsMobile();
  return (
    <PageFrame route="ia" setRoute={setRoute}>
      <WordReveal as="div" className="big">A sua marca presente em cada conversa, 24 horas por dia.</WordReveal>
      <div style={{ padding: isMobile ? '0 16px' : '0 clamp(16px, 15vw, 275px)' }}>
        <div style={{ height: isMobile ? 420 : 560, boxShadow: '0 20px 40px rgba(0,0,0,0.08)', borderRadius: 28 }}><IAChatBot /></div>
      </div>
      <div className="two-col" style={{ marginTop: 120 }}>
        <div>
          <WordReveal as="h3">IA 100% personalizada.</WordReveal>
          <p>{`Desenvolvemos uma inteligência artificial treinada com a identidade, o tom de voz e os valores da sua marca, para que cada conversa pareça humana, mesmo quando não é.\nA IA atua no WhatsApp, Instagram Direct, chat do site e e-mail. Ela atende e resolve dúvidas, qualifica leads antes de chegarem até você, agenda compromissos automaticamente e conduz vendas até o fechamento. Tudo isso sem perder a essência da sua marca em nenhuma linha.`}</p>
        </div>
      </div>

      <div className="partners">
        <img src="assets/logo_line_navena.png" alt="Line e Navena" />
      </div>

      <div className="closing">Este serviço nasce da união entre duas especialidades. A Line traz o olhar estratégico, a identidade de marca e o posicionamento. A Navena traz a tecnologia, a robustez técnica e a inteligência por trás de cada automação. Juntas, entregamos uma solução que é ao mesmo tempo sofisticada e humana.</div>

      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20uma%20IA%20100%25%20personalizada%20para%20a%20minha%20empresa', '_blank')}>Quero uma IA personalizada</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== TRÁFEGO PAGO ======
function TrafegoPage({ setRoute }) {
  return (
    <PageFrame route="trafego" setRoute={setRoute}>
      <WordReveal as="div" className="big">O seu negócio na frente da pessoa certa.</WordReveal>
      <div className="two-col">
        <div>
          <WordReveal as="h3">Outdoor Online</WordReveal>
          <p>{`Começamos pela configuração e estrutura das campanhas, desenhando uma arquitetura sólida no Meta Ads e no Google Ads para que cada centavo trabalhe com precisão.\nA partir daí, cuidamos da gestão e otimização contínua, ajustando, testando e evoluindo em tempo real. Criamos os criativos completos, artes e copies alinhados com a identidade da sua marca e pensados para converter.\nE ao final de cada ciclo, entregamos relatórios detalhados com análise de resultados, para que você entenda exatamente onde a sua marca está crescendo.`}</p>
        </div>
      </div>

      <WordReveal as="div" className="traf-highlight">Pare de aparecer para todo mundo e comece a aparecer para os certos.</WordReveal>

      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20criar%20campanhas%20que%20convertem', '_blank')}>Quero campanhas que convertem</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== VÍDEOS ======
function VideosPage({ setRoute }) {
  return (
    <PageFrame route="videos" setRoute={setRoute}>
      <WordReveal as="div" className="big">Vídeos que transformam momentos em memória</WordReveal>
      <div className="media-strip">
        <div className="ph" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
          <iframe
            width="100%"
            height="100%"
            src="https://www.youtube-nocookie.com/embed/Fn4f0bhYbEk?autoplay=1&mute=1&loop=1&playlist=Fn4f0bhYbEk&controls=1&modestbranding=1&playsinline=1&rel=0"
            title="Vídeo 1"
            frameBorder="0"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
            allowFullScreen
          ></iframe>
        </div>
        <div className="ph" style={{ padding: 0, overflow: 'hidden', background: '#000' }}>
          <iframe
            width="100%"
            height="100%"
            src="https://www.youtube-nocookie.com/embed/BsLQmEw_H5E?autoplay=1&mute=1&loop=1&playlist=BsLQmEw_H5E&controls=1&modestbranding=1&playsinline=1&rel=0"
            title="Vídeo 2"
            frameBorder="0"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen"
            allowFullScreen
          ></iframe>
        </div>
      </div>

      <div className="two-col">
        <div>
          <WordReveal as="h3">Instantes gravados para sempre</WordReveal>
          <p>{`Um vídeo é o instante mais completo que existe, ele carrega imagem, movimento, som e emoção ao mesmo tempo. Na Line, cada produção nasce com um propósito: intenção.\nTudo começa na captação, com a gravação profissional de produtos, ambientes e detalhes que traduzem visualmente a essência da sua marca. Depois vem a edição: montagem, tratamento de cor, trilha sonora, motion e finalização que transformam cenas brutas num conteúdo que prende, emociona e converte.`}</p>
        </div>
      </div>

      <ReelsGrid />

      <div className="closing-cta"><HoverBorderGradient onClick={() => window.open('https://wa.me/5551989236353?text=Quero%20que%20a%20minha%20empresa%20tenha%20v%C3%ADdeos%20com%20inten%C3%A7%C3%A3o', '_blank')}>Quero vídeos com intenção</HoverBorderGradient></div>
    </PageFrame>
  );
}

// ====== CONTATO (form simples) ======
function ContatoPage({ setRoute }) {
  return (
    <PageFrame route="todos" setRoute={setRoute}>
      <WordReveal as="div" className="big">Será um prazer colaborar com você</WordReveal>
      <div style={{ maxWidth: 720, margin: '0 auto 120px', padding: '0 32px', display: 'flex', flexDirection: 'column', gap: 20 }}>
        {['Seu nome', 'Seu e-mail', 'Seu telefone'].map(ph => (
          <input key={ph} placeholder={ph} style={{ height: 56, borderRadius: 14, border: '1px solid rgba(14,14,14,0.2)', padding: '0 20px', fontFamily: 'Urbanist', fontSize: 22, outline: 'none' }} />
        ))}
        <textarea placeholder="Conta pra gente sobre o seu projeto" rows={6} style={{ borderRadius: 14, border: '1px solid rgba(14,14,14,0.2)', padding: '16px 20px', fontFamily: 'Urbanist', fontSize: 22, outline: 'none', resize: 'vertical' }} />
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 20 }}>
          <HoverBorderGradient>Enviar mensagem</HoverBorderGradient>
        </div>
      </div>
    </PageFrame>
  );
}

// App shell & router
function App() {
  const [route, setRouteRaw] = React.useState(() => {
    try {
      const r = localStorage.getItem('line_route') || 'home';
      return r === 'todos' ? 'home' : r;
    } catch { return 'home'; }
  });

  const lenisRef = React.useRef(null);

  const setRoute = React.useCallback((r) => {
    setRouteRaw(r);
    try { localStorage.setItem('line_route', r); } catch { }
    if (lenisRef.current) {
      lenisRef.current.scrollTo(0, { immediate: true });
    } else {
      window.scrollTo({ top: 0, behavior: 'instant' });
    }
  }, []);

  // Lenis smooth scroll — rAF explícito garante que o ScrollTrigger receba updates em todo frame
  React.useEffect(() => {
    if (!window.Lenis) return;
    const lenis = new window.Lenis({ duration: 2.0, easing: t => Math.min(1, 1.001 - Math.pow(2, -10 * t)) });
    lenisRef.current = lenis;
    let rafId;
    function raf(time) {
      lenis.raf(time);
      rafId = requestAnimationFrame(raf);
    }
    rafId = requestAnimationFrame(raf);
    return () => {
      cancelAnimationFrame(rafId);
      lenis.destroy();
      lenisRef.current = null;
    };
  }, []);

  // Refresh ScrollTrigger after each route change so position calculations stay correct
  React.useEffect(() => {
    const id = setTimeout(() => window.ScrollTrigger?.refresh(), 80);
    return () => clearTimeout(id);
  }, [route]);

  const dark = route === 'home';

  const pages = {
    home: <HomePage setRoute={setRoute} />,
    social: <SocialPage setRoute={setRoute} />,
    videos: <VideosPage setRoute={setRoute} />,
    design: <DesignPage setRoute={setRoute} />,
    sites: <SitesPage setRoute={setRoute} />,
    sistemas: <SistemasPage setRoute={setRoute} />,
    ia: <IAPage setRoute={setRoute} />,
    trafego: <TrafegoPage setRoute={setRoute} />,
    contato: <ContatoPage setRoute={setRoute} />,
  };

  return (
    <div className="canvas" data-screen-label={`00 ${route}`}>
      {pages[route] || pages.home}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('app')).render(<App />);
