Privacy Statement (EU)

Region EU not activated for privacy-statement.
/* ============================================================= Dr. Arefin — Elementor Export :: arefin-interactivity.js Vanilla JS only. No deps. Idempotent — safe to load twice. Load via: ============================================================= */ (function () { 'use strict'; if (window.__arefinInit) return; window.__arefinInit = true; var ready = function (fn) { if (document.readyState !== 'loading') fn(); else document.addEventListener('DOMContentLoaded', fn); }; ready(function () { initStickyHeader(); initMobileNav(); initOrganTooltips(); initScrollReveal(); initVideoFeed(function () { initVideoCarousel(); }); initCountUp(); initFAQFallback(); }); /* -------- FAQ
click fallback (Astra/Elementor can suppress native toggle) -------- */ function initFAQFallback() { var triggers = document.querySelectorAll('.arefin-faq-item > .arefin-faq-trigger'); if (!triggers.length) return; Array.prototype.forEach.call(triggers, function (sum) { sum.addEventListener('click', function () { var item = sum.parentElement; if (!item) return; var wasOpen = item.hasAttribute('open'); setTimeout(function () { var nowOpen = item.hasAttribute('open'); if (nowOpen === wasOpen) { if (wasOpen) item.removeAttribute('open'); else item.setAttribute('open', ''); } }, 0); }); }); } /* -------- Sticky header solidifies after scroll -------- */ function initStickyHeader() { var header = document.querySelector('.arefin .arefin-header, .arefin-header'); if (!header) return; var onScroll = function () { if (window.scrollY > 16) header.classList.add('is-stuck'); else header.classList.remove('is-stuck'); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); } /* -------- Mobile nav drawer -------- */ function initMobileNav() { var toggle = document.querySelector('.arefin-nav-toggle'); var drawer = document.getElementById('arefin-mobile-drawer'); if (!toggle || !drawer) return; var openIcon = toggle.querySelector('.arefin-nav-toggle-open'); var closeIcon = toggle.querySelector('.arefin-nav-toggle-close'); toggle.addEventListener('click', function () { var next = drawer.getAttribute('data-open') !== 'true'; drawer.setAttribute('data-open', next ? 'true' : 'false'); drawer.hidden = !next; toggle.setAttribute('aria-expanded', next ? 'true' : 'false'); if (openIcon) openIcon.hidden = next; if (closeIcon) closeIcon.hidden = !next; document.body.style.overflow = next ? 'hidden' : ''; }); drawer.addEventListener('click', function (e) { if (e.target.tagName === 'A') { drawer.setAttribute('data-open', 'false'); drawer.hidden = true; toggle.setAttribute('aria-expanded', 'false'); if (openIcon) openIcon.hidden = false; if (closeIcon) closeIcon.hidden = true; document.body.style.overflow = ''; } }); } /* -------- Hero organ orbs: mobile tap reveal, second tap navigates -------- */ function initOrganTooltips() { var orbs = document.querySelectorAll('.arefin-organ-orb'); if (!orbs.length) return; var isCoarse = function () { return window.matchMedia && window.matchMedia('(hover: none)').matches; }; var closeAll = function () { orbs.forEach(function (orb) { orb.classList.remove('is-active'); orb.setAttribute('aria-expanded', 'false'); }); }; orbs.forEach(function (orb) { orb.addEventListener('click', function (e) { if (!isCoarse()) return; if (!orb.classList.contains('is-active')) { e.preventDefault(); closeAll(); orb.classList.add('is-active'); orb.setAttribute('aria-expanded', 'true'); } }); var close = orb.querySelector('.arefin-organ-tooltip-close'); if (close) { close.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); closeAll(); }); } }); document.addEventListener('click', function (e) { var target = e.target; if (target && !target.closest('.arefin-organ-orb')) closeAll(); }); } /* -------- Scroll reveal (.arefin-reveal → .is-revealed) -------- */ function initScrollReveal() { var els = document.querySelectorAll('.arefin .arefin-reveal'); if (!els.length || !('IntersectionObserver' in window)) { els.forEach(function (el) { el.classList.add('is-revealed'); }); return; } var io = new IntersectionObserver(function (entries) { entries.forEach(function (e) { if (e.isIntersecting) { e.target.classList.add('is-revealed'); io.unobserve(e.target); } }); }, { rootMargin: '0px 0px -10% 0px', threshold: 0.05 }); els.forEach(function (el) { io.observe(el); }); } /* -------- Video feed loader (Section 05) -------- Fetches recent uploads from the youtube-feed edge function and injects cards into [data-vid-feed-target]. Invokes `done` callback after all sections finish (success or fallback) so the carousel can initialize against the populated DOM. */ function initVideoFeed(done) { var sections = document.querySelectorAll('.arefin-vid-c[data-vid-feed-url]'); if (!sections.length) { if (typeof done === 'function') done(); return; } function esc(s) { return String(s == null ? '' : s) .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, '''); } function renderCards(target, items) { var html = ''; for (var i = 0; i < items.length; i++) { var v = items[i] || {}; var id = v.videoId || ''; if (!id) continue; var title = v.title || 'Dr. Arefin video'; var thumb = v.thumbnail || ('https://i.ytimg.com/vi/' + id + '/hqdefault.jpg'); var link = v.link || ('https://www.youtube.com/watch?v=' + id); html += '' + '
' + '
' + '' + esc(title) + '' + '' + '
' + '' + '

' + esc(title) + '

' + '
' + '
'; } target.innerHTML = html; } var pending = sections.length; function settle() { pending -= 1; if (pending <= 0 && typeof done === 'function') done(); } sections.forEach(function (section) { var url = section.getAttribute('data-vid-feed-url'); var anon = section.getAttribute('data-vid-feed-anon') || ''; var max = parseInt(section.getAttribute('data-vid-feed-max') || '6', 10); var target = section.querySelector('[data-vid-feed-target]'); if (!url || !target) { settle(); return; } var headers = { 'Accept': 'application/json' }; if (anon) { headers['Authorization'] = 'Bearer ' + anon; headers['apikey'] = anon; } fetch(url, { headers: headers, credentials: 'omit', cache: 'default' }) .then(function (r) { if (!r.ok) throw new Error('feed ' + r.status); return r.json(); }) .then(function (data) { var items = (data && data.items) || []; if (!items.length) throw new Error('feed empty'); renderCards(target, items.slice(0, max)); }) .catch(function (err) { if (window.console && console.warn) console.warn('[arefin-vid-feed]', err); // Leave noscript fallback link visible. }) .then(settle, settle); }); } /* -------- Video carousel (05-videos) -------- */ function initVideoCarousel() { var sections = document.querySelectorAll('.arefin-vid-c'); sections.forEach(function (section) { var track = section.querySelector('[data-vid-track]'); var prev = section.querySelector('[data-vid-prev]'); var next = section.querySelector('[data-vid-next]'); var dotsWrap = section.querySelector('[data-vid-dots]'); if (!track) return; var cards = track.querySelectorAll('[data-vid-card]'); if (!cards.length) return; var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var stepWidth = function () { var c = cards[0]; return c ? c.offsetWidth + 24 : 320; }; var scrollByDir = function (dir) { track.scrollBy({ left: dir * stepWidth(), behavior: reduce ? 'auto' : 'smooth' }); }; var scrollToIndex = function (i) { track.scrollTo({ left: i * stepWidth(), behavior: reduce ? 'auto' : 'smooth' }); }; if (prev) prev.addEventListener('click', function () { scrollByDir(-1); }); if (next) next.addEventListener('click', function () { scrollByDir(1); }); // Dots var dots = []; if (dotsWrap) { cards.forEach(function (_c, i) { var b = document.createElement('button'); b.type = 'button'; b.className = 'arefin-vid-c__dot'; b.setAttribute('role', 'tab'); b.setAttribute('aria-label', 'Go to video ' + (i + 1)); b.addEventListener('click', function () { scrollToIndex(i); }); dotsWrap.appendChild(b); dots.push(b); }); } var setActive = function (i) { dots.forEach(function (d, di) { if (di === i) d.classList.add('is-active'); else d.classList.remove('is-active'); }); }; setActive(0); // Track active via IntersectionObserver if ('IntersectionObserver' in window) { var io = new IntersectionObserver(function (entries) { var visible = entries.filter(function (e) { return e.isIntersecting; }) .sort(function (a, b) { return b.intersectionRatio - a.intersectionRatio; })[0]; if (!visible) return; var idx = Array.prototype.indexOf.call(cards, visible.target); if (idx >= 0) setActive(idx); }, { root: track, threshold: [0.5, 0.75, 1] }); cards.forEach(function (c) { io.observe(c); }); } // Hover-to-load YouTube iframe (180ms intent delay) cards.forEach(function (card) { var id = card.getAttribute('data-video-id'); if (!id || id.indexOf('REPLACE_') === 0) return; var frame = card.querySelector('[data-vid-frame]'); var overlay = card.querySelector('.arefin-vid-c__overlay'); if (!frame) return; var iframeMounted = false, engaged = false, t = null; var mount = function (autoplay) { if (iframeMounted) { if (autoplay) { var existing = frame.querySelector('iframe'); if (existing && existing.src.indexOf('autoplay=1') === -1) { existing.src = existing.src + (existing.src.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1'; } } return; } var iframe = document.createElement('iframe'); iframe.src = 'https://www.youtube.com/embed/' + id + '?rel=0&modestbranding=1' + (autoplay ? '&autoplay=1' : ''); iframe.title = card.querySelector('.arefin-vid-c__title') ? card.querySelector('.arefin-vid-c__title').textContent : 'Video'; iframe.loading = 'lazy'; iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; iframe.setAttribute('allowfullscreen', ''); iframe.className = 'arefin-vid-c__iframe'; frame.appendChild(iframe); iframeMounted = true; }; var unmount = function () { if (engaged) return; var iframe = frame.querySelector('iframe'); if (iframe) { iframe.remove(); iframeMounted = false; } }; card.addEventListener('mouseenter', function () { if (t) clearTimeout(t); t = setTimeout(function () { mount(false); }, 180); }); card.addEventListener('mouseleave', function () { if (t) clearTimeout(t); unmount(); }); if (overlay) { overlay.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); engaged = true; mount(true); overlay.style.display = 'none'; }); } }); // Auto-advance every 5s; pause on hover/touch/hidden tab if (cards.length > 1 && !reduce) { var paused = false; track.addEventListener('mouseenter', function () { paused = true; }); track.addEventListener('mouseleave', function () { paused = false; }); track.addEventListener('touchstart', function () { paused = true; }, { passive: true }); setInterval(function () { if (paused || document.hidden) return; var active = dots.findIndex ? dots.findIndex(function (d) { return d.classList.contains('is-active'); }) : -1; if (active < 0) { for (var k = 0; k < dots.length; k++) { if (dots[k].classList.contains('is-active')) { active = k; break; } } } var nextIdx = (active + 1) % cards.length; scrollToIndex(nextIdx); }, 5000); } }); } /* -------- Count-up numbers (Section 06 Metrics) -------- Reads target from data-countup, optional data-countup-suffix and data-countup-separator. Animates once on viewport entry. */ function initCountUp() { var nodes = document.querySelectorAll('[data-countup]'); if (!nodes.length) return; var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var fmt = function (n, separator) { var s = Math.round(n).toString(); if (!separator) return s; return s.replace(/\B(?=(\d{3})+(?!\d))/g, separator); }; var animate = function (el) { if (el.__cuDone) return; el.__cuDone = true; var target = parseFloat(el.getAttribute('data-countup')) || 0; var suffix = el.getAttribute('data-countup-suffix') || ''; var sep = el.getAttribute('data-countup-separator') || ''; if (reduceMotion) { el.textContent = fmt(target, sep) + suffix; return; } var dur = Math.min(1800, 600 + Math.log10(Math.max(target, 10)) * 350); var start = performance.now(); var ease = function (t) { return 1 - Math.pow(1 - t, 3); }; var tick = function (now) { var t = Math.min(1, (now - start) / dur); var v = target * ease(t); el.textContent = fmt(v, sep) + suffix; if (t < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); }; if (!('IntersectionObserver' in window)) { Array.prototype.forEach.call(nodes, animate); return; } var io = new IntersectionObserver(function (entries) { entries.forEach(function (e) { if (e.isIntersecting) { animate(e.target); io.unobserve(e.target); } }); }, { threshold: 0.35, rootMargin: '0px 0px -10% 0px' }); Array.prototype.forEach.call(nodes, function (n) { io.observe(n); }); } })();
Scroll to Top