KOPHI’S MUSICest unlabel musical indépendant ivoirien, spécialisé dans l’Urban Gospel; un mouvement musical avant-gardiste qui fusionne les codes de la musique urbaine contemporaine avec des messages profondément ancrés dans la foi chrétienne.
Né d’une passion authentique et d’une vision claire,KOPHI’S MUSICest la division musicale (artistique) deKOPHI’S GROUP SAS. Il incarne une nouvelle génération de producteurs et d’artistes qui revendiquent leur foisans compromissur la qualité artistique et l’authenticité urbaine.
Pop Urbaine– accessibilité, modernité et impact immédiat
Notre philosophie :
Une approchelabel indépendant (Indie)qui privilégie la liberté artistique
Unaccompagnement personnalisé, à l’écoute de chaque artiste
Une ambition deproduction à standard mondial, depuis Abidjan
La conviction profonde quefoi et excellence artistiquepeuvent coexister
La création d’œuvres quiinspirent, élèvent et transcendent les frontières
Notre Histoire et Notre Évolution
L’histoire deKOPHI’S MUSICest celle d’une évolution organique, portée par la conviction et le travail acharné. Son parcours est un témoignage d’humilité, de persévérance et de croissance.
Notre Évolution
L’aventure commence dans le salon de son fondateur, Jean Philippe KOFFI aliasMonsieur Kophipar la création d’un Home Studio baptiséCELS HOUSE.
Loin d’être un simple home studio,CELS HOUSEétait un sanctuaire créatif. Son nom, acronyme de «ChristEstLaSolution », en était le fondement théologique et visionnaire. Dans ce lieu, la musique était conçue comme un ministère et un témoignage, posant les bases de tout ce qui allait suivre. Cet esprit de mission et d’artisanat demeure notre cœur battant.
La vision grandit et descend littéralement au rez-de-chaussée.
Le home studio évolue pour devenir un studio professionnel situé au rez-de-chaussée de l’immeuble. Cette matérialisation marque un tournant et la naissance officielle deKOPHI’S MUSICqui commence à produire et à publier ses premières œuvres, dont l’EP «Merci Seigneur» de Monsieur Kophi.
Cette période est marquée par des connexions stratégiques. La rencontre avec le beatmakerSchama Beats, puis avecMdrick Oninni, n’est pas perçue comme un simple hasard professionnel, mais comme une synergie divine.
Cette synergie mène à la production de l’album «GOAT POUR CHRIST» deMdrick Oninni, sorti en décembre 2024 dont la réédition est prévu pour 2025.
KOPHI’S MUSICse structure officiellement en label musical, division deKOPHI’S GROUP, fruit de l’association entre Monsieur Kophi, son épouse, Schama Beats et Mdrick Oninni.
Nos Activités et Services
Chez KOPHI'S MUSIC, nous avons bâti un écosystème artistique complet et structuré, pensé pour accompagner chaque projet musical de sa genèse jusqu'à son rayonnement international. Que vous soyez artiste en quête de signature, producteur à la recherche d'un partenaire créatif, ou simplement un passionné souhaitant enregistrer votre musique dans un cadre professionnel, nous avons une solution taillée pour vous.
Développement et Production d'Artistes
Le cœur battant deKOPHI’S MUSIC, c’est ses artistes. Nous ne nous contentons pas de signer des talents; nous lesaccompagnons, les façonnons et les propulsonsvers leur plein potentiel artistique et spirituel. Chaque artiste signé chez nous bénéficie d’un suivi individualisé, d’une production musicale aux standards internationaux et d’une stratégie de carrière construite sur le long terme.
Détection & Signature de Talents
Identification d’artistes dont lavision, les valeurs et les objectifss’alignent avec l’ADN du label
Processus de sélectionrigoureux mais bienveillant, basé sur l’authenticité, le potentiel et l’engagement spirituel
Signature dans un cadre contractuelclair, équitable et transparent, respectueux des droits de l’artiste
Sessions d’échanges approfondies pourcomprendre la vision de chaque artisteavant tout engagement
Production Musicale Complète
Composition et arrangementsmusicaux aux standards internationaux, couvrant tous les genres Urban Gospel (Hip-Hop, Afrobeat, Trap, RnB, Soul, Pop)
Direction artistiquepersonnalisée pour affiner l’identité sonore de chaque artiste
Mixage et mastering professionnelspour une qualité sonore compétitive sur toutes les plateformes
Production de clips et contenus visuelsen adéquation avec l’univers artistique de l’artiste
Développement de Carrière & Rayonnement
Stratégie de lancement et de promotionmulticanale : streaming, réseaux sociaux, médias, radio
Distribution numériquesur toutes les grandes plateformes (Spotify, Apple Music, Boomplay, YouTube Music, Deezer…)
Construction de l’image de marque: identité visuelle, storytelling, communication digitale
Préparation aux performances scéniques: coaching vocal, mise en scène, gestion du trac
Suivi des performanceset ajustement de la stratégie en fonction des résultats obtenus
Collaborations Créatives
ChezKOPHI’S MUSIC, nous croyons fermement que lacréativité s’épanouit dans la rencontre. C’est pourquoi nous cultivons activement des partenariats artistiques ouverts, sincères et mutuellement enrichissants. Qu’il s’agisse d’un artiste solo, d’un collectif, d’un producteur indépendant ou d’un autre label, nous sommes convaincus que l’Urban Gospel africain grandit plus vite et plus loinlorsque ses acteurs unissent leurs forces.
Co-Productions & Featurings
Collaborations avec des artistes de la scène Urban Gospellocale, panafricaine et internationale
Featurings stratégiquespour maximiser la visibilité des artistes et enrichir le catalogue du label
Co-productions musicalesavec des beatmakers et compositeurs partageant notre vision artistique et spirituelle
Compilations thématiquesréunissant plusieurs artistes autour d’un message commun fort
Partenariats Stratégiques & Institutionnels
Partenariats avec des labels, maisons de disques et distributeursafricains et internationaux pour élargir notre réseau
Collaborations avec des églises, ministères et organisations chrétiennespour ancrer notre musique dans les communautés de foi
Partenariats avec des médias spécialisés(radios chrétiennes, webzines musicaux, chaînes YouTube gospel) pour une diffusion ciblée
Collaborations avec des écoles de musique et structures de formationpour soutenir la relève artistique gospel
Événements & Projets Spéciaux
Organisation et participation à des concerts, showcases et festivalsUrban Gospel en Côte d’Ivoire et à l’international
Sessions créatives collectives(camps d’écriture, sessions de production groupées) pour stimuler l’innovation artistique
Projets cross-borderréunissant des artistes de différents pays d’Afrique francophone autour d’une vision commune
Le studio deKOPHI’S MUSICest bien plus qu’un simple espace technique; c’est unsanctuaire de la création musicale. Conçu pour répondre aux exigences des productions contemporaines les plus ambitieuses, il est ouvert aussi bien aux artistes du label qu’auxartistes externes, producteurs indépendants et créatifs de tous horizonssouhaitant donner vie à leurs projets dans des conditions optimales.
Services Proposés
Sessions d’enregistrement vocal et instrumentalencadrées par des ingénieurs du son expérimentés
Production de beats et arrangements musicauxsur mesure selon votre style et votre vision
Mixage professionnelpour un rendu sonore puissant, clair et équilibré
Mastering finalaux standards des plateformes de streaming internationales (Spotify, Apple Music, etc.)
Production de voix off, jingles et bandes sonorespour des projets audiovisuels et publicitaires
Accès & Tarification
Réservation de sessions flexibles: à l’heure, à la demi-journée ou à la journée complète
Tarifs adaptésà tous les profils : artistes émergents, producteurs confirmés, structures professionnelles
Forfaits spéciauxpour les projets complets (EP, album, mixtape) avec suivi de bout en bout
Tarifs préférentielspour les ministères, associations chrétiennes et artistes gospel en développement
ChezKOPHI’S MUSIC, nous ne faisons pas que produire de la musique. Nous bâtissons unmouvement culturel et spirituelancré dans la jeunesse africaine contemporaine. Notre vision s’articule autour de trois grandes ambitions :
Devenir la référence de l’Urban Gospel en Afrique francophone
PositionnerKOPHI’S MUSICcomme le label Urban Gospelnuméro 1 en Afrique francophone
Rayonner au-delà des frontières ivoiriennes vers leSénégal, le Cameroun, le Congo, la Franceet la diaspora africaine
Être reconnu comme unlabel de référence mondialedans la gospel music contemporaine
Créer une musique qui résonne avec la jeunesse
Proposer unemusique moderne, authentique et spirituellement richequi parle à la génération Z et aux milléniaux
Porter unmessage de foi fort et sans compromis, habillé dans les codes urbains actuels
Briser le cliché selon lequel la musique chrétienne ne peut pas êtrecool, urbaine et compétitivesur le plan artistique
Bâtir un écosystème durable pour l’Urban Gospel africain
Structurer uneindustrie musicale gospel professionnelleen Afrique francophone
Accompagner et former laprochaine génération d’artistes et producteursengagés
Créer des ponts entrel’Afrique, l’Europe et la diasporaà travers la musique
KOPHI'S MUSIC - Un Seul Esprit, une diversité de Don pour un Seul et Même But! Nous ne construisons pas seulement un label. Nous posons les fondations d'un mouvement.
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 });
}})();