/**
 * El Captain Sports Management — Marketing Site
 * main.js — Vanilla ES6+, no external dependencies
 */

document.addEventListener('DOMContentLoaded', () => {
  initNav();
  initMobileMenu();
  initReveal();
  initCounters();
  initSmoothScroll();
  initFormValidation();
  initWhatsAppFAB();
  initCardHover();
  initStickyCTA();
  initExitIntent();
  initBackToTop();
  initPricingCalc();
  initMicroInteractions();
  initPageTransitions();
  initSocialProof();
  injectRevealStyles();
  injectDynamicStyles();
});

/* ═══════════════════════════════════════════════
   1. NAV SHADOW ON SCROLL
   Add .nav--scrolled when page scrolls past 50px
═══════════════════════════════════════════════ */
function initNav() {
  const nav = document.querySelector('.nav');
  if (!nav) return;

  let ticking = false;

  const updateNav = () => {
    nav.classList.toggle('nav--scrolled', window.scrollY > 50);
    ticking = false;
  };

  window.addEventListener('scroll', () => {
    if (!ticking) {
      requestAnimationFrame(updateNav);
      ticking = true;
    }
  }, { passive: true });

  // Apply immediately on load if already scrolled
  if (window.scrollY > 50) nav.classList.add('nav--scrolled');
}

/* ═══════════════════════════════════════════════
   2. MOBILE NAV TOGGLE (Enhanced with Drawer Animation)
   Hamburger opens/closes #navLinks with slide-in drawer + backdrop
═══════════════════════════════════════════════ */
function initMobileMenu() {
  const toggle = document.querySelector('.nav__toggle');
  const links  = document.getElementById('navLinks') || document.querySelector('.nav__links');
  if (!toggle || !links) return;

  // Create backdrop overlay
  let backdrop = document.querySelector('.nav-backdrop');
  if (!backdrop) {
    backdrop = document.createElement('div');
    backdrop.className = 'nav-backdrop';
    backdrop.setAttribute('aria-hidden', 'true');
    document.body.appendChild(backdrop);
  }

  const open = () => {
    links.classList.add('nav__links--open');
    backdrop.classList.add('nav-backdrop--visible');
    toggle.setAttribute('aria-expanded', 'true');
    document.body.style.overflow = 'hidden';
  };

  const close = () => {
    links.classList.remove('nav__links--open');
    backdrop.classList.remove('nav-backdrop--visible');
    toggle.setAttribute('aria-expanded', 'false');
    document.body.style.overflow = '';
  };

  const isOpen = () => links.classList.contains('nav__links--open');

  // Hamburger click
  toggle.addEventListener('click', () => {
    isOpen() ? close() : open();
  });

  // Close on backdrop click
  backdrop.addEventListener('click', close);

  // Close when clicking a nav link
  links.addEventListener('click', (e) => {
    const target = e.target.closest('a');
    if (target && links.contains(target)) close();
  });

  // Close on Escape key
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && isOpen()) close();
  });

  // Close when clicking outside the nav
  document.addEventListener('click', (e) => {
    if (isOpen() && !links.contains(e.target) && !toggle.contains(e.target) && !backdrop.contains(e.target)) {
      close();
    }
  });
}

/* ═══════════════════════════════════════════════
   3. SCROLL REVEAL ANIMATIONS
   [data-reveal] elements fade in on scroll
   data-reveal value = delay in ms
═══════════════════════════════════════════════ */
function initReveal() {
  const elements = document.querySelectorAll('[data-reveal]');
  if (!elements.length) return;

  // Respect prefers-reduced-motion — just show immediately
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
    elements.forEach(el => {
      el.style.opacity = '1';
      el.style.transform = 'none';
    });
    return;
  }

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const delay = parseInt(entry.target.dataset.reveal) || 0;
          setTimeout(() => {
            entry.target.classList.add('revealed');
          }, delay);
          observer.unobserve(entry.target);
        }
      });
    },
    { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }
  );

  elements.forEach((el) => {
    el.style.opacity = '0';
    el.style.transform = 'translateY(20px)';
    el.style.transition = 'opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1)';
    observer.observe(el);
  });
}

function injectRevealStyles() {
  const style = document.createElement('style');
  style.textContent = `
    .revealed {
      opacity: 1 !important;
      transform: translateY(0) !important;
    }
    .module-card::before,
    .feature-card::before,
    .pain-point::before {
      background: radial-gradient(
        400px circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
        oklch(0.550 0.180 353.3 / 0.04),
        transparent 60%
      ) !important;
      opacity: 1 !important;
    }
  `;
  document.head.appendChild(style);
}

/* ═══════════════════════════════════════════════
   4. COUNTER ANIMATION
   [data-count] elements count from 0 to target
   [data-count-suffix] appends suffix (e.g. "+", "%")
═══════════════════════════════════════════════ */
function initCounters() {
  const counters = document.querySelectorAll('[data-count]');
  if (!counters.length) return;

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          animateCounter(entry.target);
          observer.unobserve(entry.target);
        }
      });
    },
    { threshold: 0.5 }
  );

  counters.forEach(el => observer.observe(el));

  // Also handle legacy .stat__value elements that store value in text
  const statValues = document.querySelectorAll('.stat__value:not([data-count])');
  statValues.forEach(el => {
    const legacyObserver = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            animateStatValue(entry.target);
            legacyObserver.unobserve(entry.target);
          }
        });
      },
      { threshold: 0.5 }
    );
    legacyObserver.observe(el);
  });
}

function animateCounter(el) {
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

  const target = parseFloat(el.dataset.count);
  const suffix = el.dataset.countSuffix || '';
  const prefix = el.dataset.countPrefix || '';
  if (isNaN(target)) return;

  const duration = 2000; // 2 seconds
  const start    = performance.now();
  const isInt    = Number.isInteger(target);

  function easeOut(t) {
    return 1 - Math.pow(1 - t, 3); // cubic ease-out
  }

  function update(now) {
    const elapsed  = now - start;
    const progress = Math.min(elapsed / duration, 1);
    const eased    = easeOut(progress);
    const current  = eased * target;

    el.textContent = prefix + (isInt ? Math.round(current) : current.toFixed(1)) + suffix;

    if (progress < 1) {
      requestAnimationFrame(update);
    }
  }

  el.textContent = prefix + '0' + suffix;
  requestAnimationFrame(update);
}

// Legacy: animate .stat__value elements with +/% in their text
function animateStatValue(el) {
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

  const text       = el.textContent.trim();
  const hasPlus    = text.startsWith('+');
  const hasPercent = text.endsWith('%');
  const target     = parseFloat(text.replace(/[^0-9.]/g, ''));

  if (isNaN(target)) return;

  const duration = 1500;
  const start    = performance.now();

  function easeOut(t) {
    return 1 - Math.pow(1 - t, 4);
  }

  function update(now) {
    const elapsed  = now - start;
    const progress = Math.min(elapsed / duration, 1);
    const current  = Math.round(easeOut(progress) * target);

    el.textContent = (hasPlus ? '+' : '') + current + (hasPercent ? '%' : '');

    if (progress < 1) requestAnimationFrame(update);
  }

  el.textContent = (hasPlus ? '+' : '') + '0' + (hasPercent ? '%' : '');
  requestAnimationFrame(update);
}

/* ═══════════════════════════════════════════════
   5. SMOOTH SCROLL FOR ANCHOR LINKS
   Accounts for sticky nav height offset
═══════════════════════════════════════════════ */
function initSmoothScroll() {
  document.addEventListener('click', (e) => {
    const link = e.target.closest('a[href^="#"]');
    if (!link) return;

    const targetId = link.getAttribute('href').slice(1);
    if (!targetId) return; // bare "#" — do nothing

    const target = document.getElementById(targetId);
    if (!target) return;

    e.preventDefault();

    const nav    = document.querySelector('.nav');
    const offset = nav ? nav.offsetHeight + 8 : 80;
    const top    = target.getBoundingClientRect().top + window.scrollY - offset;

    window.scrollTo({ top, behavior: 'smooth' });
  });
}

/* ═══════════════════════════════════════════════
   6. FORM VALIDATION (Contact page)
   Required fields + phone validation
   All error messages in Arabic
═══════════════════════════════════════════════ */
function initFormValidation() {
  const forms = document.querySelectorAll('.contact-form, form[data-validate]');
  if (!forms.length) return;

  forms.forEach((form) => {
    form.addEventListener('submit', (e) => {
      const isValid = validateForm(form);
      if (!isValid) e.preventDefault();
    });

    // Clear errors on input
    form.addEventListener('input', (e) => {
      const field = e.target;
      clearFieldError(field);
    });
  });
}

function validateForm(form) {
  let isValid = true;

  const fields = form.querySelectorAll('[required], [data-validate]');

  fields.forEach((field) => {
    clearFieldError(field);
    const value = field.value.trim();
    const type  = field.type || field.tagName.toLowerCase();

    // Required check
    if (field.hasAttribute('required') && !value) {
      showFieldError(field, 'هذا الحقل مطلوب');
      isValid = false;
      return;
    }

    if (!value) return; // Optional and empty — skip further checks

    // Phone validation: must start with 01 and be exactly 11 digits
    if (type === 'tel' || field.dataset.validate === 'phone') {
      const digitsOnly = value.replace(/\D/g, '');
      if (!digitsOnly.startsWith('01') || digitsOnly.length !== 11) {
        showFieldError(field, 'رقم الهاتف يجب أن يبدأ بـ 01 ويتكون من 11 رقماً');
        isValid = false;
        return;
      }
    }

    // Email validation
    if (type === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        showFieldError(field, 'البريد الإلكتروني غير صحيح');
        isValid = false;
        return;
      }
    }

    // Min length
    if (field.dataset.minLength) {
      const min = parseInt(field.dataset.minLength);
      if (value.length < min) {
        showFieldError(field, `يجب أن يكون على الأقل ${min} أحرف`);
        isValid = false;
      }
    }
  });

  // Focus the first invalid field
  if (!isValid) {
    const firstError = form.querySelector('.form-group--error input, .form-group--error textarea, .form-group--error select');
    if (firstError) firstError.focus();
  }

  return isValid;
}

function showFieldError(field, message) {
  const group = field.closest('.form-group');
  if (!group) return;

  group.classList.add('form-group--error');
  field.setAttribute('aria-invalid', 'true');

  // Create or update error message
  let errorEl = group.querySelector('.form-error');
  if (!errorEl) {
    errorEl = document.createElement('span');
    errorEl.className = 'form-error';
    errorEl.setAttribute('role', 'alert');
    group.appendChild(errorEl);
  }
  errorEl.textContent = message;
}

function clearFieldError(field) {
  const group = field.closest('.form-group');
  if (!group) return;

  group.classList.remove('form-group--error');
  field.removeAttribute('aria-invalid');

  const errorEl = group.querySelector('.form-error');
  if (errorEl) errorEl.remove();
}

/* ═══════════════════════════════════════════════
   7. WHATSAPP FAB ENTRANCE ANIMATION
   Scale up from 0 after 3 seconds
═══════════════════════════════════════════════ */
function initWhatsAppFAB() {
  const fab = document.querySelector('.whatsapp-fab, [data-fab="whatsapp"]');
  if (!fab) return;

  // Initially hidden
  fab.style.transform  = 'scale(0)';
  fab.style.opacity    = '0';
  fab.style.transition = 'transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease';

  setTimeout(() => {
    fab.style.transform = 'scale(1)';
    fab.style.opacity   = '1';
  }, 3000);
}

/* ═══════════════════════════════════════════════
   8. CARD HOVER GLOW EFFECT
   Tracks mouse position for radial gradient
═══════════════════════════════════════════════ */
function initCardHover() {
  const cards = document.querySelectorAll('.module-card, .feature-card, .pain-point');

  cards.forEach(card => {
    const update = (e) => {
      const rect = card.getBoundingClientRect();
      card.style.setProperty('--mouse-x', `${e.clientX - rect.left}px`);
      card.style.setProperty('--mouse-y', `${e.clientY - rect.top}px`);
    };

    card.addEventListener('mouseenter', update);
    card.addEventListener('mousemove', update);
  });
}

/* ═══════════════════════════════════════════════
   9. STICKY CTA BAR
   Shows fixed bottom bar after 600px scroll on homepage.
   Only on pages with [data-sticky-cta] on body.
   Remembers dismissal via sessionStorage.
═══════════════════════════════════════════════ */
function initStickyCTA() {
  if (!document.body.hasAttribute('data-sticky-cta')) return;
  if (sessionStorage.getItem('sticky-cta-closed') === '1') return;

  // Create the CTA bar
  const bar = document.createElement('div');
  bar.className = 'sticky-cta';
  bar.setAttribute('role', 'complementary');
  bar.setAttribute('aria-label', 'عرض تجريبي');
  bar.innerHTML = `
    <div class="sticky-cta__inner">
      <a href="#pricing" class="sticky-cta__btn btn">ابدأ تجربتك المجانية</a>
      <button class="sticky-cta__close" aria-label="إغلاق" type="button">&times;</button>
    </div>
  `;
  document.body.appendChild(bar);

  // Close button
  bar.querySelector('.sticky-cta__close').addEventListener('click', () => {
    bar.classList.remove('sticky-cta--visible');
    sessionStorage.setItem('sticky-cta-closed', '1');
    setTimeout(() => bar.remove(), 400);
  });

  // Show/hide on scroll
  let ticking = false;
  const updateVisibility = () => {
    bar.classList.toggle('sticky-cta--visible', window.scrollY > 600);
    ticking = false;
  };

  window.addEventListener('scroll', () => {
    if (!ticking) {
      requestAnimationFrame(updateVisibility);
      ticking = true;
    }
  }, { passive: true });

  // Check on load
  if (window.scrollY > 600) bar.classList.add('sticky-cta--visible');
}

/* ═══════════════════════════════════════════════
   10. EXIT-INTENT POPUP
   Desktop only — triggers when mouse leaves viewport top.
   Shows modal with WhatsApp booking form.
   Only once per session. Only on pages with [data-exit-intent].
═══════════════════════════════════════════════ */
function initExitIntent() {
  if (!document.body.hasAttribute('data-exit-intent')) return;
  if (sessionStorage.getItem('exit-intent-shown') === '1') return;

  // Skip on touch devices
  const isTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
  if (isTouch) return;

  const whatsappNumber = document.body.dataset.exitIntent || '201000000000';

  const showPopup = (e) => {
    // Only trigger when mouse leaves from the top
    if (e.clientY > 10) return;

    sessionStorage.setItem('exit-intent-shown', '1');
    document.removeEventListener('mouseleave', showPopup);

    // Create modal
    const modal = document.createElement('div');
    modal.className = 'exit-modal';
    modal.setAttribute('role', 'dialog');
    modal.setAttribute('aria-modal', 'true');
    modal.setAttribute('aria-labelledby', 'exit-modal-title');
    modal.innerHTML = `
      <div class="exit-modal__backdrop"></div>
      <div class="exit-modal__content">
        <button class="exit-modal__close" aria-label="إغلاق" type="button">&times;</button>
        <h2 id="exit-modal-title" class="exit-modal__title">قبل ما تمشي...</h2>
        <p class="exit-modal__subtitle">احجز عرض تجريبي مجاني في 30 ثانية</p>
        <form class="exit-modal__form" id="exitIntentForm">
          <div class="exit-modal__field">
            <input
              type="tel"
              class="exit-modal__input"
              placeholder="رقم الموبايل (01xxxxxxxxx)"
              dir="ltr"
              required
              pattern="01[0-9]{9}"
              maxlength="11"
            />
          </div>
          <button type="submit" class="exit-modal__submit btn">احجز العرض التجريبي</button>
        </form>
      </div>
    `;
    document.body.appendChild(modal);

    // Animate in
    requestAnimationFrame(() => {
      modal.classList.add('exit-modal--visible');
    });

    // Close handlers
    const closeModal = () => {
      modal.classList.remove('exit-modal--visible');
      setTimeout(() => modal.remove(), 300);
    };

    modal.querySelector('.exit-modal__close').addEventListener('click', closeModal);
    modal.querySelector('.exit-modal__backdrop').addEventListener('click', closeModal);
    document.addEventListener('keydown', function handler(ev) {
      if (ev.key === 'Escape') {
        closeModal();
        document.removeEventListener('keydown', handler);
      }
    });

    // Form submit — open WhatsApp with pre-filled message
    modal.querySelector('#exitIntentForm').addEventListener('submit', (ev) => {
      ev.preventDefault();
      const phone = modal.querySelector('input[type="tel"]').value.trim();
      if (!phone || phone.length !== 11 || !phone.startsWith('01')) return;

      const message = encodeURIComponent(`مرحبا، أنا مهتم بعرض تجريبي مجاني. رقمي: ${phone}`);
      window.open(`https://wa.me/${whatsappNumber}?text=${message}`, '_blank');
      closeModal();
    });
  };

  // Delay activation by 5 seconds to avoid false triggers
  setTimeout(() => {
    document.addEventListener('mouseleave', showPopup);
  }, 5000);
}

/* ═══════════════════════════════════════════════
   11. BACK TO TOP BUTTON
   Appears after 500px scroll. Smooth scroll to top.
   Positioned bottom-left (visually bottom-right in RTL).
═══════════════════════════════════════════════ */
function initBackToTop() {
  const btn = document.createElement('button');
  btn.className = 'back-to-top';
  btn.setAttribute('aria-label', 'العودة للأعلى');
  btn.setAttribute('type', 'button');
  btn.innerHTML = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 13 10 8 5 13"/></svg>`;
  document.body.appendChild(btn);

  let ticking = false;
  const updateVisibility = () => {
    btn.classList.toggle('back-to-top--visible', window.scrollY > 500);
    ticking = false;
  };

  window.addEventListener('scroll', () => {
    if (!ticking) {
      requestAnimationFrame(updateVisibility);
      ticking = true;
    }
  }, { passive: true });

  // Check on load
  if (window.scrollY > 500) btn.classList.add('back-to-top--visible');

  btn.addEventListener('click', () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  });
}

/* ═══════════════════════════════════════════════
   12. PRICING CALCULATOR
   Range slider for monthly collections (10,000–500,000 EGP).
   Shows calculated cost per plan. Highlights cheapest.
   Only activates if #pricing-calculator exists.
═══════════════════════════════════════════════ */
function initPricingCalc() {
  const container = document.getElementById('pricing-calculator');
  if (!container) return;

  // Plan definitions: { name, monthlyFee (EGP), platformPercent }
  const plans = [
    { id: 'starter',      name: 'المبتدئ',     monthlyFee: 500,  platformPercent: 3.0 },
    { id: 'growth',       name: 'النمو',       monthlyFee: 1200, platformPercent: 2.0 },
    { id: 'professional', name: 'الاحترافي',   monthlyFee: 2500, platformPercent: 1.0 },
    { id: 'enterprise',   name: 'المؤسسات',    monthlyFee: 5000, platformPercent: 0.5 },
  ];

  // Allow overriding plans via data attribute
  if (container.dataset.plans) {
    try {
      const customPlans = JSON.parse(container.dataset.plans);
      if (Array.isArray(customPlans) && customPlans.length) {
        plans.length = 0;
        plans.push(...customPlans);
      }
    } catch (e) { /* use defaults */ }
  }

  const minCollections = 10000;
  const maxCollections = 500000;
  const step = 5000;

  container.innerHTML = `
    <div class="pricing-calc">
      <label class="pricing-calc__label" for="collectionsSlider">
        حجم التحصيلات الشهرية: <strong class="pricing-calc__value" id="calcValue">${formatEGP(minCollections)}</strong>
      </label>
      <input
        type="range"
        id="collectionsSlider"
        class="pricing-calc__slider"
        min="${minCollections}"
        max="${maxCollections}"
        step="${step}"
        value="${minCollections}"
        dir="ltr"
      />
      <div class="pricing-calc__range-labels">
        <span>${formatEGP(minCollections)}</span>
        <span>${formatEGP(maxCollections)}</span>
      </div>
      <div class="pricing-calc__results" id="calcResults"></div>
    </div>
  `;

  const slider = container.querySelector('#collectionsSlider');
  const valueDisplay = container.querySelector('#calcValue');
  const resultsContainer = container.querySelector('#calcResults');

  function formatEGP(amount) {
    return new Intl.NumberFormat('ar-EG', { style: 'currency', currency: 'EGP', maximumFractionDigits: 0 }).format(amount);
  }

  function calculate(collections) {
    const results = plans.map(plan => ({
      ...plan,
      totalCost: plan.monthlyFee + (collections * plan.platformPercent / 100),
    }));

    // Find cheapest
    const minCost = Math.min(...results.map(r => r.totalCost));

    resultsContainer.innerHTML = results.map(r => `
      <div class="pricing-calc__plan ${r.totalCost === minCost ? 'pricing-calc__plan--cheapest' : ''}">
        <div class="pricing-calc__plan-name">${r.name}</div>
        <div class="pricing-calc__plan-breakdown">
          <span>اشتراك: ${formatEGP(r.monthlyFee)}</span>
          <span>عمولة: ${formatEGP(collections * r.platformPercent / 100)} (${r.platformPercent}%)</span>
        </div>
        <div class="pricing-calc__plan-total">${formatEGP(r.totalCost)}</div>
        ${r.totalCost === minCost ? '<span class="pricing-calc__badge">الأوفر</span>' : ''}
      </div>
    `).join('');
  }

  slider.addEventListener('input', () => {
    const val = parseInt(slider.value);
    valueDisplay.textContent = formatEGP(val);
    calculate(val);
  });

  // Initial calculation
  calculate(minCollections);
}

/* ═══════════════════════════════════════════════
   13. MICRO-INTERACTIONS
   Subtle scale on button press, input glow, card lift on hover
═══════════════════════════════════════════════ */
function initMicroInteractions() {
  // Button press effect
  document.addEventListener('mousedown', (e) => {
    const btn = e.target.closest('.btn');
    if (btn) btn.classList.add('btn--pressed');
  });

  document.addEventListener('mouseup', () => {
    document.querySelectorAll('.btn--pressed').forEach(b => b.classList.remove('btn--pressed'));
  });

  document.addEventListener('mouseleave', () => {
    document.querySelectorAll('.btn--pressed').forEach(b => b.classList.remove('btn--pressed'));
  }, true);

  // Input focus glow — handled via CSS class
  document.addEventListener('focusin', (e) => {
    if (e.target.matches('input, textarea, select')) {
      e.target.classList.add('input--focused');
    }
  });

  document.addEventListener('focusout', (e) => {
    if (e.target.matches('input, textarea, select')) {
      e.target.classList.remove('input--focused');
    }
  });

  // Card hover lift
  const hoverCards = document.querySelectorAll('.plan-card, .pain-card, .feature-card, .module-card');
  hoverCards.forEach(card => {
    card.addEventListener('mouseenter', () => card.classList.add('card--lifted'));
    card.addEventListener('mouseleave', () => card.classList.remove('card--lifted'));
  });
}

/* ═══════════════════════════════════════════════
   14. PAGE TRANSITIONS (View Transitions API)
   Intercept internal link clicks for smooth fade transitions.
   Only if browser supports document.startViewTransition.
═══════════════════════════════════════════════ */
function initPageTransitions() {
  if (!document.startViewTransition) return;

  document.addEventListener('click', (e) => {
    const link = e.target.closest('a[href]');
    if (!link) return;

    const href = link.getAttribute('href');
    if (!href) return;

    // Skip anchor links, external links, target=_blank, downloads
    if (href.startsWith('#')) return;
    if (link.target === '_blank') return;
    if (link.hasAttribute('download')) return;
    if (link.dataset.noTransition !== undefined) return;

    // Check if internal link (same origin)
    try {
      const url = new URL(href, window.location.origin);
      if (url.origin !== window.location.origin) return;
    } catch {
      return;
    }

    e.preventDefault();

    document.startViewTransition(() => {
      window.location.href = href;
    });
  });
}

/* ═══════════════════════════════════════════════
   15. SOCIAL PROOF COUNTER
   [data-social-proof] elements get animated count-up
   with a pulse animation on completion.
═══════════════════════════════════════════════ */
function initSocialProof() {
  const elements = document.querySelectorAll('[data-social-proof]');
  if (!elements.length) return;

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          animateSocialProof(entry.target);
          observer.unobserve(entry.target);
        }
      });
    },
    { threshold: 0.5 }
  );

  elements.forEach(el => observer.observe(el));
}

function animateSocialProof(el) {
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
    el.classList.add('social-proof--complete');
    return;
  }

  const target = parseFloat(el.dataset.socialProof);
  const suffix = el.dataset.socialProofSuffix || '';
  const prefix = el.dataset.socialProofPrefix || '';
  if (isNaN(target)) return;

  const duration = 2200;
  const start    = performance.now();
  const isInt    = Number.isInteger(target);

  function easeOut(t) {
    return 1 - Math.pow(1 - t, 3);
  }

  function update(now) {
    const elapsed  = now - start;
    const progress = Math.min(elapsed / duration, 1);
    const eased    = easeOut(progress);
    const current  = eased * target;

    el.textContent = prefix + (isInt ? Math.round(current) : current.toFixed(1)) + suffix;

    if (progress < 1) {
      requestAnimationFrame(update);
    } else {
      // Pulse animation on completion
      el.classList.add('social-proof--complete');
    }
  }

  el.textContent = prefix + '0' + suffix;
  requestAnimationFrame(update);
}

/* ═══════════════════════════════════════════════
   DYNAMIC STYLES INJECTION
   All CSS for JS-created elements in one place
═══════════════════════════════════════════════ */
function injectDynamicStyles() {
  const style = document.createElement('style');
  style.id = 'dynamic-js-styles';
  style.textContent = `
    /* ── Mobile Menu Drawer ── */
    .nav-backdrop {
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0);
      z-index: 998;
      pointer-events: none;
      transition: background 0.3s ease;
    }
    .nav-backdrop--visible {
      background: rgba(0, 0, 0, 0.5);
      pointer-events: auto;
    }

    @media (max-width: 768px) {
      .nav__links {
        position: fixed;
        top: 0;
        inset-inline-end: 0;
        width: 280px;
        height: 100vh;
        height: 100dvh;
        background: var(--color-surface, #fff);
        transform: translateX(100%);
        transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
        z-index: 999;
        overflow-y: auto;
        padding-top: 4rem;
        box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1);
      }
      [dir="rtl"] .nav__links {
        transform: translateX(-100%);
        box-shadow: 4px 0 20px rgba(0, 0, 0, 0.1);
      }
      .nav__links--open {
        transform: translateX(0) !important;
      }
    }

    /* ── Sticky CTA Bar ── */
    .sticky-cta {
      position: fixed;
      bottom: 0;
      inset-inline: 0;
      z-index: 990;
      background: var(--color-primary, #1e3a5f);
      padding: 0.75rem 1rem;
      transform: translateY(100%);
      transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
      box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.15);
    }
    .sticky-cta--visible {
      transform: translateY(0);
    }
    .sticky-cta__inner {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 1rem;
      max-width: 1200px;
      margin: 0 auto;
    }
    .sticky-cta__btn {
      background: var(--color-accent, #f59e0b);
      color: #fff;
      padding: 0.6rem 1.5rem;
      border-radius: 8px;
      font-weight: 700;
      text-decoration: none;
      white-space: nowrap;
      transition: transform 0.2s, box-shadow 0.2s;
    }
    .sticky-cta__btn:hover {
      transform: scale(1.03);
      box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
    }
    .sticky-cta__close {
      background: none;
      border: none;
      color: rgba(255, 255, 255, 0.8);
      font-size: 1.5rem;
      cursor: pointer;
      line-height: 1;
      padding: 0.25rem 0.5rem;
      border-radius: 4px;
      transition: color 0.2s, background 0.2s;
    }
    .sticky-cta__close:hover {
      color: #fff;
      background: rgba(255, 255, 255, 0.1);
    }

    /* ── Exit Intent Modal ── */
    .exit-modal {
      position: fixed;
      inset: 0;
      z-index: 10000;
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      transition: opacity 0.3s ease;
      pointer-events: none;
    }
    .exit-modal--visible {
      opacity: 1;
      pointer-events: auto;
    }
    .exit-modal__backdrop {
      position: absolute;
      inset: 0;
      background: rgba(0, 0, 0, 0.6);
      backdrop-filter: blur(4px);
    }
    .exit-modal__content {
      position: relative;
      background: var(--color-surface, #fff);
      border-radius: 16px;
      padding: 2.5rem 2rem;
      max-width: 420px;
      width: 90%;
      text-align: center;
      transform: scale(0.9) translateY(20px);
      transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    }
    .exit-modal--visible .exit-modal__content {
      transform: scale(1) translateY(0);
    }
    .exit-modal__close {
      position: absolute;
      top: 0.75rem;
      inset-inline-end: 0.75rem;
      background: none;
      border: none;
      font-size: 1.75rem;
      color: var(--color-text-muted, #666);
      cursor: pointer;
      line-height: 1;
      padding: 0.25rem 0.5rem;
      border-radius: 4px;
      transition: color 0.2s;
    }
    .exit-modal__close:hover {
      color: var(--color-text, #333);
    }
    .exit-modal__title {
      font-size: 1.5rem;
      font-weight: 800;
      margin-bottom: 0.5rem;
      color: var(--color-text, #1e293b);
    }
    .exit-modal__subtitle {
      font-size: 1rem;
      color: var(--color-text-muted, #64748b);
      margin-bottom: 1.5rem;
    }
    .exit-modal__field {
      margin-bottom: 1rem;
    }
    .exit-modal__input {
      width: 100%;
      padding: 0.75rem 1rem;
      border: 2px solid var(--color-border, #e2e8f0);
      border-radius: 8px;
      font-size: 1rem;
      text-align: center;
      transition: border-color 0.2s, box-shadow 0.2s;
    }
    .exit-modal__input:focus {
      outline: none;
      border-color: var(--color-primary, #1e3a5f);
      box-shadow: 0 0 0 3px rgba(30, 58, 95, 0.1);
    }
    .exit-modal__submit {
      width: 100%;
      padding: 0.85rem 1.5rem;
      background: var(--color-primary, #1e3a5f);
      color: #fff;
      border: none;
      border-radius: 8px;
      font-size: 1rem;
      font-weight: 700;
      cursor: pointer;
      transition: background 0.2s, transform 0.2s;
    }
    .exit-modal__submit:hover {
      background: var(--color-primary-dark, #15294a);
      transform: translateY(-1px);
    }

    /* ── Back to Top Button ── */
    .back-to-top {
      position: fixed;
      bottom: 6rem;
      inset-inline-start: 1.5rem;
      z-index: 980;
      width: 44px;
      height: 44px;
      border-radius: 50%;
      background: var(--color-primary, #1e3a5f);
      color: #fff;
      border: none;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      transform: scale(0);
      transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    }
    .back-to-top--visible {
      opacity: 1;
      transform: scale(1);
    }
    .back-to-top:hover {
      background: var(--color-primary-dark, #15294a);
      transform: scale(1.1);
    }
    .back-to-top:active {
      transform: scale(0.95);
    }

    /* ── Pricing Calculator ── */
    .pricing-calc {
      padding: 1.5rem;
    }
    .pricing-calc__label {
      display: block;
      font-size: 1.1rem;
      font-weight: 600;
      margin-bottom: 1rem;
      color: var(--color-text, #1e293b);
    }
    .pricing-calc__value {
      color: var(--color-primary, #1e3a5f);
      font-size: 1.25rem;
    }
    .pricing-calc__slider {
      width: 100%;
      height: 8px;
      border-radius: 4px;
      appearance: none;
      background: var(--color-border, #e2e8f0);
      outline: none;
      cursor: pointer;
    }
    .pricing-calc__slider::-webkit-slider-thumb {
      appearance: none;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      background: var(--color-primary, #1e3a5f);
      cursor: pointer;
      box-shadow: 0 2px 8px rgba(30, 58, 95, 0.3);
      transition: transform 0.2s;
    }
    .pricing-calc__slider::-webkit-slider-thumb:hover {
      transform: scale(1.15);
    }
    .pricing-calc__slider::-moz-range-thumb {
      width: 24px;
      height: 24px;
      border-radius: 50%;
      background: var(--color-primary, #1e3a5f);
      cursor: pointer;
      border: none;
      box-shadow: 0 2px 8px rgba(30, 58, 95, 0.3);
    }
    .pricing-calc__range-labels {
      display: flex;
      justify-content: space-between;
      font-size: 0.8rem;
      color: var(--color-text-muted, #64748b);
      margin-top: 0.5rem;
      margin-bottom: 1.5rem;
    }
    .pricing-calc__results {
      display: grid;
      gap: 0.75rem;
    }
    .pricing-calc__plan {
      position: relative;
      padding: 1rem 1.25rem;
      border: 2px solid var(--color-border, #e2e8f0);
      border-radius: 12px;
      transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
    }
    .pricing-calc__plan--cheapest {
      border-color: var(--color-primary, #1e3a5f);
      box-shadow: 0 4px 16px rgba(30, 58, 95, 0.12);
      transform: scale(1.02);
    }
    .pricing-calc__plan-name {
      font-weight: 700;
      font-size: 1rem;
      margin-bottom: 0.25rem;
      color: var(--color-text, #1e293b);
    }
    .pricing-calc__plan-breakdown {
      display: flex;
      gap: 1rem;
      font-size: 0.85rem;
      color: var(--color-text-muted, #64748b);
      margin-bottom: 0.5rem;
      flex-wrap: wrap;
    }
    .pricing-calc__plan-total {
      font-size: 1.2rem;
      font-weight: 800;
      color: var(--color-primary, #1e3a5f);
    }
    .pricing-calc__badge {
      position: absolute;
      top: -0.6rem;
      inset-inline-end: 1rem;
      background: var(--color-accent, #f59e0b);
      color: #fff;
      font-size: 0.75rem;
      font-weight: 700;
      padding: 0.15rem 0.6rem;
      border-radius: 20px;
    }

    /* ── Micro-Interactions ── */
    .btn--pressed {
      transform: scale(0.97) !important;
    }
    .btn {
      transition: transform 0.15s ease, box-shadow 0.2s ease;
    }

    .input--focused {
      box-shadow: 0 0 0 3px rgba(30, 58, 95, 0.12) !important;
      border-color: var(--color-primary, #1e3a5f) !important;
    }

    .card--lifted {
      transform: translateY(-4px) !important;
      box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1) !important;
      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s ease !important;
    }
    .plan-card,
    .pain-card,
    .feature-card,
    .module-card {
      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s ease;
    }

    /* ── Social Proof Pulse ── */
    .social-proof--complete {
      animation: socialProofPulse 0.6s cubic-bezier(0.4, 0, 0.2, 1);
    }
    @keyframes socialProofPulse {
      0%   { transform: scale(1); }
      30%  { transform: scale(1.15); }
      60%  { transform: scale(0.95); }
      100% { transform: scale(1); }
    }

    /* ── View Transitions ── */
    @view-transition {
      navigation: auto;
    }
    ::view-transition-old(root) {
      animation: fadeOut 0.2s ease-out;
    }
    ::view-transition-new(root) {
      animation: fadeIn 0.2s ease-in;
    }
    @keyframes fadeOut {
      from { opacity: 1; }
      to   { opacity: 0; }
    }
    @keyframes fadeIn {
      from { opacity: 0; }
      to   { opacity: 1; }
    }
  `;
  document.head.appendChild(style);
}
