/* ============================================================ DIMITRYCODE.COM — Scripts ============================================================ */ document.addEventListener('DOMContentLoaded', () => { // -------------------------------------------------------- // 1. SCROLL REVEAL ANIMATIONS // -------------------------------------------------------- const revealObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('active'); } }); }, { threshold: 0.1, rootMargin: '0px 0px -30px 0px' }); document.querySelectorAll('.reveal').forEach(el => { revealObserver.observe(el); }); // -------------------------------------------------------- // 2. NAVBAR SCROLL EFFECT // -------------------------------------------------------- const navbar = document.getElementById('navbar'); window.addEventListener('scroll', () => { if (window.scrollY > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }, { passive: true }); // -------------------------------------------------------- // 3. ACTIVE NAV LINK HIGHLIGHTING // -------------------------------------------------------- const sections = document.querySelectorAll('section[id]'); const navLinks = document.querySelectorAll('.nav-link'); const sectionObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const id = entry.target.getAttribute('id'); navLinks.forEach(link => { link.classList.toggle('active', link.getAttribute('href') === `#${id}`); }); } }); }, { threshold: 0.3, rootMargin: '-80px 0px -50% 0px' }); sections.forEach(section => sectionObserver.observe(section)); // -------------------------------------------------------- // 4. MOBILE MENU // -------------------------------------------------------- const mobileMenuBtn = document.getElementById('mobile-menu-btn'); const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenuBtn && mobileMenu) { mobileMenuBtn.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); }); document.querySelectorAll('.mobile-link').forEach(link => { link.addEventListener('click', () => { mobileMenu.classList.add('hidden'); }); }); } // -------------------------------------------------------- // 5. SMOOTH SCROLL FOR ANCHOR LINKS // -------------------------------------------------------- document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.getAttribute('href'); const targetEl = document.querySelector(targetId); if (targetEl) { const navHeight = navbar.offsetHeight; const targetPosition = targetEl.getBoundingClientRect().top + window.scrollY - navHeight - 40; window.scrollTo({ top: targetPosition, behavior: 'smooth' }); // Close mobile menu if open if (mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); } } }); }); // -------------------------------------------------------- // 6. PAGE LOAD — trigger hero animations // -------------------------------------------------------- setTimeout(() => { document.querySelectorAll('#hero .reveal').forEach((el, i) => { setTimeout(() => { el.classList.add('active'); }, i * 100); }); }, 200); // -------------------------------------------------------- // 8. PERFORMANCE: Reduce motion for users who prefer it // -------------------------------------------------------- const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); if (prefersReducedMotion.matches) { document.querySelectorAll('.reveal').forEach(el => { el.style.transition = 'none'; el.classList.add('active'); }); } });