Files
Concept Agent 68d29ae532 Fix mobile nav dropdowns, unique hero images per page, Google Maps, meta tags, reel update
- Fix mobile nav: all 3 dropdowns now get click handlers (was only first)
- Remove Our Work from nav
- Add Google Maps embed to homepage footer
- Update title and meta description/keywords/canonical
- Unique hero image per page (14 pages updated)
- Remove technician clip from hero reel
- Add .cpanel.yml for cPanel Git deployment
- Add hero image generation script (ComfyUI SDXL)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 21:27:36 +02:00

74 lines
2.6 KiB
JavaScript

const mobileToggle = document.querySelector('.mobile-menu-toggle');
const navLinks = document.querySelector('.nav-links');
const navContact = document.querySelector('.nav-contact');
if (mobileToggle) {
mobileToggle.addEventListener('click', () => {
navLinks.classList.toggle('active');
navContact.classList.toggle('active');
mobileToggle.classList.toggle('active');
});
}
// Mobile dropdowns — wire ALL dropdown labels, not just the first
document.querySelectorAll('.nav-dropdown').forEach(function(dropdown) {
var label = dropdown.querySelector('.dropdown-label');
if (!label) return;
label.addEventListener('click', function(e) {
if (window.innerWidth <= 768) {
e.preventDefault();
e.stopPropagation();
// Close all other open dropdowns
document.querySelectorAll('.nav-dropdown.open').forEach(function(other) {
if (other !== dropdown) other.classList.remove('open');
});
dropdown.classList.toggle('open');
}
});
});
document.addEventListener('click', function(e) {
if (!e.target.closest('.nav-dropdown')) {
document.querySelectorAll('.nav-dropdown.open').forEach(function(d) {
d.classList.remove('open');
});
}
});
const form = document.getElementById('quoteForm');
if (form) {
form.addEventListener('submit', function(e) {
e.preventDefault();
alert('Thank you for your quote request! We will contact you shortly.');
this.reset();
});
}
// How It Works — scroll-triggered step reveal
(function () {
function initProcess() {
var track = document.querySelector('.process-track');
if (!track) return;
var steps = track.querySelectorAll('.process-step');
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
track.classList.add('animated');
steps.forEach(function (step, i) {
setTimeout(function () {
step.classList.add('visible');
}, i * 220);
});
observer.disconnect();
}
});
}, { threshold: 0.25 });
observer.observe(track);
}
// components.js runs before main.js, but process section is injected synchronously
// so it's available immediately
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initProcess);
} else {
initProcess();
}
}());