/* ============================================================ RIFT TO ROCKIES PROVISIONS — main.js Nav scroll, hamburger, animations, stat bars, form handling ============================================================ */ document.addEventListener('DOMContentLoaded', () => { /* ── Sticky nav shadow ─────────────────────────────────── */ const nav = document.querySelector('.nav'); if (nav) { const onScroll = () => nav.classList.toggle('scrolled', window.scrollY > 20); window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); } /* ── Active nav link ───────────────────────────────────── */ const currentPage = window.location.pathname.split('/').pop() || 'index.html'; document.querySelectorAll('.nav__link, .nav__mobile .nav__link').forEach(link => { const href = link.getAttribute('href') || ''; const linkPage = href.split('/').pop(); if (linkPage === currentPage || (currentPage === '' && (linkPage === 'index.html' || linkPage === ''))) { link.classList.add('active'); } }); /* ── Hamburger menu ────────────────────────────────────── */ const hamburger = document.querySelector('.nav__hamburger'); const mobileMenu = document.querySelector('.nav__mobile'); if (hamburger && mobileMenu) { hamburger.addEventListener('click', () => { const isOpen = hamburger.classList.toggle('open'); mobileMenu.classList.toggle('open', isOpen); document.body.style.overflow = isOpen ? 'hidden' : ''; }); mobileMenu.querySelectorAll('a').forEach(a => { a.addEventListener('click', () => { hamburger.classList.remove('open'); mobileMenu.classList.remove('open'); document.body.style.overflow = ''; }); }); } /* ── Intersection Observer: fade-in ───────────────────── */ const fadeEls = document.querySelectorAll('.fade-in'); if (fadeEls.length && 'IntersectionObserver' in window) { const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); io.unobserve(e.target); } }); }, { threshold: 0.12 }); fadeEls.forEach(el => io.observe(el)); } else { fadeEls.forEach(el => el.classList.add('visible')); } /* ── Stat bars animate on scroll ───────────────────────── */ const bars = document.querySelectorAll('.stat-bar__fill'); if (bars.length && 'IntersectionObserver' in window) { const barIO = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { const target = e.target.dataset.width || '0'; e.target.style.width = target + '%'; barIO.unobserve(e.target); } }); }, { threshold: 0.3 }); bars.forEach(bar => { bar.style.width = '0'; barIO.observe(bar); }); } else { bars.forEach(bar => { bar.style.width = (bar.dataset.width || 0) + '%'; }); } /* ── RFQ / Contact Form Submission ─────────────────────── */ const rfqForm = document.getElementById('rfqForm'); if (rfqForm) { rfqForm.addEventListener('submit', async (e) => { e.preventDefault(); if (!validateForm(rfqForm)) return; const submitBtn = rfqForm.querySelector('[type="submit"]'); submitBtn.textContent = 'Sending…'; submitBtn.disabled = true; // Build mailto as fallback — Formspree / Netlify Forms endpoint goes here // Replace YOUR_FORM_ID with actual Formspree form ID after setup const endpoint = rfqForm.dataset.endpoint || '#'; if (endpoint && endpoint !== '#') { try { const data = new FormData(rfqForm); const res = await fetch(endpoint, { method: 'POST', body: data, headers: { 'Accept': 'application/json' } }); if (res.ok) { showSuccess(rfqForm); } else { fallbackMailto(rfqForm); } } catch { fallbackMailto(rfqForm); } } else { fallbackMailto(rfqForm); } submitBtn.textContent = 'Submit Request'; submitBtn.disabled = false; }); } const contactForm = document.getElementById('contactForm'); if (contactForm) { contactForm.addEventListener('submit', async (e) => { e.preventDefault(); if (!validateForm(contactForm)) return; const submitBtn = contactForm.querySelector('[type="submit"]'); submitBtn.textContent = 'Sending…'; submitBtn.disabled = true; const endpoint = contactForm.dataset.endpoint || '#'; if (endpoint && endpoint !== '#') { try { const data = new FormData(contactForm); const res = await fetch(endpoint, { method: 'POST', body: data, headers: { 'Accept': 'application/json' } }); if (res.ok) { showSuccess(contactForm); } else { fallbackMailto(contactForm); } } catch { fallbackMailto(contactForm); } } else { fallbackMailto(contactForm); } submitBtn.textContent = 'Send Message'; submitBtn.disabled = false; }); } function validateForm(form) { let valid = true; form.querySelectorAll('[required]').forEach(field => { const group = field.closest('.form-group'); if (!field.value.trim()) { if (group) group.classList.add('has-error'); valid = false; } else { if (group) group.classList.remove('has-error'); } }); const consent = form.querySelector('[name="consent"]'); if (consent && !consent.checked) { consent.closest('.form-group')?.classList.add('has-error'); valid = false; } return valid; } function showSuccess(form) { form.style.display = 'none'; const successEl = form.nextElementSibling; if (successEl && successEl.classList.contains('form-success')) { successEl.classList.add('show'); } } function fallbackMailto(form) { const data = new FormData(form); let body = ''; data.forEach((val, key) => { body += `${key}: ${val}%0A`; }); window.location.href = `mailto:info@r2rprovisions.com?subject=Website Inquiry&body=${body}`; } /* ── Smooth scroll for anchor links ────────────────────── */ document.querySelectorAll('a[href^="#"]').forEach(a => { a.addEventListener('click', e => { const target = document.querySelector(a.getAttribute('href')); if (target) { e.preventDefault(); const offset = 80; window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' }); } }); }); });