Espace Artiste

EUSTACHE MÉLODY LANCE « MERCI PAPA » : SON 1ER SINGLE OFFICIEL CHEZ KOPHI'S MUSIC

Sortie d'Album / Single / EP 5 min de lecture · Monsieur Kophi · 25 Avril 2026
EUSTACHE MÉLODY LANCE « MERCI PAPA » : SON 1ER SINGLE OFFICIEL CHEZ KOPHI'S MUSIC
SORTIE D'ALBUM / SINGLE / EP

Ce dimanche 26 avril 2026, le monde du Gospel ivoirien marque une étape importante : le chantre Eustache Mélody, artiste signé chez KOPHI’S MUSIC, dévoile son tout premier single officiel intitulé « Merci Papa ». Une sortie doublement symbolique, puisqu’elle coïncide précisément avec le 26ème anniversaire de l’artiste — une façon bouleversante de célébrer la vie en rendant gloire à Celui qui la donne.


Un anniversaire transformé en offrande

Né un 26 avril, Eustache Mélody aurait pu choisir de fêter ses 26 ans comme beaucoup d’autres. Il a préféré faire de ce jour un acte de culte. En choisissant cette date pour lancer « Merci Papa », il pose d’emblée les fondations de sa carrière sur une conviction profonde : tout vient de Dieu, et tout Lui revient.

Ce choix artistique et spirituel n’est pas anodin. Dans un paysage musical où la notoriété précède souvent le sens, Eustache Mélody choisit d’abord le sens. Et c’est précisément ce qui rend ce premier single aussi fort.


« Merci Papa » — Le single décrypté

« Merci Papa » est un chant d’action de grâce dans la pure tradition de l’Urban Gospel. Le titre s’adresse directement à Dieu le Père — ce Papa God que l’artiste interpelle avec une familiarité sincère et une foi décomplexée. La mélodie épouse les contours de la vie quotidienne : se réveiller chaque matin, respirer, être en bonne santé, tenir debout malgré les défis du quotidien.

Les paroles mélangent habilement le français, le nouchi ivoirien et l’anglais, créant ce son hybride caractéristique de la nouvelle génération Gospel d’Abidjan :

 

« Chaque jour je dors, je me réveille — C’est par ta grâce
Un nouveau souffle renouvelé — C’est par ta grâce
J’ai la santé, j’suis en pleine forme — C’est par ta grâce
Mon p’tit djôssi, je me défends — C’est par ta grâce

Ta grâce me suffit, moi je suis en joie
Si c’est pas toi, c’est qui ?
Papa God oh, you are the best »

Le refrain, lui, monte en puissance dans une confession de foi bilingue :

« Merci Papa car tu es unique
Dieu fidèle — Dieu puissant


Thank you Daddy, You are the only God

Mighty God — Faithful God »

La structure du texte, répétitive et ancrée dans la formule « C’est par ta grâce », n’est pas qu’une figure stylistique — c’est une liturgie. Elle installe l’auditeur dans un rythme de gratitude, comme une prière qu’on murmure en boucle jusqu’à ce qu’elle devienne réflexe.


Eustache Mélody — Qui est l’artiste ?

De son vrai nom Djegna Yolou Eustache, le chantre se fait appeler Eustache Mélody sur scène — un nom de scène qui dit déjà tout de sa vocation : la mélodie au service du message. Artiste ancré dans la scène Urban Gospel d’Abidjan, il a rejoint le label KOPHI’S MUSIC, division musicale du groupe KOPHI’S GROUP SAS, après une signature officielle qui a fait l’effet d’une bonne nouvelle dans le milieu.

Avec « Merci Papa », il signe son entrée en discographie officielle et confirme que sa présence chez KOPHI’S MUSIC n’est pas symbolique — c’est une carrière qui commence pour de vrai, un dimanche d’anniversaire, sous la bénédiction du Père.


KOPHI’S MUSIC — La vision derrière l’artiste

KOPHI’S MUSIC est le label Urban Gospel du groupe KOPHI’S GROUP SAS, basé à Abidjan, Côte d’Ivoire. Structure indépendante portée par une vision claire, le label accompagne des artistes chrétiens dans la création, la production et la distribution de leur musique — avec l’exigence artistique d’une maison de disques et la foi d’un ministère.

Le groupe intègre également JASIN FÊ (production audiovisuelle et marketing) et CTA7SON (distribution musicale et streaming), offrant ainsi à ses artistes un écosystème complet, du studio à l’oreille de l’auditeur.

La sortie de « Merci Papa » s’inscrit dans cette dynamique : une musique soignée, un message fort, une diffusion stratégique.


Où écouter « Merci Papa » ?

Le single « Merci Papa » d’Eustache Mélody est disponible sur les principales plateformes de streaming. Retrouvez-le dès maintenant et partagez-le autour de vous :


  • 🎧 Spotify

  • 🎵 Apple Music

  • ▶️ YouTube Music

  • 📲 Boomplay

➡️ Suivez Eustache Mélody et KOPHI’S MUSIC sur les réseaux sociaux pour ne manquer aucune actualité.


En conclusion — La grâce comme premier mot

Il y a quelque chose de profondément juste dans le fait qu’un artiste choisisse la gratitude comme premier mot de sa carrière officielle. Dans un monde saturé de revendications et d’ego, Eustache Mélody dit simplement : « Merci ». Et ce merci — adressé au Père, chanté en nouchi, en français et en anglais, le jour même de ses 26 ans — résonne comme une promesse autant que comme une prière.

« Merci Papa » n’est pas qu’un single. C’est une déclaration d’intention. Et chez KOPHI’S MUSIC, on est convaincu que ce n’est que le début.

🙌 Bonne écoute. Et joyeux anniversaire, Eustache Mélody. 🎂

Retour en haut
) * ============================================================ * * SPEC TIMING (synchronisé avec le CSS) : * DISPLAY_MS = 5000ms — durée totale d'affichage par slide * TRANSITION_MS = 1200ms — durée du crossfade CSS ease-in-out * OVERLAP_MS = 3800ms — délai avant déclenchement du crossfade * (DISPLAY − TRANSITION = 3800ms) * * FONCTIONNEMENT : * t = 0 → slide N devient is-active * Ken Burns scale(1.0 → 1.08) démarre * t = 3800ms → crossfadeTo() déclenché : * slide N → is-leaving (opacity 1→0 / 1200ms) * slide N+1 → is-active (opacity 0→1 / 1200ms) * Ken Burns de N+1 démarre * t = 5000ms → crossfade terminé, slide N+1 pleinement visible * t = 5000ms → prochain cycle démarre (boucle) * * RÈGLES : * • Pas de pause au survol de la souris * • Couleur accent propagée via CSS var(--accent) par slide * • Labels en français (SUIVANT, Mettre en pause, etc.) * ============================================================ */(function () { 'use strict';/* ───────────────────────────────────────────────────────── CONSTANTES DE TIMING — synchronisées avec le CSS ───────────────────────────────────────────────────────── */ const DISPLAY_MS = 5000; // Affichage total par slide const TRANSITION_MS = 1200; // Durée du crossfade CSS const OVERLAP_MS = DISPLAY_MS - TRANSITION_MS; // 3800ms : déclenchement anticipé/* ───────────────────────────────────────────────────────── INIT D'UN SLIDER ───────────────────────────────────────────────────────── */ function initKMSlider(wrapper) {/* ── Config ── */ const id = wrapper.id; const slidesData = (window.kmSliderData && window.kmSliderData[id]) || []; const auto = wrapper.dataset.auto !== 'false'; const total = parseInt(wrapper.dataset.total) || 0;if (total < 1) return;/* ── Éléments DOM ── */ const slides = wrapper.querySelectorAll('.km-slide'); const dots = wrapper.querySelectorAll('.km-dot'); const counter = wrapper.querySelector('.km-counter__current'); const progressFill = wrapper.querySelector('.km-progress-fill'); const nextTitle = wrapper.querySelector(`#${id}-next-title`); const btnPrev = wrapper.querySelector('.km-nav--prev'); const btnNext = wrapper.querySelector('.km-nav--next'); const btnPlay = wrapper.querySelector('.km-play-pause');if (!slides.length) return;/* ── État ── */ let current = 0; let isPlaying = auto; let overlapTimer = null; // Timer OVERLAP_MS → déclenche le crossfade let cleanTimer = null; // Timer TRANSITION_MS → nettoie is-leaving/* ── Utilitaires ── */ const pad = n => String(n).padStart(2, '0'); const mod = (n, m) => ((n % m) + m) % m; const getData = i => slidesData[i] || {};/* ─────────────────────────────────────────────────────── MISE À JOUR UI Compteur · Dots · Titre SUIVANT · Couleur accent ─────────────────────────────────────────────────────── */ function updateUI(index) {// Compteur numérique if (counter) counter.textContent = pad(index + 1);// Dots : classe active + aria dots.forEach((d, i) => { d.classList.toggle('is-active', i === index); d.setAttribute('aria-selected', i === index ? 'true' : 'false'); });// Titre SUIVANT : micro fade-out → mise à jour → fade-in const nextIdx = mod(index + 1, total); if (nextTitle) { nextTitle.classList.add('is-updating'); setTimeout(() => { nextTitle.textContent = getData(nextIdx).titre || ''; nextTitle.classList.remove('is-updating'); }, 300); }// Couleur accent : propagée à tous les éléments via var(--accent) const accent = getData(index).couleur || '#E63946'; wrapper.style.setProperty('--accent', accent); }/* ─────────────────────────────────────────────────────── BARRE DE PROGRESSION Se remplit sur DISPLAY_MS (5000ms) en continu. ─────────────────────────────────────────────────────── */ function startProgress() { if (!progressFill) return; progressFill.style.transition = 'none'; progressFill.style.width = '0%'; void progressFill.offsetWidth; // Force reflow progressFill.style.transition = `width ${DISPLAY_MS}ms linear`; progressFill.style.width = '100%'; }function stopProgress() { if (!progressFill) return; const computed = parseFloat(getComputedStyle(progressFill).width); const parent = progressFill.parentElement; const pct = parent ? (computed / parent.offsetWidth) * 100 : 0; progressFill.style.transition = 'none'; progressFill.style.width = pct + '%'; }function resetProgress() { if (!progressFill) return; progressFill.style.transition = 'none'; progressFill.style.width = '0%'; }/* ─────────────────────────────────────────────────────── CROSSFADE — cœur de la transition ─────────────────────────────────────────────────────── Appelé à t = OVERLAP_MS (3800ms) après le début d'affichage. • Slide sortant → is-leaving : opacity 1→0 sur 1200ms • Slide entrant → is-active : opacity 0→1 sur 1200ms Ken Burns scale(1→1.08) sur 5000ms ─────────────────────────────────────────────────────── */ function crossfadeTo(nextIndex) { const prev = current; current = mod(nextIndex, total);const slideOut = slides[prev]; const slideIn = slides[current];// Slide sortant : amorce le fondu sortant CSS slideOut.classList.remove('is-active'); slideOut.classList.add('is-leaving'); slideOut.setAttribute('aria-hidden', 'true');// Slide entrant : amorce le fondu entrant + Ken Burns CSS slideIn.classList.add('is-active'); slideIn.setAttribute('aria-hidden', 'false');// Mise à jour interface updateUI(current);// Nettoyage du slide sortant après fin du crossfade clearTimeout(cleanTimer); cleanTimer = setTimeout(() => { slideOut.classList.remove('is-leaving'); }, TRANSITION_MS + 50); // +50ms de marge de sécurité// Planifier le prochain crossfade si autoplay actif if (isPlaying) scheduleNext(); }/* ─────────────────────────────────────────────────────── AUTOPLAY — timer précis OVERLAP ─────────────────────────────────────────────────────── Le crossfade est déclenché à OVERLAP_MS (3800ms) pour que la transition se termine exactement à DISPLAY_MS (5000ms). ─────────────────────────────────────────────────────── */ function scheduleNext() { clearTimeout(overlapTimer); if (!isPlaying) return; overlapTimer = setTimeout(() => { crossfadeTo(current + 1); }, OVERLAP_MS); }function cancelAutoplay() { clearTimeout(overlapTimer); }/* ─────────────────────────────────────────────────────── NAVIGATION MANUELLE Déclenche le crossfade immédiatement, repart sur un cycle complet de DISPLAY_MS. ─────────────────────────────────────────────────────── */ function goTo(index) { const target = mod(index, total); if (target === current) return;cancelAutoplay(); resetProgress(); crossfadeTo(target);if (isPlaying) startProgress(); }const nextSlide = () => goTo(current + 1); const prevSlide = () => goTo(current - 1);/* ─────────────────────────────────────────────────────── LECTURE / PAUSE ─────────────────────────────────────────────────────── */ function play() { isPlaying = true; if (btnPlay) { btnPlay.classList.remove('is-paused'); btnPlay.setAttribute('aria-label', 'Mettre en pause'); } scheduleNext(); startProgress(); }function pause() { isPlaying = false; cancelAutoplay(); if (btnPlay) { btnPlay.classList.add('is-paused'); btnPlay.setAttribute('aria-label', 'Reprendre la lecture'); } stopProgress(); }/* ─────────────────────────────────────────────────────── ÉVÉNEMENTS ─────────────────────────────────────────────────────── */// Flèches if (btnPrev) btnPrev.addEventListener('click', prevSlide); if (btnNext) btnNext.addEventListener('click', nextSlide);// Lecture / Pause if (btnPlay) { btnPlay.addEventListener('click', () => isPlaying ? pause() : play()); }// Points de navigation dots.forEach(dot => { dot.addEventListener('click', () => { const i = parseInt(dot.dataset.goto, 10); if (!isNaN(i) && i !== current) goTo(i); }); });// PAS de pause au survol — comportement intentionnel// Swipe tactile let txStart = 0, tyStart = 0; wrapper.addEventListener('touchstart', e => { txStart = e.touches[0].clientX; tyStart = e.touches[0].clientY; }, { passive: true });wrapper.addEventListener('touchend', e => { const dx = txStart - e.changedTouches[0].clientX; const dy = tyStart - e.changedTouches[0].clientY; if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) { dx > 0 ? nextSlide() : prevSlide(); } }, { passive: true });// Navigation clavier wrapper.setAttribute('tabindex', '0'); wrapper.addEventListener('keydown', e => { switch (e.key) { case 'ArrowRight': nextSlide(); break; case 'ArrowLeft': prevSlide(); break; case ' ': e.preventDefault(); isPlaying ? pause() : play(); break; } });/* ─────────────────────────────────────────────────────── INITIALISATION ─────────────────────────────────────────────────────── */ (function init() {// Le slide 0 est déjà is-active dans le HTML (via PHP) if (counter) counter.textContent = pad(1);dots.forEach((d, i) => { d.classList.toggle('is-active', i === 0); d.setAttribute('aria-selected', i === 0 ? 'true' : 'false'); });// Titre SUIVANT : slide index 1 if (nextTitle) { nextTitle.textContent = getData(mod(1, total)).titre || ''; }// Couleur accent initiale wrapper.style.setProperty('--accent', getData(0).couleur || '#E63946');// prefers-reduced-motion → pas d'autoplay if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { return; }// Démarrage de l'autoplay if (isPlaying) { scheduleNext(); // Premier crossfade à OVERLAP_MS (3800ms) startProgress(); // Barre de progression sur DISPLAY_MS (5000ms) } })(); }/* ───────────────────────────────────────────────────────── BOOTSTRAP — Initialise tous les sliders de la page ───────────────────────────────────────────────────────── */ function boot() { document.querySelectorAll('.km-hero-slider').forEach(initKMSlider); }if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); }})();) * * CORRECTIONS v11 vs v10 : * 1. Throbber : exclut explicitement #kpm-cta-artiste du listener * (sécurité supplémentaire, target="_blank" suffit déjà). * 2. Aucune autre logique modifiée (rétrocompatible v10). * ════════════════════════════════════════════════════════════════ */ (function () { 'use strict';document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', init) : init();function init() { injectPageLoader(); initCompactOnScroll(); initProgressBar(); initDynamicColors(); initMegaMenu(); initArtistePageActive(); initActualitesPageActive(); initBurgerMenu(); initThrobberLoader(); }/* ══════════════════════════════════════════════════════════════ UTILITAIRES COULEUR ══════════════════════════════════════════════════════════════ */ function hexToRgb(hex) { var c = (hex || '').replace('#', ''); if (c.length === 3) c = c[0]+c[0]+c[1]+c[1]+c[2]+c[2]; var m = /^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(c); return m ? { r:parseInt(m[1],16), g:parseInt(m[2],16), b:parseInt(m[3],16) } : null; }function tintLogoImage(img, hexColor) { if (!img || img.tagName !== 'IMG') return; var rgb = hexToRgb(hexColor); if (!rgb) return; if (!img.dataset.originalSrc) img.dataset.originalSrc = img.src; var t = new Image(); t.crossOrigin = 'anonymous'; t.onload = function() { try { var cv = document.createElement('canvas'); cv.width = t.naturalWidth || 100; cv.height = t.naturalHeight || 100; var ctx = cv.getContext('2d'); ctx.drawImage(t,0,0); var id = ctx.getImageData(0,0,cv.width,cv.height), d = id.data; for (var i=0; i10) { var l=(d[i]*.299+d[i+1]*.587+d[i+2]*.114)/255; d[i]=Math.round(rgb.r*l); d[i+1]=Math.round(rgb.g*l); d[i+2]=Math.round(rgb.b*l); } } ctx.putImageData(id,0,0); img.src = cv.toDataURL('image/png'); img.style.filter='none'; } catch(e) { applyLogoFilterFallback(img, hexColor); } }; t.onerror = function() { applyLogoFilterFallback(img, hexColor); }; t.src = img.dataset.originalSrc; }function applyLogoFilterFallback(img, hex) { var rgb = hexToRgb(hex); if (!rgb) { img.style.filter='brightness(0) invert(1)'; return; } var r=rgb.r/255,g=rgb.g/255,b=rgb.b/255, mx=Math.max(r,g,b),mn=Math.min(r,g,b),h=0,s=0,l=(mx+mn)/2; if (mx!==mn){var d=mx-mn; s=l>.5?d/(2-mx-mn):d/(mx+mn); if(mx===r) h=((g-b)/d+(g THRESHOLD; if (sc===isCompact) return; isCompact=sc; header.classList.toggle('kpm-compact',isCompact); applyState(isCompact); }, {passive:true});window.addEventListener('resize', function() { H_NORMAL = window.matchMedia('(max-width:600px)').matches ? 56 : window.matchMedia('(max-width:868px)').matches ? 60 : window.matchMedia('(max-width:1024px)').matches ? 64 : 72; if (!isCompact) applyState(false); }, {passive:true});applyState(false); }/* ══════════════════════════════════════════════════════════════ 2. BARRE DE PROGRESSION ══════════════════════════════════════════════════════════════ */ function initProgressBar() { var bar = document.getElementById('kpm-progress')||document.querySelector('.kpm-progress-bar'); if (!bar) return; window.addEventListener('scroll', function() { var s=document.documentElement.scrollTop||document.body.scrollTop; var t=document.documentElement.scrollHeight-document.documentElement.clientHeight; bar.style.width = t>0 ? (s/t*100)+'%' : '0%'; }, {passive:true}); }/* ══════════════════════════════════════════════════════════════ 3. COULEURS DYNAMIQUES ══════════════════════════════════════════════════════════════ */ function initDynamicColors() { var menuLinks = document.querySelectorAll('.kpm-menu > li > a[data-color]'); var logo = document.getElementById('kpm-logo-svg')||document.getElementById('kpm-logo-text'); var bar = document.getElementById('kpm-progress')||document.querySelector('.kpm-progress-bar'); if (!menuLinks.length) return;var activeLink = null; var initItem = document.querySelector('.kpm-menu > li.current-menu-item > a[data-color]'); if (initItem && !document.body.classList.contains('single-nos-artistes') && !document.body.classList.contains('kpm-is-actualites')) { activeLink = initItem; colorItem(initItem, initItem.getAttribute('data-color')||'#6621c3'); applyLogoColor(logo, initItem.getAttribute('data-logo-color')||initItem.getAttribute('data-color')||'#6621c3'); if (bar) bar.style.background = initItem.getAttribute('data-color')||'#6621c3'; }menuLinks.forEach(function(link) { var mc = link.getAttribute('data-color')||'#6621c3'; var lc = link.getAttribute('data-logo-color')||mc; var li = link.closest('li');link.addEventListener('mouseenter', function() { colorItem(link,mc); }); link.addEventListener('mouseleave', function() { var act = (link===activeLink)||(li&&(li.classList.contains('current-menu-item')||li.classList.contains('nos-artistes-actif'))); act ? colorItem(link,mc) : resetItem(link); }); link.addEventListener('click', function() { if (link.classList.contains('kpm-menu-trigger')) return; menuLinks.forEach(function(l2){ var l2li=l2.closest('li'); if(l2li) l2li.classList.remove('current-menu-item'); if(l2!==link) resetItem(l2); }); li&&li.classList.add('current-menu-item'); activeLink=link; colorItem(link,mc); applyLogoColor(logo,lc); if (bar) bar.style.background=mc; }); }); }/* ══════════════════════════════════════════════════════════════ 4. PAGES ARTISTE — item "Nos Artistes" actif ══════════════════════════════════════════════════════════════ */ function initArtistePageActive() { if (!document.body.classList.contains('single-nos-artistes')) return; var trigger = document.querySelector('.kpm-menu-trigger'); var logo = document.getElementById('kpm-logo-svg')||document.getElementById('kpm-logo-text'); var bar = document.getElementById('kpm-progress')||document.querySelector('.kpm-progress-bar'); if (!trigger) return; var mc=trigger.getAttribute('data-color')||'#c0392b'; var lc=trigger.getAttribute('data-logo-color')||mc; var li=trigger.closest('li'); if (li) { li.classList.add('nos-artistes-actif','current-menu-item'); } colorItem(trigger,mc); applyLogoColor(logo,lc); if (bar) bar.style.background=mc; }/* ══════════════════════════════════════════════════════════════ 5. PAGES ACTUALITÉS — item "Actualités" actif ══════════════════════════════════════════════════════════════ */ function initActualitesPageActive() { if (!document.body.classList.contains('kpm-is-actualites')) return;var logo = document.getElementById('kpm-logo-svg')||document.getElementById('kpm-logo-text'); var bar = document.getElementById('kpm-progress')||document.querySelector('.kpm-progress-bar');var actuLink = null; var menuLinks = document.querySelectorAll('.kpm-menu > li > a[data-color]'); menuLinks.forEach(function(link) { var label = (link.querySelector('.menu-label')||link).textContent.toLowerCase().trim(); if (label.indexOf('actu') !== -1 || label.indexOf('news') !== -1 || label.indexOf('blog') !== -1) { actuLink = link; } });if (!actuLink) return;var mc = actuLink.getAttribute('data-color') || '#6621c3'; var lc = actuLink.getAttribute('data-logo-color') || mc; var li = actuLink.closest('li');if (li) li.classList.add('current-menu-item', 'kpm-actualites-actif'); colorItem(actuLink, mc); applyLogoColor(logo, lc); if (bar) bar.style.background = mc; }/* ══════════════════════════════════════════════════════════════ 6. MÉGA MENU ══════════════════════════════════════════════════════════════ */ function initMegaMenu() { var trigger = document.querySelector('.kpm-menu-trigger'); var dropdown = document.querySelector('.has-megamenu .aa-dropdown'); var btnBack = dropdown ? dropdown.querySelector('.aa-dropdown-back') : null; var logo = document.getElementById('kpm-logo-svg')||document.getElementById('kpm-logo-text'); var bar = document.getElementById('kpm-progress')||document.querySelector('.kpm-progress-bar'); if (!trigger || !dropdown) return;var isOpen = false; var mc = trigger.getAttribute('data-color') || '#6621c3'; var lc = trigger.getAttribute('data-logo-color') || mc; var li = trigger.closest('li');function open() { isOpen = true; dropdown.classList.add('is-open'); dropdown.setAttribute('aria-hidden','false'); trigger.setAttribute('aria-expanded','true'); colorItem(trigger,mc); applyLogoColor(logo,lc); if (bar) bar.style.background = mc; if (!isMobileNav()) { dropdown.querySelectorAll('.aa-drop-card').forEach(function(c,i){ c.style.animationDelay = (i*.04)+'s'; }); } }function close() { isOpen = false; dropdown.classList.remove('is-open'); dropdown.setAttribute('aria-hidden','true'); trigger.setAttribute('aria-expanded','false'); if (!document.body.classList.contains('single-nos-artistes') && li && !li.classList.contains('current-menu-item')) { resetItem(trigger); } }trigger.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); isOpen ? close() : open(); });if (btnBack) { btnBack.addEventListener('click', function(e) { e.stopPropagation(); close(); trigger.focus(); }); }document.addEventListener('click', function(e) { if (!isOpen || isMobileNav()) return; if (!dropdown.contains(e.target) && !trigger.contains(e.target)) close(); });document.addEventListener('keydown', function(e) { if (e.key==='Escape' && isOpen) close(); });dropdown.addEventListener('wheel', function(e) { if (isMobileNav()) return; var grid = dropdown.querySelector('.aa-dropdown-grid'); if (grid && !dropdown.classList.contains('aa-dropdown-grid--wrap')) { e.preventDefault(); grid.scrollLeft += e.deltaY; } }, {passive:false}); }/* ══════════════════════════════════════════════════════════════ 7. BURGER MENU ══════════════════════════════════════════════════════════════ */ function initBurgerMenu() { var burger = document.getElementById('kpm-burger'); var nav = document.getElementById('kpm-nav'); var overlay = document.getElementById('kpm-overlay'); var dropdown = document.querySelector('.has-megamenu .aa-dropdown'); if (!burger || !nav || !overlay) return; var isOpen = false;function openNav() { isOpen = true; burger.classList.add('is-active'); burger.setAttribute('aria-expanded','true'); nav.classList.add('is-active'); overlay.classList.add('is-active'); overlay.setAttribute('aria-hidden','false'); document.body.style.overflow = 'hidden'; }function closeNav() { isOpen = false; if (dropdown && dropdown.classList.contains('is-open')) { dropdown.classList.remove('is-open'); dropdown.setAttribute('aria-hidden','true'); var trig = document.querySelector('.kpm-menu-trigger'); if (trig) trig.setAttribute('aria-expanded','false'); } burger.classList.remove('is-active'); burger.setAttribute('aria-expanded','false'); nav.classList.remove('is-active'); overlay.classList.remove('is-active'); overlay.setAttribute('aria-hidden','true'); document.body.style.overflow = ''; }burger.addEventListener('click', function() { isOpen ? closeNav() : openNav(); }); overlay.addEventListener('click', closeNav);nav.querySelectorAll('.kpm-menu a').forEach(function(l) { l.addEventListener('click', function() { if (l.classList.contains('kpm-menu-trigger')) return; if (isOpen) setTimeout(closeNav, 250); }); });document.addEventListener('keydown', function(e) { if (e.key==='Escape' && isOpen) closeNav(); }); }/* ══════════════════════════════════════════════════════════════ 8. THROBBER LOADER ══════════════════════════════════════════════════════════════ v11 : exclut #kpm-cta-artiste (target="_blank" suffit déjà, mais on sécurise avec un check explicite sur l'id). ══════════════════════════════════════════════════════════════ */ function initThrobberLoader() { var logo = document.getElementById('kpm-logo-svg')||document.getElementById('kpm-logo-text'); var overlay = document.getElementById('kpm-page-loader'); var iconEl = document.getElementById('kpm-loader-icon');if (logo && logo.tagName==='IMG' && iconEl && iconEl.tagName==='IMG') { iconEl.src = logo.dataset.originalSrc || logo.src; }var isLoading=false, kickT=null, stopT=null, safeT=null;function clearClasses(el) { if (!el) return; el.classList.remove('kpm-throbber-kick','kpm-throbbing','kpm-throbber-stop'); }function startThrobber() { if (isLoading) return; isLoading=true; clearTimeout(kickT); clearTimeout(stopT); clearTimeout(safeT); overlay && overlay.classList.add('kpm-loader-active'); overlay && overlay.classList.remove('kpm-loader-exit'); [logo, iconEl].forEach(function(el){ clearClasses(el); el&&el.classList.add('kpm-throbber-kick'); }); kickT = setTimeout(function() { if (!isLoading) return; [logo, iconEl].forEach(function(el){ clearClasses(el); el&&el.classList.add('kpm-throbbing'); }); }, 600); safeT = setTimeout(stopThrobber, 8000); }function stopThrobber() { if (!isLoading) return; isLoading=false; clearTimeout(kickT); clearTimeout(safeT); [logo, iconEl].forEach(function(el){ clearClasses(el); el&&el.classList.add('kpm-throbber-stop'); }); if (overlay) { overlay.classList.remove('kpm-loader-active'); overlay.classList.add('kpm-loader-exit'); } stopT = setTimeout(function() { [logo, iconEl].forEach(function(el){ clearClasses(el); }); overlay&&overlay.classList.remove('kpm-loader-exit'); }, 600); }document.querySelectorAll('.kpm-menu a').forEach(function(link) { link.addEventListener('click', function() { if (link.classList.contains('kpm-menu-trigger')) return; if (link.target==='_blank') return; /* v11 : sécurité supplémentaire — ne jamais throbber sur le CTA artiste */ if (link.id === 'kpm-cta-artiste') return; startThrobber(); window.addEventListener('beforeunload', stopThrobber, {once:true}); }); });window.addEventListener('load', function() { if (isLoading) stopThrobber(); }); window.addEventListener('pageshow', function() { if (isLoading) stopThrobber(); }); window.addEventListener('popstate', function() { if (isLoading) stopThrobber(); }); }})();) * * Comportement style Reach Records : * → Clic "Nos Artistes" = dropdown s'ouvre SOUS le header * → La page en dessous reste visible * → L'URL passe à /nos-artistes/ via pushState * → Clic en dehors / Échap / ✕ = ferme * → Clic sur une image = navigue vers l'artiste * ================================================================ */ (function () { 'use strict';document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', init) : init();function init() { var trigger = document.querySelector('.rr-menu-trigger, .aa-nav-trigger'); var dropdown = document.getElementById('aa-dropdown');if (!trigger || !dropdown) return;var btnClose = dropdown.querySelector('.aa-dropdown-close'); var archiveUrl = trigger.getAttribute('href') || '/nos-artistes/'; var urlOrigin = window.location.href; var isOpen = false; var histPushed = false;/* ── Hauteur du header → positionne le dropdown ── */ function updateHeaderHeight() { var header = document.querySelector( '#masthead, .main-header-bar, .ast-primary-header-bar, .site-header, header' ); if (header) { var h = Math.round(header.getBoundingClientRect().height); document.documentElement.style.setProperty('--rr-header-h', h + 'px'); dropdown.style.top = h + 'px'; } } updateHeaderHeight(); window.addEventListener('resize', updateHeaderHeight, { passive: true });/* ── OUVRIR ── */ function open() { if (isOpen) return; isOpen = true;dropdown.classList.add('is-open'); dropdown.setAttribute('aria-hidden', 'false'); trigger.classList.add('is-active'); trigger.setAttribute('aria-expanded', 'true');/* URL → /nos-artistes/ sans rechargement */ if (window.history && window.history.pushState) { urlOrigin = window.location.href; window.history.pushState({ aaMenu: true }, 'Nos Artistes', archiveUrl); histPushed = true; }/* Animation cascade des cartes */ var cartes = dropdown.querySelectorAll('.aa-drop-card'); cartes.forEach(function (c, i) { c.classList.remove('rr-animate'); c.style.animationDelay = (i * 0.04) + 's'; void c.offsetWidth; // force reflow c.classList.add('rr-animate'); });/* Focus accessibilité */ var first = dropdown.querySelector('.aa-drop-card'); if (first) setTimeout(function () { first.focus(); }, 60); }/* ── FERMER ── */ function close(opts) { opts = opts || {}; if (!isOpen) return; isOpen = false;dropdown.classList.remove('is-open'); dropdown.setAttribute('aria-hidden', 'true'); trigger.classList.remove('is-active'); trigger.setAttribute('aria-expanded', 'false');/* Remet l'URL d'origine */ if (!opts.noHistory && histPushed && window.history && window.history.pushState) { window.history.pushState({ aaMenu: false }, document.title, urlOrigin); histPushed = false; }/* Reset animations */ dropdown.querySelectorAll('.aa-drop-card').forEach(function (c) { c.classList.remove('rr-animate'); c.style.animationDelay = ''; });trigger.focus(); }/* ── Clic sur le trigger ── */ trigger.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation();if (isOpen) { /* 2e clic → naviguer vers la page archive */ close({ noHistory: true }); window.location.href = archiveUrl; } else { open(); } });/* ── Bouton ✕ ── */ if (btnClose) { btnClose.addEventListener('click', function (e) { e.stopPropagation(); close(); }); }/* ── Clic en dehors ── */ document.addEventListener('click', function (e) { if (!isOpen) return; if (!dropdown.contains(e.target) && !trigger.contains(e.target)) close(); });/* ── Touche Échap ── */ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && isOpen) close(); });/* ── Navigation clavier dans le dropdown ── */ dropdown.addEventListener('keydown', function (e) { var liens = Array.from(dropdown.querySelectorAll('.aa-drop-card')); var idx = liens.indexOf(document.activeElement); if (idx === -1) return; var next; switch (e.key) { case 'ArrowRight': case 'ArrowDown': next = liens[(idx + 1) % liens.length]; break; case 'ArrowLeft': case 'ArrowUp': next = liens[(idx - 1 + liens.length) % liens.length]; break; case 'Home': next = liens[0]; break; case 'End': next = liens[liens.length - 1]; break; default: return; } if (next) { e.preventDefault(); next.focus(); } });/* ── Bouton Précédent du navigateur ── */ window.addEventListener('popstate', function () { if (isOpen) { isOpen = false; dropdown.classList.remove('is-open'); dropdown.setAttribute('aria-hidden', 'true'); trigger.classList.remove('is-active'); trigger.setAttribute('aria-expanded', 'false'); histPushed = false; dropdown.querySelectorAll('.aa-drop-card').forEach(function (c) { c.classList.remove('rr-animate'); }); } });/* ── Scroll horizontal dans le dropdown (tactile) ── */ dropdown.addEventListener('wheel', function (e) { var grid = dropdown.querySelector('.aa-dropdown-grid'); if (grid && !dropdown.classList.contains('aa-dropdown-grid--wrap')) { e.preventDefault(); grid.scrollLeft += e.deltaY; } }, { passive: false }); }})();