Spaces:
Running
Running
File size: 6,822 Bytes
8d62c0c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
// 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: `
<h4>Objective</h4>
<p>Assess the resilience of critical applications and infrastructure against realistic attacker TTPs.</p>
<h4>Approach</h4>
<ul>
<li>External and internal network penetration testing</li>
<li>Web application and API testing (OWASP Top 10)</li>
<li>Social engineering campaign</li>
<li>Exploit validation in a safe, coordinated manner</li>
</ul>
<h4>Results</h4>
<ul>
<li>Identified a zero‑day chain leading to domain admin</li>
<li>Provided prioritized remediation roadmap</li>
<li>Retest confirmed effective mitigation</li>
</ul>
<p>Post‑engagement, the client adopted continuous automated security testing in CI/CD.</p>
`
},
hipaa: {
title: 'HIPAA Compliance Program',
body: `
<h4>Objective</h4>
<p>Build a HIPAA compliance program aligned to the Security Rule with audit readiness.</p>
<h4>Approach</h4>
<ul>
<li>Gap analysis against HIPAA requirements</li>
<li>Policy, procedure, and control design</li>
<li>Technical safeguard implementation (encryption, IAM, logging)</li>
<li>Risk assessment and workforce training</li>
</ul>
<h4>Results</h4>
<ul>
<li>Passed third‑party audit with zero major findings</li>
<li>Reduced risk exposure by 62% in 90 days</li>
<li>Established continuous compliance monitoring</li>
</ul>
`
},
ransomware: {
title: 'Ransomware Containment',
body: `
<h4>Objective</h4>
<p>Contain active ransomware and restore operations with minimal disruption.</p>
<h4>Approach</h4>
<ul>
<li>Immediate triage and scoping</li>
<li>Network segmentation to limit spread</li>
<li>Forensic preservation and root cause analysis</li>
<li>Recovery from validated backups</li>
</ul>
<h4>Results</h4>
<ul>
<li>Mean time to contain: 14 minutes</li>
<li>No data loss; operations resumed within hours</li>
<li>Hardened controls to prevent recurrence</li>
</ul>
`
}
};
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(); |