(() => {
  'use strict';

  const header = document.querySelector('.site-header');
  const backToTop = document.querySelector('.back-to-top');
  const menuToggle = document.querySelector('.menu-toggle');
  const mobilePanel = document.querySelector('.mobile-panel');

  const onScroll = () => {
    const y = window.scrollY;
    header?.classList.toggle('scrolled', y > 22);
    backToTop?.classList.toggle('visible', y > 520);
  };

  window.addEventListener('scroll', onScroll, { passive: true });
  onScroll();

  const setMenuState = (open) => {
    mobilePanel?.classList.toggle('open', open);
    document.body.classList.toggle('menu-open', open);
    menuToggle?.setAttribute('aria-expanded', String(open));
    menuToggle?.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
    mobilePanel?.setAttribute('aria-hidden', String(!open));

    if (open) {
      window.setTimeout(() => mobilePanel?.querySelector('a')?.focus(), 180);
    } else {
      menuToggle?.focus({ preventScroll: true });
    }
  };

  menuToggle?.addEventListener('click', () => {
    setMenuState(!mobilePanel?.classList.contains('open'));
  });

  mobilePanel?.querySelectorAll('a').forEach((link) => {
    link.addEventListener('click', () => setMenuState(false));
  });

  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape' && mobilePanel?.classList.contains('open')) {
      setMenuState(false);
    }
  });

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

  // Active navigation state, including project detail pages and homepage anchors.
  const currentFile = window.location.pathname.split('/').pop() || 'index.html';
  document.querySelectorAll('[data-nav]').forEach((link) => {
    const href = link.getAttribute('href') || '';
    const targetFile = href.split('#')[0] || 'index.html';
    const isProjectPage = currentFile.startsWith('project-') && targetFile === 'projects.html';
    const isDirectPage = href === currentFile || (targetFile === currentFile && !href.includes('#'));

    if (isProjectPage || isDirectPage) {
      link.classList.add('active');
      link.setAttribute('aria-current', 'page');
    }
  });

  // Reveal elements. If IntersectionObserver is unavailable, content remains visible.
  const revealElements = document.querySelectorAll('.reveal');
  if ('IntersectionObserver' in window) {
    const revealObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return;
        entry.target.classList.add('visible');
        observer.unobserve(entry.target);
      });
    }, { threshold: 0.1, rootMargin: '0px 0px -36px 0px' });

    revealElements.forEach((element) => revealObserver.observe(element));
  } else {
    revealElements.forEach((element) => element.classList.add('visible'));
  }

  // Animated counters.
  const animateCounter = (element) => {
    const target = Number(element.dataset.counter || 0);
    const suffix = element.dataset.suffix || '';
    const duration = 1250;
    const start = performance.now();

    const update = (now) => {
      const progress = Math.min((now - start) / duration, 1);
      const eased = 1 - Math.pow(1 - progress, 3);
      element.textContent = `${Math.round(target * eased)}${suffix}`;
      if (progress < 1) requestAnimationFrame(update);
    };

    requestAnimationFrame(update);
  };

  const counters = document.querySelectorAll('[data-counter]');
  if ('IntersectionObserver' in window) {
    const counterObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return;
        animateCounter(entry.target);
        observer.unobserve(entry.target);
      });
    }, { threshold: .55 });
    counters.forEach((counter) => counterObserver.observe(counter));
  } else {
    counters.forEach(animateCounter);
  }

  // Process interaction.
  const steps = [...document.querySelectorAll('.process-step')];
  const panel = document.querySelector('.process-panel');
  const processContent = {
    discovery: {
      number: '01',
      title: 'Discovery',
      copy: 'Understanding the business, audience, objectives, content, requirements, success criteria, and practical constraints before design begins.'
    },
    design: {
      number: '02',
      title: 'Design',
      copy: 'Creating the content hierarchy, wireframes, responsive interface direction, visual system, and focused calls to action.'
    },
    development: {
      number: '03',
      title: 'Development',
      copy: 'Building clean, responsive, accessible, and maintainable interfaces with dependable front-end behaviour across devices.'
    },
    launch: {
      number: '04',
      title: 'Launch',
      copy: 'Testing, performance refinement, deployment, handover, and practical support so the website is ready for real use.'
    }
  };

  steps.forEach((step) => {
    const activate = () => {
      const data = processContent[step.dataset.process];
      if (!data || !panel) return;
      steps.forEach((item) => item.classList.remove('active'));
      step.classList.add('active');
      panel.innerHTML = `
        <span class="section-label">${data.number} — ${data.title}</span>
        <h3 class="display-5 fw-bold mb-3">${data.title}</h3>
        <p class="lead-copy mb-0">${data.copy}</p>
      `;
    };
    step.addEventListener('click', activate);
    step.addEventListener('keydown', (event) => {
      if (event.key === 'Enter' || event.key === ' ') {
        event.preventDefault();
        activate();
      }
    });
    step.setAttribute('tabindex', '0');
    step.setAttribute('role', 'button');
  });

  // Subtle cursor spotlight on pointer devices.
  if (window.matchMedia('(pointer:fine)').matches && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
    window.addEventListener('pointermove', (event) => {
      document.documentElement.style.setProperty('--spot-x', `${event.clientX}px`);
      document.documentElement.style.setProperty('--spot-y', `${event.clientY}px`);
    }, { passive: true });
  }

  document.querySelectorAll('[data-year]').forEach((element) => {
    element.textContent = new Date().getFullYear();
  });
})();
