112 lines
3.5 KiB
JavaScript
112 lines
3.5 KiB
JavaScript
(() => {
|
|
const toggle = document.getElementById('mobileToggle');
|
|
const nav = document.getElementById('siteNav');
|
|
|
|
if (toggle && nav) {
|
|
const closeMenu = () => {
|
|
toggle.setAttribute('aria-expanded', 'false');
|
|
nav.classList.remove('open');
|
|
};
|
|
|
|
toggle.addEventListener('click', () => {
|
|
const expanded = toggle.getAttribute('aria-expanded') === 'true';
|
|
toggle.setAttribute('aria-expanded', String(!expanded));
|
|
nav.classList.toggle('open');
|
|
});
|
|
|
|
nav.querySelectorAll('a').forEach((link) => {
|
|
link.addEventListener('click', () => {
|
|
closeMenu();
|
|
});
|
|
});
|
|
|
|
document.addEventListener('click', (event) => {
|
|
if (!nav.classList.contains('open')) return;
|
|
if (nav.contains(event.target) || toggle.contains(event.target)) return;
|
|
closeMenu();
|
|
});
|
|
|
|
document.addEventListener('keydown', (event) => {
|
|
if (event.key === 'Escape' && nav.classList.contains('open')) {
|
|
closeMenu();
|
|
}
|
|
});
|
|
}
|
|
|
|
const siteHeader = document.getElementById('siteHeader');
|
|
if (siteHeader) {
|
|
const syncScrolledState = () => {
|
|
siteHeader.classList.toggle('is-scrolled', window.scrollY > 8);
|
|
};
|
|
|
|
syncScrolledState();
|
|
window.addEventListener('scroll', syncScrolledState, { passive: true });
|
|
}
|
|
|
|
const reveals = document.querySelectorAll('[data-reveal]');
|
|
if ('IntersectionObserver' in window && reveals.length) {
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('is-visible');
|
|
observer.unobserve(entry.target);
|
|
}
|
|
});
|
|
}, { threshold: 0.12 });
|
|
|
|
reveals.forEach((el) => observer.observe(el));
|
|
} else {
|
|
reveals.forEach((el) => el.classList.add('is-visible'));
|
|
}
|
|
|
|
const parallaxEls = document.querySelectorAll('[data-parallax]');
|
|
if (parallaxEls.length) {
|
|
const onScroll = () => {
|
|
const y = window.scrollY || 0;
|
|
parallaxEls.forEach((el) => {
|
|
const speed = Number(el.getAttribute('data-parallax')) || 0;
|
|
el.style.transform = `translateY(${y * speed}px)`;
|
|
});
|
|
};
|
|
onScroll();
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
}
|
|
|
|
const contactForm = document.getElementById('contactForm');
|
|
const status = document.getElementById('formStatus');
|
|
const endpoint = 'https://api.corben.world/forms/af90392e-9399-4778-9b80-9eed83580f1d/submit';
|
|
|
|
if (contactForm && status) {
|
|
contactForm.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
|
|
if (!contactForm.checkValidity()) {
|
|
status.textContent = 'Please complete all required fields.';
|
|
status.className = 'form-status error';
|
|
contactForm.reportValidity();
|
|
return;
|
|
}
|
|
|
|
const payload = Object.fromEntries(new FormData(contactForm).entries());
|
|
status.textContent = 'Sending...';
|
|
status.className = 'form-status pending';
|
|
|
|
try {
|
|
const response = await fetch(endpoint, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload)
|
|
});
|
|
|
|
if (!response.ok) throw new Error('Submission failed');
|
|
|
|
status.textContent = 'Thank you. Your inquiry was submitted successfully.';
|
|
status.className = 'form-status success';
|
|
contactForm.reset();
|
|
} catch (error) {
|
|
status.textContent = 'Unable to submit right now. Please try again.';
|
|
status.className = 'form-status error';
|
|
}
|
|
});
|
|
}
|
|
})();
|