'
+ ''
+ '';
}
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); });
}
})();
Manage Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.