/* ================================================================== CANVA BEGINNER TO PRO — MARATHI LANDING PAGE script.js — Vanilla JS (no dependencies) ================================================================== */ /* ================================================================== ⚙️ EDIT SETTINGS Change ONLY the values below. The whole website (title, prices, image, links, footer, meta tags) updates automatically. ================================================================== */ const CONFIG = { BOOK_TITLE: "Canva Beginner To Pro (मराठी Guide)", AUTHOR: "Vijay Gatir", BRAND: "Digital Success Marathi", PRICE: "₹199", OLD_PRICE: "₹999", BUY_BUTTON_LINK: "#", // 👉 replace with your payment link WHATSAPP_LINK: "https://wa.me/919999999999", // 👉 replace with your WhatsApp number BOOK_IMAGE: "https://via.placeholder.com/520x680.png?text=BOOK_IMAGE", // 👉 replace with real cover image URL LOGO: "DS", // text logo (or swap for an if you have a logo file) META_TITLE: "Canva Beginner To Pro (मराठी Guide) | Digital Success Marathi", META_DESCRIPTION: "मराठीतून Canva शिका आणि फक्त ७ दिवसात प्रोफेशनल पोस्टर, रील्स थंबनेल व बिझनेस डिझाईन्स बनवा. फक्त ₹199 मध्ये लाईफटाईम अॅक्सेस.", FOOTER_TEXT: "मराठीतून डिजिटल स्किल्स शिकवणारा विश्वासार्ह प्लॅटफॉर्म.", /* Countdown timer — hours from first page load (resets per visit) */ COUNTDOWN_HOURS: 6 }; /* ================================================================== APPLY CONFIG TO THE DOM ================================================================== */ function applyConfig(){ // Plain text bindings: document.querySelectorAll('[data-config]').forEach(el => { const key = el.getAttribute('data-config'); if (CONFIG[key] !== undefined) el.textContent = CONFIG[key]; }); // Link href bindings: document.querySelectorAll('[data-config-href]').forEach(el => { const key = el.getAttribute('data-config-href'); if (CONFIG[key] !== undefined) el.setAttribute('href', CONFIG[key]); }); // Image src bindings: document.querySelectorAll('[data-config-src]').forEach(el => { const key = el.getAttribute('data-config-src'); if (CONFIG[key] !== undefined) el.setAttribute('src', CONFIG[key]); }); // Page title + meta description (progressive enhancement; static // tags already carry sensible SEO defaults for crawlers) document.title = CONFIG.META_TITLE; const metaDesc = document.querySelector('meta[name="description"]'); if (metaDesc) metaDesc.setAttribute('content', CONFIG.META_DESCRIPTION); // Footer year const yearEl = document.getElementById('year'); if (yearEl) yearEl.textContent = new Date().getFullYear(); } /* ================================================================== READING PROGRESS BAR ================================================================== */ function initProgressBar(){ const bar = document.getElementById('progressBar'); if (!bar) return; window.addEventListener('scroll', () => { const scrollTop = window.scrollY; const docHeight = document.documentElement.scrollHeight - window.innerHeight; const pct = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0; bar.style.width = pct + '%'; }, { passive: true }); } /* ================================================================== HEADER SCROLL STATE + MOBILE MENU ================================================================== */ function initHeader(){ const header = document.getElementById('header'); const menuToggle = document.getElementById('menuToggle'); const nav = document.getElementById('mainNav'); window.addEventListener('scroll', () => { header.classList.toggle('scrolled', window.scrollY > 20); }, { passive: true }); menuToggle.addEventListener('click', () => { const isOpen = nav.classList.toggle('open'); menuToggle.setAttribute('aria-expanded', isOpen); }); // Close mobile menu after clicking a link nav.querySelectorAll('a').forEach(link => { link.addEventListener('click', () => { nav.classList.remove('open'); menuToggle.setAttribute('aria-expanded', 'false'); }); }); } /* ================================================================== SCROLL REVEAL ANIMATIONS (fade in / slide up) ================================================================== */ function initScrollReveal(){ const items = document.querySelectorAll('.reveal'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting){ entry.target.classList.add('in-view'); observer.unobserve(entry.target); } }); }, { threshold: 0.15 }); items.forEach(item => observer.observe(item)); } /* ================================================================== ANIMATED COUNTERS (statistics section) ================================================================== */ function initCounters(){ const counters = document.querySelectorAll('[data-counter]'); if (!counters.length) return; const animate = (el) => { const target = parseFloat(el.getAttribute('data-counter')); const isDecimal = el.getAttribute('data-decimal') === 'true'; const duration = 1600; const start = performance.now(); function tick(now){ const progress = Math.min((now - start) / duration, 1); const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic const value = target * eased; el.textContent = isDecimal ? value.toFixed(1) : Math.round(value); if (progress < 1) requestAnimationFrame(tick); } requestAnimationFrame(tick); }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting){ animate(entry.target); observer.unobserve(entry.target); } }); }, { threshold: 0.5 }); counters.forEach(c => observer.observe(c)); } /* ================================================================== FAQ ACCORDION ================================================================== */ function initAccordion(){ document.querySelectorAll('.accordion-item').forEach(item => { const head = item.querySelector('.accordion-head'); const body = item.querySelector('.accordion-body'); head.addEventListener('click', () => { const isOpen = item.classList.contains('open'); // Close all other items (single-open accordion) document.querySelectorAll('.accordion-item.open').forEach(openItem => { if (openItem !== item){ openItem.classList.remove('open'); openItem.querySelector('.accordion-head').setAttribute('aria-expanded', 'false'); openItem.querySelector('.accordion-body').style.maxHeight = null; } }); if (isOpen){ item.classList.remove('open'); head.setAttribute('aria-expanded', 'false'); body.style.maxHeight = null; } else { item.classList.add('open'); head.setAttribute('aria-expanded', 'true'); body.style.maxHeight = body.scrollHeight + 'px'; } }); }); } /* ================================================================== COUNTDOWN TIMER (pricing section) ================================================================== */ function initCountdown(){ const hEl = document.getElementById('cdH'); const mEl = document.getElementById('cdM'); const sEl = document.getElementById('cdS'); if (!hEl) return; // Persist the deadline across a single session so it doesn't reset on refresh const storageKey = 'dsm_countdown_deadline'; let deadline = sessionStorage.getItem(storageKey); if (!deadline){ deadline = Date.now() + CONFIG.COUNTDOWN_HOURS * 60 * 60 * 1000; sessionStorage.setItem(storageKey, deadline); } else { deadline = parseInt(deadline, 10); } function pad(n){ return String(n).padStart(2, '0'); } function tick(){ const remaining = deadline - Date.now(); if (remaining <= 0){ hEl.textContent = '00'; mEl.textContent = '00'; sEl.textContent = '00'; return; } const h = Math.floor(remaining / (1000 * 60 * 60)); const m = Math.floor((remaining / (1000 * 60)) % 60); const s = Math.floor((remaining / 1000) % 60); hEl.textContent = pad(h); mEl.textContent = pad(m); sEl.textContent = pad(s); setTimeout(tick, 1000); } tick(); } /* ================================================================== STICKY BUY BAR (shows after hero scrolled past) ================================================================== */ function initStickyBuy(){ const stickyBuy = document.getElementById('stickyBuy'); const hero = document.getElementById('hero'); if (!stickyBuy || !hero) return; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { stickyBuy.classList.toggle('visible', !entry.isIntersecting && window.scrollY > 200); }); }, { threshold: 0 }); observer.observe(hero); window.addEventListener('scroll', () => { if (window.scrollY < 200) stickyBuy.classList.remove('visible'); }, { passive: true }); } /* ================================================================== BACK TO TOP BUTTON ================================================================== */ function initBackToTop(){ const btn = document.getElementById('backToTop'); if (!btn) return; window.addEventListener('scroll', () => { btn.classList.toggle('visible', window.scrollY > 600); }, { passive: true }); btn.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); } /* ================================================================== COOKIE BANNER ================================================================== */ function initCookieBanner(){ const banner = document.getElementById('cookieBanner'); const acceptBtn = document.getElementById('cookieAccept'); if (!banner) return; const accepted = localStorage.getItem('dsm_cookie_accepted'); if (!accepted){ setTimeout(() => banner.classList.add('visible'), 1200); } acceptBtn.addEventListener('click', () => { localStorage.setItem('dsm_cookie_accepted', 'true'); banner.classList.remove('visible'); }); } /* ================================================================== EXIT INTENT POPUP (desktop: mouse leaves viewport upward) ================================================================== */ function initExitIntent(){ const popup = document.getElementById('exitPopup'); const closeBtn = document.getElementById('exitPopupClose'); if (!popup) return; let shown = sessionStorage.getItem('dsm_exit_shown') === 'true'; document.addEventListener('mouseout', (e) => { if (shown) return; if (e.clientY <= 0){ popup.classList.add('visible'); shown = true; sessionStorage.setItem('dsm_exit_shown', 'true'); } }); closeBtn.addEventListener('click', () => popup.classList.remove('visible')); popup.addEventListener('click', (e) => { if (e.target === popup) popup.classList.remove('visible'); }); } /* ================================================================== NEWSLETTER POPUP (shows once after a short delay) ================================================================== */ function initNewsletterPopup(){ const popup = document.getElementById('newsletterPopup'); const closeBtn = document.getElementById('newsletterClose'); const form = document.getElementById('newsletterForm'); if (!popup) return; const seen = sessionStorage.getItem('dsm_newsletter_shown'); if (!seen){ setTimeout(() => { // Don't stack with the exit popup if (!document.getElementById('exitPopup').classList.contains('visible')){ popup.classList.add('visible'); } sessionStorage.setItem('dsm_newsletter_shown', 'true'); }, 20000); // after 20s on page } closeBtn.addEventListener('click', () => popup.classList.remove('visible')); popup.addEventListener('click', (e) => { if (e.target === popup) popup.classList.remove('visible'); }); form.addEventListener('submit', (e) => { e.preventDefault(); form.innerHTML = '

धन्यवाद! तुमचे टेम्पलेट्स लवकरच WhatsApp वर येतील. 🎉

'; setTimeout(() => popup.classList.remove('visible'), 2200); }); } /* ================================================================== SMOOTH SCROLL for in-page anchor links ================================================================== */ function initSmoothScroll(){ document.querySelectorAll('a[href^="#"]').forEach(link => { link.addEventListener('click', (e) => { const targetId = link.getAttribute('href'); if (targetId.length <= 1) return; // ignore bare "#" (e.g. unset buy links) const target = document.querySelector(targetId); if (target){ e.preventDefault(); const headerHeight = document.getElementById('header').offsetHeight; const top = target.getBoundingClientRect().top + window.scrollY - headerHeight + 1; window.scrollTo({ top, behavior: 'smooth' }); } }); }); } /* ================================================================== INIT — run everything once DOM is ready ================================================================== */ document.addEventListener('DOMContentLoaded', () => { applyConfig(); initProgressBar(); initHeader(); initScrollReveal(); initCounters(); initAccordion(); initCountdown(); initStickyBuy(); initBackToTop(); initCookieBanner(); initExitIntent(); initNewsletterPopup(); initSmoothScroll(); });

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!