.elementor-151 .elementor-element.elementor-element-23243a8{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-151 .elementor-element.elementor-element-23243a8.e-con{--flex-grow:0;--flex-shrink:0;}.elementor-151 .elementor-element.elementor-element-a48db52{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-af6122d{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-2432837{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-132252b{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-a91b296{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-7e7fd7e{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-be801fc{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-a0a7021{width:100%;max-width:100%;margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;padding:0px 0px 0px 0px;}:root{--page-title-display:none;}body.elementor-page-151{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}@media(max-width:767px){.elementor-151 .elementor-element.elementor-element-a48db52{padding:0px 0px 0px 0px;}.elementor-151 .elementor-element.elementor-element-af6122d{margin:0px 0px calc(var(--kit-widget-spacing, 0px) + 0px) 0px;}}/* Start custom CSS for html, class: .elementor-element-2432837 */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */
/* Start custom CSS for html, class: .elementor-element-132252b */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */
/* Start custom CSS for html, class: .elementor-element-a91b296 */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */
/* Start custom CSS for html, class: .elementor-element-7e7fd7e */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */
/* Start custom CSS for html, class: .elementor-element-be801fc */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */
/* Start custom CSS for html, class: .elementor-element-a0a7021 */<script>
(function(){
  const root = document.getElementById('ava-showcase-solid');
  if(!root) return; // se a seção não estiver na página, não faz nada

  const belt = root.querySelector('.belt');
  const tracks = root.querySelectorAll('.track');
  if(!belt || tracks.length < 1) return;

  root.classList.add('js');         // desliga a animação CSS com a classe .js
  let contentWidth = 0;             // largura de UMA faixa (a primeira)
  let offset = 0;                   // posição lógica
  let viewX = 0;                    // posição apresentada (suavizada)
  let speedBase = 18;               // px/s autoplay
  let vx = -speedBase;              // velocidade atual (px/s) negativa = vai para a esquerda
  let raf = null, t0 = 0;

  // Mede a largura da primeira track
  function measure(){
    const track = tracks[0];
    contentWidth = Array.from(track.children).reduce((acc, el)=> acc + el.getBoundingClientRect().width, 0)
                     + (track.children.length - 1) * parseFloat(getComputedStyle(track).gap || 18);
  }

  // Aguarda imagens carregarem para medir melhor
  function whenImagesReady(cb){
    const imgs = belt.querySelectorAll('img');
    let left = imgs.length;
    if(left === 0) return cb();
    imgs.forEach(img=>{
      if(img.complete) { if(--left===0) cb(); }
      else {
        img.addEventListener('load', ()=>{ if(--left===0) cb(); }, {once:true});
        img.addEventListener('error', ()=>{ if(--left===0) cb(); }, {once:true});
      }
    });
  }

  function loop(t){
    const dt = (t0 ? (t - t0) : 16)/1000; t0 = t;
    offset += vx * dt;

    // Como temos duas tracks idênticas em sequência, o loop visual fecha a cada contentWidth
    if(offset <= -contentWidth) offset += contentWidth;
    if(offset >= 0)             offset -= contentWidth;

    // suavização (“cremoso”) — interpola viewX até offset
    const alpha = 0.16;
    viewX += (offset - viewX) * alpha;

    belt.style.transform = `translate3d(${viewX}px,0,0)`;
    raf = requestAnimationFrame(loop);
  }

  // Drag / Swipe (Pointer Events)
  let dragging = false, startX = 0, startOffset = 0, lastX = 0, lastT = 0;
  belt.addEventListener('pointerdown', e=>{
    dragging = true;
    startX = lastX = e.clientX;
    startOffset = offset;
    lastT = performance.now();
    belt.setPointerCapture(e.pointerId);
    vx = 0; // pausa autoplay durante o drag
  });
  belt.addEventListener('pointermove', e=>{
    if(!dragging) return;
    const now = performance.now();
    const dx  = e.clientX - startX;
    offset = startOffset + dx;

    // velocidade instantânea para inércia ao soltar
    const dxStep = e.clientX - lastX;
    const dt = Math.max(0.001, (now - lastT)/1000);
    vx = (dxStep / dt); // px/s
    lastX = e.clientX; lastT = now;
  }, {passive:false});
  function endDrag(){
    if(!dragging) return;
    dragging = false;

    // Limita a velocidade de inércia e depois somamos o autoplay
    const maxV = 1200;  // clamp
    vx = Math.max(-maxV, Math.min(maxV, vx));
    // aplica um pouco de “peso” e soma o autoplay para continuar rolando
    vx += (-Math.sign(vx) * 60) + (-speedBase);

    // fricção gradual na inércia
    const friction = 0.94;
    (function damp(){
      vx *= friction;
      if(Math.abs(vx) < speedBase) vx = -speedBase; // volta ao autoplay suave
    })();
  }
  belt.addEventListener('pointerup',   endDrag);
  belt.addEventListener('pointercancel', endDrag);
  belt.addEventListener('pointerleave',  endDrag);

  // Botões (opcionais: se quiser setas, basta criar dois botões fora e acoplar aqui)
  // Exemplo de nudge programático:
  function nudge(dir){  // dir = +1 direita, -1 esquerda
    // impulso curto mantendo “cremosidade”
    vx = dir * 600; setTimeout(()=>{ vx = -speedBase; }, 500);
  }
  // (Se criar botões, faça: document.querySelector('#meuPrev').onclick = ()=>nudge(+1); etc.)

  // Recalcula ao resize
  new ResizeObserver(()=>measure()).observe(belt);

  // Inicia
  whenImagesReady(()=>{
    measure();
    cancelAnimationFrame(raf);
    raf = requestAnimationFrame(loop);
  });
})();
</script>/* End custom CSS */