/** * Tino Andri - Quantenheilung & Selbstheilung * JavaScript functionality */ document.addEventListener('DOMContentLoaded', function() { // Mobile navigation toggle const navToggle = document.querySelector('.nav-toggle'); const navMenu = document.querySelector('.nav-menu'); if (navToggle && navMenu) { navToggle.addEventListener('click', function() { navToggle.classList.toggle('active'); navMenu.classList.toggle('active'); }); // Close menu when clicking a link navMenu.querySelectorAll('a').forEach(link => { link.addEventListener('click', () => { navToggle.classList.remove('active'); navMenu.classList.remove('active'); }); }); } // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function(e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { const headerOffset = 80; const elementPosition = target.getBoundingClientRect().top; const offsetPosition = elementPosition + window.pageYOffset - headerOffset; window.scrollTo({ top: offsetPosition, behavior: 'smooth' }); } }); }); // Reveal elements on scroll const revealElements = document.querySelectorAll('.section'); const revealOnScroll = () => { const windowHeight = window.innerHeight; revealElements.forEach(element => { const elementTop = element.getBoundingClientRect().top; const revealPoint = 150; if (elementTop < windowHeight - revealPoint) { element.classList.add('visible'); } }); }; // Initial class setup revealElements.forEach(element => { element.classList.add('reveal'); }); // Run on load and scroll revealOnScroll(); window.addEventListener('scroll', revealOnScroll, { passive: true }); // Navigation background change on scroll const nav = document.querySelector('.nav'); const updateNavOnScroll = () => { if (window.scrollY > 50) { nav.style.boxShadow = '0 2px 20px rgba(0, 0, 0, 0.1)'; } else { nav.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.06)'; } }; window.addEventListener('scroll', updateNavOnScroll, { passive: true }); // Form submission (placeholder - replace with actual form handling) const contactForm = document.querySelector('.contact-form'); if (contactForm) { contactForm.addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); const data = Object.fromEntries(formData); console.log('Form submitted:', data); alert('Vielen Dank für deine Nachricht! Ich werde mich bald bei dir melden.'); this.reset(); }); } // Active navigation link highlighting const sections = document.querySelectorAll('section[id]'); const highlightNav = () => { const scrollY = window.pageYOffset; sections.forEach(section => { const sectionHeight = section.offsetHeight; const sectionTop = section.offsetTop - 100; const sectionId = section.getAttribute('id'); const navLink = document.querySelector(`.nav-menu a[href="#${sectionId}"]`); if (navLink) { if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { navLink.style.color = 'var(--color-primary)'; } else { navLink.style.color = ''; } } }); }; window.addEventListener('scroll', highlightNav, { passive: true }); // ========================================================================= // Testimonial Carousel // ========================================================================= const carousel = document.querySelector('.carousel'); if (carousel) { const track = carousel.querySelector('.carousel-track'); const cards = track.querySelectorAll('.testimonial-card'); const prevBtn = carousel.querySelector('.carousel-prev'); const nextBtn = carousel.querySelector('.carousel-next'); const dotsContainer = carousel.querySelector('.carousel-dots'); const totalCards = cards.length; let currentIndex = 0; let autoAdvanceTimer = null; // Responsive visible count function getVisibleCount() { if (window.innerWidth <= 640) return 1; if (window.innerWidth <= 1024) return 2; return 3; } let visibleCount = getVisibleCount(); function getMaxIndex() { return Math.max(0, totalCards - visibleCount); } // Build dots function buildDots() { dotsContainer.innerHTML = ''; const dotCount = getMaxIndex() + 1; for (let i = 0; i < dotCount; i++) { const dot = document.createElement('button'); dot.classList.add('carousel-dot'); dot.setAttribute('aria-label', `Folie ${i + 1}`); if (i === currentIndex) dot.classList.add('active'); dot.addEventListener('click', () => goTo(i)); dotsContainer.appendChild(dot); } } function updateCarousel() { const gap = 24; // matches CSS gap const cardWidth = (track.clientWidth - gap * (visibleCount - 1)) / visibleCount; const offset = currentIndex * (cardWidth + gap); track.style.transform = `translateX(-${offset}px)`; // Update dots dotsContainer.querySelectorAll('.carousel-dot').forEach((dot, i) => { dot.classList.toggle('active', i === currentIndex); }); // Update button states prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex >= getMaxIndex(); } function goTo(index) { currentIndex = Math.max(0, Math.min(index, getMaxIndex())); updateCarousel(); resetAutoAdvance(); } function goNext() { if (currentIndex >= getMaxIndex()) { goTo(0); } else { goTo(currentIndex + 1); } } function goPrev() { goTo(currentIndex - 1); } // Auto-advance function startAutoAdvance() { autoAdvanceTimer = setInterval(goNext, 6000); } function resetAutoAdvance() { clearInterval(autoAdvanceTimer); startAutoAdvance(); } // Pause on hover carousel.addEventListener('mouseenter', () => clearInterval(autoAdvanceTimer)); carousel.addEventListener('mouseleave', startAutoAdvance); // Button events prevBtn.addEventListener('click', goPrev); nextBtn.addEventListener('click', goNext); // Handle resize let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { const newCount = getVisibleCount(); if (newCount !== visibleCount) { visibleCount = newCount; if (currentIndex > getMaxIndex()) currentIndex = getMaxIndex(); buildDots(); } updateCarousel(); }, 150); }); // Initialize buildDots(); updateCarousel(); startAutoAdvance(); } // ========================================================================= // Accordion // ========================================================================= document.querySelectorAll('.accordion-group').forEach(group => { const accordions = group.querySelectorAll('.accordion'); accordions.forEach(accordion => { const header = accordion.querySelector('.accordion-header'); header.addEventListener('click', () => { const isOpen = accordion.classList.contains('open'); // Close all in this group accordions.forEach(a => a.classList.remove('open')); // Toggle clicked if (!isOpen) { accordion.classList.add('open'); } }); }); }); });