3D CAROUSEL

				
					<!-- ===== TRAILS CAROUSEL (desktop 3D; mobile 450px with bottom progress; CTAs INSIDE CARD) ===== -->
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@300;700;800&family=Poppins:wght@300;400;600;800&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">

<div class="carousel-container" aria-label="Trails carousel">
  <div class="carousel">

    <!-- 1. LION'S HEAD -->
    <div class="carousel-item">
      <img decoding="async" class="gray"  src="/wp-content/uploads/herosection/lionshead.webp"  alt="Lion's Head">
      <img decoding="async" class="color" src="/wp-content/uploads/herosection/lionshead.webp"  alt="Lion's Head">
      <div class="gradient-overlay"></div>
      <div class="title">LION'S HEAD</div>
      <div class="subtitle">A scenic trail that's best at sunrise or sunset</div>

      <div class="details">
        <div class="detail-block"><i class="fas fa-clock"></i><div class="text"><div class="label">Duration</div><div class="value">± 2.5 hrs</div></div></div>
        <div class="detail-block"><i class="fas fa-mountain"></i><div class="text"><div class="label">Difficulty</div><div class="value">Moderate</div></div></div>
        <div class="detail-block"><i class="fas fa-route"></i><div class="text"><div class="label">Distance</div><div class="value">5.5 km / 3.4 mi</div></div></div>
      </div>

      <div class="pricing">
        <div class="pricing-header">
          <div class="pricing-option"><div class="label">Private Bookings</div><div class="value">R1500</div><small>per person</small></div>
          <div class="pricing-option"><div class="label">Group Bookings</div><div class="value">R1000</div><small>per person</small></div>
        </div>
      </div>

      <div class="buttons">
        <a href="#" class="btn book">BOOK NOW</a>
        <a href="/tours#lions-head" class="btn info">VIEW TOURS</a>
      </div>
    </div>

    <!-- 2. INDIA VENSTER -->
    <div class="carousel-item">
      <img decoding="async" class="gray"  src="/wp-content/uploads/herosection/india.webp" alt="India Venster">
      <img decoding="async" class="color" src="/wp-content/uploads/herosection/india.webp" alt="India Venster">
      <div class="gradient-overlay"></div>
      <div class="title">INDIA VENSTER</div>
      <div class="subtitle">Adventurous route up Table Mountain</div>

      <div class="details">
        <div class="detail-block"><i class="fas fa-clock"></i><div class="text"><div class="label">Duration</div><div class="value">± 3 hrs</div></div></div>
        <div class="detail-block"><i class="fas fa-mountain"></i><div class="text"><div class="label">Difficulty</div><div class="value">Challenging</div></div></div>
        <div class="detail-block"><i class="fas fa-route"></i><div class="text"><div class="label">Distance</div><div class="value">4 km / 2.5 mi</div></div></div>
      </div>

      <div class="pricing">
        <div class="pricing-header">
          <div class="pricing-option"><div class="label">Private Bookings</div><div class="value">R1500</div><small>per person</small></div>
          <div class="pricing-option"><div class="label">Group Bookings</div><div class="value">R1200</div><small>per person</small></div>
        </div>
      </div>

      <div class="buttons">
        <a href="#" class="btn book">BOOK NOW</a>
        <a href="/tours#india-venster" class="btn info">VIEW TOURS</a>
      </div>
    </div>

    <!-- 3. PLATTEKLIP GORGE -->
    <div class="carousel-item">
      <img decoding="async" class="gray"  src="/wp-content/uploads/herosection/platteklip.webp" alt="Platteklip Gorge">
      <img decoding="async" class="color" src="/wp-content/uploads/herosection/platteklip.webp" alt="Platteklip Gorge">
      <div class="gradient-overlay"></div>
      <div class="title">PLATTEKLIP GORGE</div>
      <div class="subtitle">Direct route up Table Mountain through a gorge</div>

      <div class="details">
        <div class="detail-block"><i class="fas fa-clock"></i><div class="text"><div class="label">Duration</div><div class="value">± 2 hrs</div></div></div>
        <div class="detail-block"><i class="fas fa-mountain"></i><div class="text"><div class="label">Difficulty</div><div class="value">Moderate</div></div></div>
        <div class="detail-block"><i class="fas fa-route"></i><div class="text"><div class="label">Distance</div><div class="value">3 km / 1.9 mi</div></div></div>
      </div>

      <div class="pricing">
        <div class="pricing-header">
          <div class="pricing-option"><div class="label">Private Bookings</div><div class="value">R1500</div><small>per person</small></div>
          <div class="pricing-option"><div class="label">Group Bookings</div><div class="value">R1200</div><small>per person</small></div>
        </div>
      </div>

      <div class="buttons">
        <a href="#" class="btn book">BOOK NOW</a>
        <a href="/tours#platteklip-gorge" class="btn info">VIEW TOURS</a>
      </div>
    </div>

    <!-- 4. WOODSTOCK CAVE -->
    <div class="carousel-item">
      <img decoding="async" class="gray"  src="/wp-content/uploads/herosection/woodstock.webp" alt="Woodstock Cave">
      <img decoding="async" class="color" src="/wp-content/uploads/herosection/woodstock.webp" alt="Woodstock Cave">
      <div class="gradient-overlay"></div>
      <div class="title">WOODSTOCK CAVE</div>
      <div class="subtitle">Hidden cave with a full view of Cape Town</div>

      <div class="details">
        <div class="detail-block"><i class="fas fa-clock"></i><div class="text"><div class="label">Duration</div><div class="value">± 1.5 hrs</div></div></div>
        <div class="detail-block"><i class="fas fa-mountain"></i><div class="text"><div class="label">Difficulty</div><div class="value">Easy</div></div></div>
        <div class="detail-block"><i class="fas fa-route"></i><div class="text"><div class="label">Distance</div><div class="value">3 km / 1.9 mi</div></div></div>
      </div>

      <div class="pricing">
        <div class="pricing-header">
          <div class="pricing-option"><div class="label">Private Bookings</div><div class="value">R1500</div><small>per person</small></div>
          <div class="pricing-option"><div class="label">Group Bookings</div><div class="value">R1200</div><small>per person</small></div>
        </div>
      </div>

      <div class="buttons">
        <a href="#" class="btn book">BOOK NOW</a>
        <a href="/tours#woodstock-cave" class="btn info">VIEW TOURS</a>
      </div>
    </div>

    <!-- 5. KASTEELSPORT -->
    <div class="carousel-item">
      <img decoding="async" class="gray"  src="/wp-content/uploads/herosection/kasteelsport.webp" alt="Kasteelsport">
      <img decoding="async" class="color" src="/wp-content/uploads/herosection/kasteelsport.webp" alt="Kasteelsport">
      <div class="gradient-overlay"></div>
      <div class="title">KASTEELSPORT</div>
      <div class="subtitle">Famous for its overhanging ‘Diving Board’ rock</div>

      <div class="details">
        <div class="detail-block"><i class="fas fa-clock"></i><div class="text"><div class="label">Duration</div><div class="value">± 4 hrs</div></div></div>
        <div class="detail-block"><i class="fas fa-mountain"></i><div class="text"><div class="label">Difficulty</div><div class="value">Moderate</div></div></div>
        <div class="detail-block"><i class="fas fa-route"></i><div class="text"><div class="label">Distance</div><div class="value">6 km / 3.7 mi</div></div></div>
      </div>

      <div class="pricing">
        <div class="pricing-header">
          <div class="pricing-option"><div class="label">Private Bookings</div><div class="value">R1500</div><small>per person</small></div>
          <div class="pricing-option"><div class="label">Group Bookings</div><div class="value">R1200</div><small>per person</small></div>
        </div>
      </div>

      <div class="buttons">
        <a href="#" class="btn book">BOOK NOW</a>
        <a href="/tours#kasteelspoort" class="btn info">VIEW TOURS</a>
      </div>
    </div>

  </div>

  <!-- Under-the-box mobile progress (arrows + progress bar + number) -->
  <div class="mobile-controls" aria-hidden="true">
    <div class="progress-row">
      <div class="nav">
        <button class="btn-prev" aria-label="Previous">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
        </button>
        <button class="btn-next" aria-label="Next">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
        </button>
      </div>
      <div class="bar"><div class="fill"></div></div>
      <div class="num" aria-hidden="true"><span class="hollow-text">01</span></div>
      <span class="sr-only" aria-live="polite"></span>
    </div>
  </div>
</div>

<style>
.elementor-widget-container:has(> .carousel-container){ padding:0 !important; }

/* === Cursor behaviour === */
.carousel,
.carousel-item { cursor: grab !important; }
.carousel:active,
.carousel-item:active,
.carousel.is-dragging { cursor: grabbing !important; }
.carousel-item .buttons .btn { cursor: pointer !important; }

/* ===== Base container ===== */
.carousel-container{
  width:100%;
  max-width:1366px;
  height:600px;
  perspective:2670px;
  margin:0 auto;
  position:relative;
  overflow:visible;
}

.mobile-controls{ display:none; }

/* ===== Desktop carousel layout ===== */
.carousel{
  width:100%; height:100%;
  display:flex; justify-content:center;
  transform-style:preserve-3d; position:relative;
}
.carousel-item{
  position:absolute; width:475px; height:600px; overflow:hidden;
  border-radius:10px; cursor:pointer; opacity:0;
  transform:translateY(60px) scale(0.9);
  transition:transform .8s cubic-bezier(.25,.8,.25,1), z-index .6s ease, box-shadow .4s ease, opacity .6s ease;
  will-change:transform; backface-visibility:hidden;
  color:#fff; font-family:'Public Sans',system-ui,-apple-system,Arial,sans-serif;
}
.carousel-item img{ width:100%; height:100%; object-fit:cover; position:absolute; inset:0; border-radius:10px; display:block; }
.carousel-item img.gray{ filter:grayscale(100%); z-index:1; }
.carousel-item img.color{ clip-path:inset(100% 0 0 0); transition:clip-path 1.2s ease; z-index:2; }
.carousel-item.active img.color{ clip-path:inset(0 0 0 0); }
.carousel-item.leaving img.color{ clip-path:inset(100% 0 0 0); }

/* Active and hover glow */
.carousel-item.active,
.carousel-item:hover{ box-shadow:0 0 40px rgba(255,255,255,.3); }

/* Inactive cards: glow on hover, keep transform so they don't jump */
.carousel-item:not(.active):hover{
  box-shadow: 0 0 40px rgba(255,255,255,.3) !important;
}

/* JS-applied hover state so overlapped cards can glow too */
.carousel-item.hover-highlight:not(.active){
  box-shadow: 0 0 40px rgba(255,255,255,.3) !important;
}

.carousel-item.entered{ opacity:1; transform:none; }

/* gradient */
.carousel-item .gradient-overlay{
  position:absolute; inset:0; border-radius:10px;
  background:linear-gradient(to top, rgba(0,0,0,.88) 0%, transparent 100%);
  clip-path:inset(100% 0 0 0); transition:clip-path 1.2s ease; z-index:3; pointer-events:none;
}
.carousel-item.active .gradient-overlay{ clip-path:inset(0 0 0 0); }

/* text blocks */
.carousel-item .title{
  position:absolute; bottom:260px; left:25px; right:25px;
  font-size:30px; font-weight:800; text-transform:uppercase;
  opacity:0; transform:translateY(20px);
  transition:opacity .6s ease, transform .6s ease; z-index:4; color:rgba(255,255,255,.95);
}
.carousel-item.active .title{ opacity:1; transform:translateY(0); }

.carousel-item .subtitle{
  position:absolute; bottom:250px; left:25px; right:25px;
  font-weight:600; font-size:15px; opacity:0; transform:translateY(20px);
  transition:opacity .6s ease .1s, transform .6s ease .1s;
  z-index:4; color:rgba(255,255,255,.8);
}
.carousel-item.active .subtitle{ opacity:1; transform:translateY(0); }

/* details + pricing (desktop) */
.carousel-item .details{
  position:absolute; bottom:200px; left:25px; right:25px;
  display:flex; justify-content:space-between; gap:10px;
  opacity:0; transform:translateY(20px);
  transition:opacity .6s ease .2s, transform .6s ease .2s; z-index:4;
}
.carousel-item.active .details{ opacity:1; transform:translateY(0); }
.carousel-item .detail-block{ display:flex; align-items:center; gap:8px; flex:1; min-width:0; }
.carousel-item .detail-block i{ font-size:16px; color:rgba(255,255,255,.7); }
.carousel-item .detail-block .text{ display:flex; flex-direction:column; font-size:12px; line-height:1.2; white-space:nowrap; }
.carousel-item .detail-block .label{ opacity:.7; font-weight:400; color:rgba(255,255,255,.7); }
.carousel-item .detail-block .value{ font-weight:600; font-size:13px; color:rgba(255,255,255,.85); }

.carousel-item .pricing{
  position:absolute; bottom:75px; left:25px; right:25px; display:flex; justify-content:center;
  opacity:0; transform:translateY(20px);
  transition:opacity .6s ease .3s, transform .6s ease .3s; z-index:4;
}
.carousel-item.active .pricing{ opacity:1; transform:translateY(0); }
.carousel-item .pricing-header{ display:grid; grid-template-columns:repeat(2, minmax(160px,1fr)); gap:12px; width:100%; }
.carousel-item .pricing-option{ border:1px solid rgba(255,255,255,.35); border-radius:14px; padding:14px 16px; background:rgba(0,0,0,.35); }
.carousel-item .pricing-option .label{ font:700 14px/1 "Poppins",system-ui,-apple-system,Arial,sans-serif; letter-spacing:.06em; text-transform:uppercase; }
.carousel-item .pricing-option .value{ font:800 32px/1 "Public Sans",system-ui,-apple-system,Arial,sans-serif; }

/* buttons */
.carousel-item .buttons{
  position:absolute; bottom:10px; left:25px; right:25px;
  display:flex; gap:10px; opacity:0; transform:translateY(20px);
  transition:opacity .6s ease .4s, transform .6s ease .4s; z-index:4;
}
.carousel-item.active .buttons{ opacity:1; transform:translateY(0); }
.carousel-item .buttons .btn{
  position:relative; overflow:hidden; isolation:isolate;
  display:flex; justify-content:center; align-items:center; flex:1;
  text-decoration:none; background:transparent;
  border:1px solid rgba(255,255,255,.95); color:#fff;
  padding:12px 12px; border-radius:5px; font-size:14px; font-weight:400; letter-spacing:.5px;
  transition: transform .15s ease, border-color .3s ease, color .3s ease;
}
.carousel-item .buttons .btn::before{
  content:""; position:absolute; inset:0;
  background:#fff; border-radius:5px; z-index:-1;
  transform:translateY(101%); transition:transform .35s ease;
}
.carousel-item .buttons .btn:hover,
.carousel-item .buttons .btn:focus-visible{
  color:#000; transform:translateY(-1px); border-color:#fff;
}
.carousel-item .buttons .btn:hover::before,
.carousel-item .buttons .btn:focus-visible::before{
  transform:translateY(0%);
}

/* ===== MOBILE ≤ 766px ===== */
@media (max-width:766px){
  .carousel-container{ padding:0; height:auto; }
  .carousel{ height:450px; }

  .carousel-item{ position:absolute; width:100%; height:100%; left:0; right:0; border-radius:10px; }

  .carousel-item .details,
  .carousel-item .pricing{ display:none !important; }

  .carousel-item .title{
    bottom:100px; left:16px; right:16px;
    font-family:"Poppins",system-ui,-apple-system,Arial,sans-serif !important;
    font-weight:400 !important; font-size:20px !important;
    line-height:55px !important; letter-spacing:-1px !important;
    text-transform:none !important;
  }
  .carousel-item .subtitle{
    bottom:80px; left:16px; right:16px;
    font-family:"Poppins",system-ui,-apple-system,Arial,sans-serif !important;
    font-weight:300 !important; font-size:14px !important;
    line-height:1.3 !important;
  }

  .carousel-item .buttons{
    bottom:16px; left:16px; right:16px;
    display:grid; grid-template-columns:1fr 1fr; gap:10px;
    opacity:1; transform:none;
  }
  .carousel-item .buttons .btn{
    border:1px solid rgba(255,255,255,.95);
    background:transparent; color:#fff;
    border-radius:5px; padding:12px 10px;
    font-family:"Public Sans",system-ui,-apple-system,Arial,sans-serif;
    font-weight:300; font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  }
  .carousel-item .buttons .btn::before{ display:block; }

  .mobile-controls{ display:flex; justify-content:center; margin:12px 0 10px; }
  .mobile-controls .progress-row{ width:100%; max-width:100%; display:grid; grid-template-columns:auto 1fr auto; gap:12px; align-items:center; }
  .mobile-controls .nav{ display:flex; gap:12px; }
  .mobile-controls .nav button{
    width:48px; height:48px; border-radius:999px;
    border:2px solid rgba(255,255,255,.65);
    background:rgba(0,0,0,.35); color:#fff; display:flex; align-items:center; justify-content:center;
    padding:0; line-height:0; cursor:pointer;
  }
  .mobile-controls .nav svg{ width:24px; height:24px; stroke-width:2; display:block; }
  .mobile-controls .bar{ position:relative; height:22px; display:flex; align-items:flex-end; width:100%; }
  .mobile-controls .bar::before{ content:""; position:absolute; left:0; bottom:10px; height:1px; width:100%; background:rgba(255,255,255,.45); }
  .mobile-controls .bar .fill{ position:absolute; left:0; bottom:10px; height:2px; width:0; background:#fff; transition:width .35s cubic-bezier(.22,.61,.36,1); }
  .mobile-controls .num{ width:48px; height:48px; display:flex; align-items:center; justify-content:center; font-family:"Public Sans"; font-weight:800; letter-spacing:.12em; color:#fff; text-shadow:0 0 6px rgba(0,0,0,.35); font-size:calc(48px * .7); }
  .mobile-controls .num .hollow-text{ color:transparent; -webkit-text-stroke:2px #fff; text-stroke:2px #fff; paint-order:stroke fill; }
  .mobile-controls .sr-only{ position:absolute!important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
}

/* Reduced motion */
@media (prefers-reduced-motion:reduce){
  .carousel-item,
  .carousel-item img.color,
  .carousel-item .gradient-overlay{ transition:none !important; }
}
</style>

<script>
(function(){
  const items = Array.from(document.querySelectorAll('.carousel-item'));
  const container = document.querySelector('.carousel-container');
  const total = items.length;
  let activeIndex = 0;

  /* === Remove parent widget padding precisely so card CENTER-fills === */
  function outdentToWidgetEdges(){
    const widget = container.closest('.elementor-widget-container');
    if(!widget) return;
    const cs = getComputedStyle(widget);
    const pl = parseFloat(cs.paddingLeft) || 0;
    const pr = parseFloat(cs.paddingRight) || 0;
    container.style.marginLeft  = (-pl) + "px";
    container.style.marginRight = (-pr) + "px";
    container.style.width = `calc(100% + ${pl + pr}px)`;
  }
  outdentToWidgetEdges();
  window.addEventListener('resize', outdentToWidgetEdges, {passive:true});

  // layout numbers
  let cardWidth = 475, overlap = 0.37, spacing = 0, depthStep = 350, liftStep = 60;

  const AUTO_MS = 5000; // 5 seconds
  const prefersReduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  let autoplayInterval = null;

  const isMobile = () => (container.getBoundingClientRect().width <= 766);
  const mod = (n,m)=>((n%m)+m)%m;

  function computeMetrics(){
    const w = container.getBoundingClientRect().width || 1366;
    if(isMobile()){
      cardWidth = Math.max(280, w);
      overlap = 0.2; depthStep = 120; liftStep = 20;
      const visibleSpace = Math.max(0, w - cardWidth);
      spacing = Math.max(140, visibleSpace + 120);
    }else{
      cardWidth = 475; overlap = 0.37; depthStep = 350; liftStep = 60;
      spacing = ((1366 - cardWidth) / ((total - 1) * (1 - overlap)));
    }
  }

  function updateCarousel(){
    computeMetrics();
    items.forEach((item,i)=>{
      let offset = mod(i - activeIndex, total);
      if(offset > total/2) offset -= total;

      let translateX, translateZ, translateY, scale;
      if(isMobile()){
        if(offset === 0){
          translateX = 0; translateY = 0; translateZ = 0; scale = 1;
          item.style.opacity = '1'; item.style.pointerEvents='auto';
        }else{
          translateX = (offset>0?1:-1)*spacing; translateY = 0; translateZ = -400; scale = 0.92;
          item.style.opacity = '0'; item.style.pointerEvents='none';
        }
      }else{
        translateX = offset*spacing;
        translateZ = -Math.abs(offset)*depthStep;
        translateY = -Math.abs(offset)*liftStep;
        if(offset === -(total-1)) translateX += total*spacing;
        if(offset ===  (total-1)) translateX -= total*spacing;
        scale = (offset===0)?1: (Math.abs(offset)===1?0.85:0.65);
        item.style.opacity = '1'; item.style.pointerEvents='auto';
      }

      item.style.transform = `translateX(${translateX}px) translateY(${translateY||0}px) translateZ(${translateZ||0}px) scale(${scale})`;
      item.style.zIndex = 100 - Math.abs(offset);

      if(offset===0){ item.classList.add('active'); item.classList.remove('leaving'); }
      else{
        if(item.classList.contains('active')){
          item.classList.remove('active'); item.classList.add('leaving');
          setTimeout(()=>item.classList.remove('leaving'), 1200);
        }
      }
    });

    updateMobileProgress();  // update the bar + number under the box

    // If hover-highlight is on the now-active card, clear it
    if(hoverIndex === activeIndex) clearHover();
  }

  function next(){ activeIndex = (activeIndex + 1) % total; updateCarousel(); }
  function prev(){ activeIndex = (activeIndex - 1 + total) % total; updateCarousel(); }

  function startAutoplay(){ stopAutoplay(); if(prefersReduced) return; autoplayInterval = setInterval(next, AUTO_MS); }
  function stopAutoplay(){ if(autoplayInterval) clearInterval(autoplayInterval); autoplayInterval = null; }

  container.addEventListener('mouseover', stopAutoplay, {passive:true});
  container.addEventListener('mouseout',  startAutoplay, {passive:true});
  container.addEventListener('focusin',   stopAutoplay);
  container.addEventListener('focusout',  ()=>{ if(!container.contains(document.activeElement)) startAutoplay(); });
  document.addEventListener('visibilitychange', ()=>{ if(document.hidden) stopAutoplay(); else startAutoplay(); });

  // Keep buttons clickable (don't trigger selection)
  items.forEach(item=>{
    item.querySelectorAll('.buttons .btn').forEach(btn=>{
      btn.addEventListener('click', e=>{ e.stopPropagation(); });
    });
  });

  // === GEOMETRIC CLICK PICKING (all 4 inactive are selectable) ===
  container.addEventListener('click', (e)=>{
    if(e.target.closest('.buttons')) return;

    const rect = container.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const cx = rect.width / 2;

    computeMetrics();

    const centers = [];
    for(let i=0;i<total;i++){
      let off = (i - activeIndex) % total;
      if(off > total/2)  off -= total;
      if(off < -total/2) off += total;

      let tx = off * spacing;
      if(off === -(total-1)) tx += total*spacing;
      if(off ===  (total-1)) tx -= total*spacing;

      centers.push({i, x: cx + tx});
    }

    let best = centers[0], bestD = Math.abs(x - centers[0].x);
    for(const c of centers){
      const d = Math.abs(x - c.x);
      if(d < bestD){ bestD = d; best = c; }
    }

    if(best && best.i !== activeIndex){
      activeIndex = best.i;
      updateCarousel();
      startAutoplay();
    }
  }, {passive:false});

  /* === Geometric HOVER highlight (no lift; works even if overlapped) === */
  let hoverIndex = -1;
  function clearHover(){
    if(hoverIndex >= 0){
      items[hoverIndex].classList.remove('hover-highlight');
      hoverIndex = -1;
    }
  }
  function nearestIndexByX(clientX){
    const rect = container.getBoundingClientRect();
    const x = clientX - rect.left;
    const cx = rect.width / 2;
    computeMetrics();
    let best = 0, bestD = Infinity;
    for(let i=0;i<total;i++){
      let off = (i - activeIndex) % total;
      if(off > total/2)  off -= total;
      if(off < -total/2) off += total;
      let tx = off * spacing;
      if(off === -(total-1)) tx += total*spacing;
      if(off ===  (total-1)) tx -= total*spacing;
      const centerX = cx + tx;
      const d = Math.abs(x - centerX);
      if(d < bestD){ bestD = d; best = i; }
    }
    return best;
  }
  container.addEventListener('mousemove', (e)=>{
    if(e.target.closest('.buttons')){ clearHover(); return; }
    const idx = nearestIndexByX(e.clientX);
    if(idx === activeIndex){ clearHover(); return; }
    if(idx !== hoverIndex){
      clearHover();
      items[idx].classList.add('hover-highlight');
      hoverIndex = idx;
    }
  }, {passive:true});
  container.addEventListener('mouseleave', clearHover, {passive:true});

  // === Cursor grabbing helper (visual only) ===
  let down = false;
  container.addEventListener('mousedown', () => {
    down = true;
    container.classList.add('is-dragging');
  });
  window.addEventListener('mouseup', () => {
    if(down){
      down = false;
      container.classList.remove('is-dragging');
    }
  });
  container.addEventListener('mouseleave', () => {
    if(down){
      down = false;
      container.classList.remove('is-dragging');
    }
  });

  // Staggered entrance
  const order = [0, total-1, 1, total-2, 2];
  function entrance(){
    updateCarousel();
    order.forEach((i,idx)=>{ if(items[i]) setTimeout(()=>items[i].classList.add('entered'), idx*150); });
    setTimeout(startAutoplay, order.length * 150 + 600);
  }

  if('IntersectionObserver' in window){
    const obs = new IntersectionObserver((entries,o)=>{ if(entries[0].isIntersecting){ entrance(); o.disconnect(); } }, {threshold:0.3});
    obs.observe(container);
  }else{
    updateCarousel(); items.forEach(i=>i.classList.add('entered')); startAutoplay();
  }

  // Swipe (mobile)
  let startX = 0; const threshold = 50;
  container.addEventListener('touchstart', e=>{ startX = e.touches[0].clientX; }, {passive:true});
  container.addEventListener('touchend',   e=>{
    const diff = e.changedTouches[0].clientX - startX;
    if(Math.abs(diff) > threshold){ diff>0 ? prev() : next(); startAutoplay(); }
  }, {passive:true});

  // Keyboard (desktop)
  container.tabIndex = 0;
  container.addEventListener('keydown', e=>{
    if(e.key==='ArrowRight'){ e.preventDefault(); next(); startAutoplay(); }
    if(e.key==='ArrowLeft'){  e.preventDefault(); prev(); startAutoplay(); }
    if(e.key===' '){          e.preventDefault(); next(); startAutoplay(); }
  });

  /* ===== Mobile progress (under the box) + mobile arrow buttons ===== */
  const mControls = container.querySelector('.mobile-controls');
  const mFill = mControls ? mControls.querySelector('.bar .fill') : null;
  const mNumTxt = mControls ? mControls.querySelector('.num .hollow-text') : null;
  const mLive = mControls ? mControls.querySelector('.sr-only') : null;

  const mPrevBtn = mControls ? mControls.querySelector('.btn-prev') : null;
  const mNextBtn = mControls ? mControls.querySelector('.btn-next') : null;

  if(mPrevBtn){ mPrevBtn.addEventListener('click', (e)=>{ e.preventDefault(); e.stopPropagation(); prev(); startAutoplay(); }); }
  if(mNextBtn){ mNextBtn.addEventListener('click', (e)=>{ e.preventDefault(); e.stopPropagation(); next(); startAutoplay(); }); }

  const pad2 = n => String(n).padStart(2,'0');
  function updateMobileProgress(){
    if(!mControls) return;
    const ratio = (activeIndex + 1) / Math.max(1, total);
    if(mFill)   mFill.style.width = (ratio * 100) + '%';
    if(mNumTxt) mNumTxt.textContent = pad2(activeIndex + 1);
    if(mLive)   mLive.textContent = `Slide ${pad2(activeIndex+1)} of ${pad2(total)}`;
  }

  window.addEventListener('resize', ()=>{ updateCarousel(); }, {passive:true});
  window.addEventListener('load', ()=>{ updateCarousel(); updateMobileProgress(); }, {once:true});
})();
</script>