/* ============================================================
MY ELEGANT KID — Custom JS Refinement
Target: mykids-shop.com (Celia theme on Salla)
Maintainer: Codio | Last updated: 2026-05-15
No external dependencies — Salla CSP may block CDNs.
Global scroll listener: fine here (no SPA navigation).
============================================================ */
(function () {
'use strict';
const ready = (fn) => {
if (document.readyState !== 'loading') fn();
else document.addEventListener('DOMContentLoaded', fn);
};
// ── 1. SCROLL PROGRESS BAR ────────────────────────────────
const initScrollProgress = () => {
const bar = document.createElement('div');
bar.id = 'mek-progress';
document.body.appendChild(bar);
const update = () => {
const scrolled = window.scrollY;
const total = document.documentElement.scrollHeight - window.innerHeight;
bar.style.width = total > 0 ? (scrolled / total) * 100 + '%' : '0%';
};
window.addEventListener('scroll', update, { passive: true });
update();
};
// ── 2. HERO INJECTION — homepage only, bilingual ──────────
const injectHero = () => {
const path = window.location.pathname;
// Matches /, /ar, /ar/, /en, /en/ — all valid Salla homepage paths
const isHome = /^\/(ar|en)?\/?$/.test(path);
if (!isHome) return;
const anchor =
document.querySelector('section.animated-text--0') ||
document.querySelector('main');
if (!anchor || document.getElementById('mek-hero')) return;
// Use html[lang] — set by Salla regardless of URL structure
const isEn = (document.documentElement.lang || 'ar').startsWith('en');
const content = isEn
? {
eyebrow: 'Collection 2026',
title: 'The Welcome Moment
Deserves the Details',
sub: 'Timeless elegance, for every special moment',
cta1: 'Shop Now',
cta2: 'Explore the Collection',
offersHref: `/${document.documentElement.lang || 'en'}/offers`,
}
: {
eyebrow: 'مجموعة ٢٠٢٦',
title: 'لحظة الاستقبال
تستحق التفاصيل',
sub: 'أناقة خالدة، لكل لحظة مميزة',
cta1: 'تسوق الآن',
cta2: 'اكتشف المجموعة',
offersHref: `/${document.documentElement.lang || 'ar'}/offers`,
};
const hero = document.createElement('section');
hero.id = 'mek-hero';
hero.setAttribute('aria-label', 'Hero — MY ELEGANT KID');
hero.innerHTML = `
${content.eyebrow}
${content.sub}
`; anchor.insertAdjacentElement('beforebegin', hero); hero.querySelector('[href="#mek-categories"]').addEventListener('click', (e) => { e.preventDefault(); const cats = document.querySelector('.s-block--circle-links'); if (cats) cats.scrollIntoView({ behavior: 'smooth', block: 'start' }); }); }; // ── 3. SCROLLABLE NAV — smart edge fades ────────────────── const initNavScroll = () => { const inner = document.querySelector('#mainnav .inner'); const nav = inner && inner.querySelector('ul.main-menu'); if (!nav || !inner) return; const update = () => { // scrollLeft is negative in Chrome RTL, 0 in others — normalise const scrolled = Math.abs(nav.scrollLeft); const maxScroll = nav.scrollWidth - nav.clientWidth; inner.classList.toggle('mek-nav-at-start', scrolled < 4); inner.classList.toggle('mek-nav-at-end', maxScroll - scrolled < 4); }; nav.addEventListener('scroll', update, { passive: true }); // Also update on resize window.addEventListener('resize', update, { passive: true }); update(); }; // ── 4. STICKY HEADER — glass morphism on scroll ────────── const initHeaderScroll = () => { const header = document.querySelector('header.store-header'); if (!header) return; const toggle = () => { header.classList.toggle('mek-scrolled', window.scrollY > 24); }; window.addEventListener('scroll', toggle, { passive: true }); toggle(); }; // ── 4. SECTION SCROLL FADE-IN ────────────────────────────── const initScrollFadeIn = () => { if (!('IntersectionObserver' in window)) return; if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('mek-visible'); observer.unobserve(entry.target); } }); }, { threshold: 0.07, rootMargin: '0px 0px -30px 0px' } ); document.querySelectorAll('section.s-block').forEach((section) => { section.classList.add('mek-fade-in'); observer.observe(section); }); }; // ── 5. SECTION TITLE REVEAL ──────────────────────────────── const initTitleReveal = () => { if (!('IntersectionObserver' in window)) return; if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const titles = document.querySelectorAll('.home-block-title h2'); if (!titles.length) return; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('mek-title-revealed'); observer.unobserve(entry.target); } }); }, { threshold: 0.3, rootMargin: '0px 0px -20px 0px' } ); titles.forEach((title) => { title.classList.add('mek-title-hidden'); observer.observe(title); }); }; // ── 6. CATEGORY CARD STAGGER ─────────────────────────────── const initCategoryStagger = () => { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const cards = document.querySelectorAll('.s-block--circle-links li.group'); if (!cards.length) return; const observer = new IntersectionObserver( (entries) => { if (entries.some((e) => e.isIntersecting)) { cards.forEach((card, i) => { setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, i * 60); }); observer.disconnect(); } }, { threshold: 0.08 } ); cards.forEach((card) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'opacity 0.55s var(--mek-ease-out, cubic-bezier(0,0,.2,1)), transform 0.55s var(--mek-ease-out, cubic-bezier(0,0,.2,1))'; }); const section = document.querySelector('.s-block--circle-links'); if (section) observer.observe(section); }; // ── 7. REVIEW CARD STAGGER ───────────────────────────────── const initReviewStagger = () => { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; const reviews = document.querySelectorAll('.s-block--testimonials .review'); if (!reviews.length) return; const observer = new IntersectionObserver( (entries) => { if (entries.some((e) => e.isIntersecting)) { reviews.forEach((review, i) => { setTimeout(() => { review.style.opacity = '1'; review.style.transform = 'translateY(0)'; }, i * 80); }); observer.disconnect(); } }, { threshold: 0.1 } ); reviews.forEach((review) => { review.style.opacity = '0'; review.style.transform = 'translateY(20px)'; review.style.transition = 'opacity 0.5s ease-out, transform 0.5s ease-out'; }); const section = document.querySelector('.s-block--testimonials'); if (section) observer.observe(section); }; // ── 8. CURSOR POINTER SAFETY NET ─────────────────────────── const initCursorPointer = () => { const selectors = [ '.s-block--circle-links li.group', '.s-block--circle-links li.group > a', '.s-block--testimonials .review', 'ul.main-menu li > a', '.header-btn', '.mburger', 'salla-cart-summary', ]; document.querySelectorAll(selectors.join(',')).forEach((el) => { el.style.cursor = 'pointer'; }); }; // ── BOOT ─────────────────────────────────────────────────── ready(() => { initScrollProgress(); injectHero(); initHeaderScroll(); initNavScroll(); initScrollFadeIn(); initTitleReveal(); initCategoryStagger(); initReviewStagger(); initCursorPointer(); }); })();