Espace Artiste
Aller au contenu principal

Politique de confidentialité

Dernière mise à jour : mai 21, 2026

Ce site Web appartient et est exploité parKOPHI’S MUSIC, label Urban Gospel, la division musicale deKOPHI’S GROUP SAS(« nous », « notre » ou « le label »). La présente Politique de confidentialité explique le type d’informations que nous collectons sur ce site, comment nous pouvons utiliser ces informations et les choix dont vous disposez concernant la manière dont vos informations sont collectées et utilisées.

Veuillez lire attentivement cette Politique de confidentialité, car votre utilisation de ce site vaut confirmation que vous l’avez lue, comprise et que vous acceptez sans réserve nos pratiques en matière de confidentialité, telles que décrites dans le présent document. Nous vous invitons également à consulter nos Conditions d’utilisation qui régissent votre utilisation de ce site.

1. Quelles informations collectons-nous ?

Nous collectons des informations vous concernant lorsque vous vous inscrivez à un service sur le site (notamment notre serviceFuture Save), passez une commande, participez à un jeu-concours ou un tirage au sort, répondez à un sondage ou à une communication par email, ou utilisez une autre fonctionnalité du site.

Lors d’une inscription, d’une commande ou d’une prise de contact, nous pouvons être amenés à vous demander : votre prénom, votre nom, votre adresse email, votre adresse postale, votre numéro de téléphone, vos coordonnées de paiement ou toute autre information utile à la prestation demandée. Vous pouvez néanmoins consulter notre site de manière anonyme.

Comme la plupart des sites Web, nous utilisons des « cookies » pour améliorer votre expérience et recueillir des informations sur les visiteurs et les visites de notre site. Veuillez vous référer à la section « Utilisons-nous des cookies ? » ci-dessous pour plus de détails.

Nous recevons également des informations résultant de votre visite : votre adresse IP, votre type et version de navigateur, votre système d’exploitation, les pages que vous consultez, les produits que vous recherchez, la durée de vos visites et d’autres informations relatives à l’interaction avec le site. Spécifiquement pour le serviceFuture Save, nous enregistrons votre prénom, votre email, l’artiste ou le label que vous suivez, ainsi que la date, l’adresse IP et le User-Agent au moment de votre inscription (à titre de preuve de consentement).

L’ensemble des informations que nous collectons est ci-après désigné collectivement par « Informations Personnelles« .

2. Comment utilisons-nous vos Informations Personnelles ?

Nous pouvons utiliser les Informations Personnelles que nous collectons de la manière suivante :

  • Personnaliser votre expérience sur le site et vous proposer le type de contenu et d’offres musicales qui vous intéressent le plus
  • Vous envoyer les alertes de sorties auxquelles vous avez souscrit viaFuture Save
  • Mieux répondre à vos demandes de service client
  • Traiter rapidement vos commandes et transactions
  • Administrer un concours, une promotion, un sondage ou toute autre fonctionnalité du site
  • Vous envoyer périodiquement des emails informationnels ou promotionnels (newsletters, annonces de sorties, événements, opportunités), si vous avez explicitement opté pour ces communications

Si vous ne souhaitez plus recevoir nos emails promotionnels, veuillez consulter la section « Comment vous désinscrire, supprimer ou modifier les informations que vous nous avez fournies ? » ci-dessous. Si vous n’avez pas explicitement opté pour les newsletters, vous ne recevrez pas ces emails. Les visiteurs qui s’inscrivent ou participent à d’autres fonctionnalités du site (programmes marketing, contenus réservés aux membres) se voient toujours proposer le choix de figurer ou non sur notre liste de diffusion.

3. Comment protégeons-nous vos Informations Personnelles ?

Nous mettons en œuvre diverses mesures de sécurité pour préserver la confidentialité de vos Informations Personnelles. Vos données sont stockées derrière des réseaux sécurisés et ne sont accessibles qu’à un nombre limité de personnes disposant de droits d’accès spécifiques, qui sont tenues de respecter leur confidentialité.

Lorsque vous passez commande ou accédez à vos Informations Personnelles, nous utilisons une connexion serveur sécurisée. Toutes les informations sensibles ou bancaires que vous nous transmettez sont chiffrées via la technologie SSL (Secure Socket Layer) et stockées dans nos bases de données chiffrées, accessibles uniquement dans les conditions précitées.

Pour le service Future Save, chaque lien de confirmation et de désinscription est sécurisé par un token unique et non devinable. Des mécanismes anti-spam (honeypot, limitation par adresse IP) sont également en place.

4. Utilisons-nous des « cookies » ?

Oui. Les cookies sont de petits fichiers qu’un site ou son prestataire transfère sur le disque dur de votre ordinateur via votre navigateur Web (avec votre autorisation), permettant aux systèmes du site de reconnaître votre navigateur et de mémoriser certaines informations.

Par exemple, nous utilisons des cookies pour mémoriser le contenu de votre panier d’achat, comprendre vos préférences selon votre activité passée ou actuelle (afin de vous offrir de meilleurs services), et compiler des données agrégées sur le trafic et l’interaction avec le site afin d’améliorer l’expérience utilisateur. Nous pouvons faire appel à des prestataires tiers (analytics, embeds Spotify/YouTube, etc.) pour mieux comprendre notre audience. Ces prestataires ne sont pas autorisés à utiliser les informations collectées pour notre compte à d’autres fins que l’amélioration de notre activité.

Vous pouvez configurer votre navigateur pour être averti à chaque envoi de cookie, ou pour désactiver tous les cookies. Chaque navigateur étant différent, consultez le menu d’aide de votre navigateur pour connaître la procédure exacte. Notez que la désactivation des cookies peut limiter l’accès à certaines fonctionnalités du site.

5. Divulguons-nous les informations collectées à des tiers ?

Nous ne vendons, n’échangeons et ne transférons d’aucune autre manière vos informations personnellement identifiables à des tiers, sauf si nous vous en avertissons préalablement, et à l’exception des cas décrits ci-dessous. Le terme « tiers » n’inclut pas :

  • Notre entité juridique (KOPHI’S GROUP SAS et ses filiales)
  • Nos partenaires d’hébergement Web et autres prestataires nous aidant à exploiter le site, conduire notre activité ou vous servir (notamment : hébergeur, prestataire d’envoi d’emails comme Brevo ou MailerSend, prestataire de paiement, traitement des commandes), à condition que ces parties s’engagent à préserver la confidentialité des informations

Nous pouvons également divulguer vos informations lorsque nous estimons que cette divulgation est appropriée pour : respecter la loi, faire appliquer nos conditions d’utilisation, ou protéger nos droits, propriétés ou la sécurité de tiers. Toutefois, des informations non personnellement identifiables peuvent être fournies à d’autres parties à des fins de marketing, de publicité ou d’analyse.

Nous pouvons être amenés à transférer vos Informations Personnelles dans le cadre de la vente de la quasi-totalité des actifs de notre activité, d’une fusion, d’une consolidation ou d’une acquisition. Dans un tel cas, tout acquéreur sera lié par les engagements de la présente Politique.

6. Comment vous désinscrire, supprimer ou modifier les informations que vous nous avez fournies ?

Pour modifier vos préférences d’abonnement email, vous disposez de plusieurs options :

  • Désinscription en 1 clic :cliquez sur le lien « Se désabonner » présent dans chacun de nos emails Future Save
  • Modification ou suppression complète :contactez-nous àcontact@kophismusic.comavec votre demande

Veuillez noter que, en raison des cycles de production des emails, vous pourrez recevoir des envois déjà programmés peu après votre désinscription. Nous pouvons également conserver une trace d’une transaction commerciale pendant la durée nécessaire à son suivi et au respect de nos obligations comptables et légales.

Liens vers des sites tiers :Pour vous offrir une valeur ajoutée, nous incluons parfois des liens vers des sites tiers (plateformes de streaming musical, réseaux sociaux, partenaires). Ces sites disposent de politiques de confidentialité distinctes et indépendantes. Nous ne sommes par conséquent pas responsables du contenu et des activités de ces sites. Nous restons toutefois soucieux de l’intégrité de notre site et accueillons tout retour à leur sujet (notamment en cas de lien défectueux).

7. Avis aux résidents de l’Union européenne (RGPD)

Si vous êtes résident de l’Union européenne, le Règlement Général sur la Protection des Données (RGPD) vous confère les droits suivants sur vos données :

  • Droit d’accès :obtenir une copie des données que nous détenons sur vous
  • Droit de rectification :corriger une information inexacte
  • Droit à l’effacement(« droit à l’oubli ») : demander la suppression de vos données
  • Droit d’opposition :vous opposer à un traitement
  • Droit de retrait du consentement :vous désinscrire à tout moment
  • Droit à la portabilité :récupérer vos données dans un format lisible
  • Droit d’introduire une réclamationauprès de l’autorité de protection des données de votre pays de résidence (en France : la CNIL —www.cnil.fr)

Pour exercer ces droits, écrivez-nous àcontact@kophismusic.com. Nous répondrons dans un délai maximum de30 jours.

8. Avis aux résidents de Californie et autres juridictions américaines (CCPA)

Les résidents de Californie disposent du droit, une fois par an, de demander et d’obtenir certaines informations concernant la divulgation, le cas échéant, de leurs Informations Personnelles à des tiers à des fins de marketing direct durant l’année calendaire précédente. Conformément à la présente Politique, nous offrons aux visiteurs la possibilité de nous indiquer de ne pas partager leurs informations personnellement identifiables avec des tiers à des fins de marketing direct.

Pour formuler une telle demande, envoyez un email àcontact@kophismusic.com. L’expéditeur doit indiquer le nom de ce site Web en objet, ainsi que ses nom complet, adresse email et adresse postale dans le corps du message.

9. Mineurs de moins de treize (13) ans

Nous ne collectons sciemment aucune Information Personnelle d’enfants de moins de treize (13) ans, sauf si la collecte est conforme à la législation applicable en matière de protection des mineurs en ligne (notamment le COPPA aux États-Unis et l’article 8 du RGPD en Europe).

Si vous avez moins de 13 ans, ne nous transmettez aucune information vous concernant.Si nous découvrons qu’un enfant de moins de 13 ans nous a fourni des Informations Personnelles, nous mettrons tout en œuvre dans des délais raisonnables pour supprimer ces informations de nos systèmes.

10. Notification des modifications

Toute modification de notre Politique de confidentialité sera publiée sur ce site et prendra effet à la date de publication, concernant les Informations Personnelles que nous collecterons à l’avenir. Elle ne modifiera pas les conditions applicables aux Informations Personnelles déjà collectées.

Il est de votre responsabilité de consulter régulièrement notre Politique de confidentialité afin de prendre connaissance de toute modification. Les modifications substantielles vous seront, dans la mesure du possible, notifiées par email.

11. Sécurité

Nous nous efforçons d’assurer la sécurité des Informations Personnelles de l’utilisateur sur nos systèmes, notamment en limitant l’accès à ces informations sur nos serveurs. Malheureusement, aucune transmission de données sur Internet ne peut être garantie sûre à 100 %. Par conséquent, nous ne pouvons pas garantir la sécurité absolue des informations que vous nous transmettez, et vous le faites à vos propres risques.

En cas de violation de données susceptible d’engendrer un risque pour vos droits et libertés, nous nous engageons à vous en notifier dans les meilleurs délais, conformément à nos obligations légales.

12. Liens externes

Veuillez noter que lorsque vous naviguez sur notre site Web ou consultez un email ou tout autre contenu fourni par nous, vous pouvez avoir la possibilité de cliquer sur des liens qui vous mèneront hors de notre service vers d’autres sites Web ou contenus en ligne échappant à notre contrôle.

Vous pourriez par exemple être amené à cliquer sur des liens vers des sites de fans, des plateformes de streaming (Spotify, Apple Music, Deezer, YouTube), des sites de billetterie, ou des liens de sponsors ou partenaires. Nous n’avons aucun contrôle sur ces sites et n’en sommes pas responsables. Nous déclinons expressément toute responsabilité liée à votre utilisation de ces sites tiers et au contenu qui y figure.

Une fois que vous avez quitté notre site en cliquant sur un lien externe ou une publicité, nous vous invitons à consulter la politique de confidentialité applicable du site tiers pour déterminer s’il collecte des Informations Personnelles vous concernant et comment il les utilise.

13. Collecte et transferts internationaux de données

Ce site est exploité depuis laCôte d’Ivoire, où KOPHI’S GROUP SAS a son siège social, et conformément à laLoi n° 2013-450 du 19 juin 2013relative à la protection des données à caractère personnel en Côte d’Ivoire, sous la supervision de l’Autorité de Régulation des Télécommunications de Côte d’Ivoire (ARTCI).

Si vous êtes situé dans l’Union européenne, au Canada, aux États-Unis ou ailleurs hors de Côte d’Ivoire, veuillez noter que toute information que vous nous fournissez sera collectée en Côte d’Ivoire et/ou transférée vers les pays où sont hébergés nos prestataires techniques (serveurs Web, services d’envoi d’emails, etc.). En utilisant notre site, en participant à nos services et/ou en nous fournissant vos informations, vous consentez à ce transfert.

Nous nous engageons à ce que ces transferts s’effectuent avec des garanties appropriées en matière de protection des données, conformément aux exigences légales applicables.

14. Questions et retours

Nous accueillons volontiers vos questions, commentaires et préoccupations concernant la vie privée. N’hésitez pas à nous adresser tout retour relatif à la confidentialité ou à tout autre sujet, à l’adressecontact@kophismusic.com.

Politique en ligne uniquement :la présente Politique de confidentialité ne s’applique qu’aux informations collectées via ce site Web, et non aux informations collectées hors ligne.

15. Votre consentement

En utilisant notre site, vous consentez à la présente Politique de confidentialité.

16. Confidentialité SMS et messagerie

Si vous nous fournissez un numéro de téléphone mobile, aucune information mobile ne sera partagée avec des tiers ou des affiliés à des fins de marketing ou de promotion. Les catégories décrites dans la présente Politique excluent expressément les données d’opt-in et de consentement liées à la messagerie texte (SMS) : ces informations ne seront partagées avec aucun tiers.


Contact du responsable de traitement

KOPHI’S MUSIC— Division musicale deKOPHI’S GROUP SAS
Abidjan, Côte d’Ivoire
📧contact@kophismusic.com
🌐kophismusic.com

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 }); }})();