// Mobile menu toggle const mobileMenuBtn = document.getElementById('mobileMenuBtn'); const mobileMenu = document.getElementById('mobileMenu'); if (mobileMenuBtn) { mobileMenuBtn.addEventListener('click', () => { const isOpen = !mobileMenu.classList.contains('hidden'); mobileMenu.classList.toggle('hidden'); mobileMenuBtn.setAttribute('aria-expanded', String(!isOpen)); }); } // Reveal on scroll const revealEls = document.querySelectorAll('.reveal'); const revealObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.15 }); revealEls.forEach(el => revealObserver.observe(el)); // Testimonials slider const track = document.getElementById('testimonialTrack'); const slides = track ? Array.from(track.children) : []; const prevBtn = document.getElementById('prevTestimonial'); const nextBtn = document.getElementById('nextTestimonial'); const dotsWrap = document.getElementById('testimonialDots'); let current = 0; let autoTimer = null; function updateSlider(index) { if (!track) return; current = (index + slides.length) % slides.length; const width = track.clientWidth; track.style.transform = `translateX(-${current * width}px)`; // Update dots Array.from(dotsWrap.children).forEach((dot, i) => { dot.classList.toggle('bg-brand-yellow', i === current); dot.classList.toggle('bg-gray-300', i !== current); }); } function createDots() { if (!dotsWrap || slides.length === 0) return; dotsWrap.innerHTML = ''; slides.forEach((_, i) => { const dot = document.createElement('button'); dot.className = 'h-2 w-2 rounded-full bg-gray-300'; dot.setAttribute('aria-label', `Go to slide ${i + 1}`); dot.addEventListener('click', () => { updateSlider(i); resetAuto(); }); dotsWrap.appendChild(dot); }); updateSlider(0); } function nextSlide() { updateSlider(current + 1); } function prevSlide() { updateSlider(current - 1); } function startAuto() { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; stopAuto(); autoTimer = setInterval(nextSlide, 6000); } function stopAuto() { if (autoTimer) clearInterval(autoTimer); } function resetAuto() { stopAuto(); startAuto(); } if (nextBtn && prevBtn) { nextBtn.addEventListener('click', () => { nextSlide(); resetAuto(); }); prevBtn.addEventListener('click', () => { prevSlide(); resetAuto(); }); } window.addEventListener('resize', () => updateSlider(current)); createDots(); startAuto(); // Case studies modal const caseModal = document.getElementById('caseModal'); const caseTitle = document.getElementById('caseTitle'); const caseBody = document.getElementById('caseBody'); const closeCase = document.getElementById('closeCase'); const CASES = { fintech: { title: 'Fintech Red Team Engagement', body: `

Objective

Assess the resilience of critical applications and infrastructure against realistic attacker TTPs.

Approach

Results

Post‑engagement, the client adopted continuous automated security testing in CI/CD.

` }, hipaa: { title: 'HIPAA Compliance Program', body: `

Objective

Build a HIPAA compliance program aligned to the Security Rule with audit readiness.

Approach

Results

` }, ransomware: { title: 'Ransomware Containment', body: `

Objective

Contain active ransomware and restore operations with minimal disruption.

Approach

Results

` } }; document.querySelectorAll('.case-study-btn').forEach(btn => { btn.addEventListener('click', () => { const key = btn.dataset.case; const data = CASES[key]; if (!data) return; caseTitle.textContent = data.title; caseBody.innerHTML = data.body; caseModal.classList.remove('hidden'); document.body.style.overflow = 'hidden'; }); }); function closeModal() { caseModal.classList.add('hidden'); document.body.style.overflow = ''; } closeCase?.addEventListener('click', closeModal); caseModal?.addEventListener('click', (e) => { if (e.target === caseModal) closeModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !caseModal.classList.contains('hidden')) closeModal(); }); // Back to top button const backToTop = document.getElementById('backToTop'); window.addEventListener('scroll', () => { if (window.scrollY > 600) { backToTop.classList.remove('hidden'); } else { backToTop.classList.add('hidden'); } }); backToTop?.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' })); // Quote form handling (demo) const form = document.getElementById('quoteForm'); const status = document.getElementById('formStatus'); form?.addEventListener('submit', (e) => { e.preventDefault(); const formData = new FormData(form); const payload = Object.fromEntries(formData.entries()); // Demo success status.textContent = 'Submitting...'; setTimeout(() => { status.textContent = 'Thanks! We will contact you shortly.'; console.log('Quote request:', payload); form.reset(); }, 800); }); // Set current year in footer document.getElementById('year').textContent = new Date().getFullYear();