/* Cicada — musique. Interface mobile d'abord, sombre, sobre et lisible.
   Aucune dependance : tout est ecrit a la main pour rester leger sur un VPS
   de 2 cœurs. */

:root {
  --fond: #0b0714;
  --fond-2: #130c22;
  --verre: rgba(255, 255, 255, .055);
  --verre-fort: rgba(255, 255, 255, .1);
  --bord: rgba(255, 255, 255, .1);
  --texte: #f4f1fb;
  --texte-doux: #a79fbd;
  --accent: #b07bff;
  --accent-2: #ff6fae;
  --ok: #57e0a0;
  --rayon: 18px;
  --ombre: 0 18px 40px rgba(0, 0, 0, .45);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* ⚠️ L'attribut `hidden` ne suffit PAS : une regle CSS qui fixe `display`
   (ici `.mini{display:flex}`, `.feuille{display:grid}`) l'emporte sur la feuille
   du navigateur. Sans cette ligne, la feuille de telechargement restait
   AFFICHEE en permanence et son flou s'appliquait a toute la page. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--fond);
  color: var(--texte);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  min-height: 100vh;
  overflow-x: hidden;
  padding-bottom: 140px;
}

/* ───────────────────────────── fond anime */
.fond { position: fixed; inset: 0; z-index: -1; overflow: hidden; background:
  radial-gradient(120% 90% at 50% 0%, #1a1030 0%, var(--fond) 60%); }
.orbe { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .5;
  animation: derive 26s ease-in-out infinite alternate; }
.orbe-1 { width: 60vw; height: 60vw; background: #6b3df0; top: -18vw; left: -12vw; }
.orbe-2 { width: 52vw; height: 52vw; background: #ff3d84; bottom: -16vw; right: -14vw;
  animation-delay: -8s; }
.orbe-3 { width: 44vw; height: 44vw; background: #22d3ee; top: 38%; left: 40%;
  opacity: .28; animation-delay: -15s; }
@keyframes derive {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(4vw, 6vw, 0) scale(1.15); }
}
@media (prefers-reduced-motion: reduce) { .orbe { animation: none; } }

/* ───────────────────────────── entete */
.entete {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 18px 10px; position: sticky; top: 0; z-index: 20;
  background: linear-gradient(180deg, rgba(11, 7, 20, .92), rgba(11, 7, 20, .45) 70%, transparent);
  backdrop-filter: blur(14px);
}
.marque { display: flex; align-items: center; gap: 12px; }
.logo {
  width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center;
  font-weight: 700; font-size: 20px; color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow: 0 8px 22px rgba(176, 123, 255, .35);
}
.marque-texte { display: flex; flex-direction: column; line-height: 1.15; }
.marque-texte strong { font-size: 17px; letter-spacing: .2px; }
.marque-texte small { color: var(--texte-doux); font-size: 12.5px; }
/* L'avatar du profil remplace la lettre « C » des que l'image est chargee :
   une vraie photo dit plus qu'une initiale, et elle vient du compte Suno. */
.logo-avatar { padding: 0; object-fit: cover; background: #241a3a;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .45); }

/* ───────────────────────────── en-tete de profil (banniere + avatar) */
.profil { padding: 0 18px; }
.profil-banniere {
  position: relative; border-radius: var(--rayon); overflow: hidden;
  aspect-ratio: 1200 / 670; border: 1px solid var(--bord);
  box-shadow: var(--ombre); background: #241a3a;
}
.profil-banniere img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Le degrade garantit que le nom et les chiffres restent lisibles, quelle que
   soit la photo : sans lui, un bas de banniere clair mangerait le texte. */
.profil-banniere::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(11, 7, 20, 0) 32%, rgba(11, 7, 20, .5) 70%,
              rgba(11, 7, 20, .88) 100%);
}
.profil-corps {
  display: flex; align-items: center; gap: 12px; margin: -34px 6px 0;
  position: relative; z-index: 1;
}
.profil-avatar {
  width: 78px; height: 78px; border-radius: 50%; object-fit: cover; flex: none;
  border: 3px solid var(--fond); background: #241a3a;
  box-shadow: 0 12px 26px rgba(0, 0, 0, .55);
}
.profil-identite { display: flex; flex-direction: column; line-height: 1.2;
  min-width: 0; padding-top: 26px; }
.profil-identite strong { font-size: 19px; letter-spacing: .2px; }
.profil-handle { color: var(--texte-doux); font-size: 13px; text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profil-handle:hover { color: var(--accent); }
.profil-chiffres { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
.profil-chiffres span {
  border: 1px solid var(--bord); background: var(--verre); border-radius: 999px;
  padding: 5px 12px; font-size: 12.5px; color: var(--texte-doux);
}
.profil-chiffres b { color: var(--texte); font-weight: 600; margin-right: 3px; }

/* Trois commandes du profil : garder hors ligne, tout telecharger, installer.
   Elles passent a la ligne sur telephone plutot que de retrecir (mesure : trois
   pilules ne tiennent pas sur 375 px). */
.profil-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 0; }
.profil-actions .pilule { display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; text-decoration: none; font-size: 13px; }
.profil-actions .icone { width: 15px; height: 15px; flex: none; }

/* Jauge de progression du gardiennage hors ligne. */
.hl-jauge { height: 6px; border-radius: 999px; background: var(--verre);
  overflow: hidden; margin: 12px 0; }
.hl-jauge span { display: block; height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .25s ease; }
.hl-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 6px; }
.hl-actions .pilule { flex: 1 1 auto; text-align: center; }

/* Sur un grand ecran la banniere 1200x670 deviendrait plus haute que l'ecran :
   on la plafonne et l'image se recadre (object-fit) au lieu d'ecraser la liste. */
@media (min-width: 720px) {
  .profil-banniere { width: 100%; max-height: 46vh; }
  .profil-avatar { width: 92px; height: 92px; }
}

.rond {
  width: 42px; height: 42px; flex: none; border-radius: 50%; border: 1px solid var(--bord);
  background: var(--verre); color: var(--texte); font-size: 16px; cursor: pointer;
  display: grid; place-items: center; transition: transform .18s, background .18s;
}
.rond:active { transform: scale(.92); }
.rond-fort {
  background: linear-gradient(135deg, var(--accent), var(--accent-2)); border: none;
  color: #fff; box-shadow: 0 10px 24px rgba(176, 123, 255, .4);
}
.rond-large { width: 64px; height: 64px; font-size: 22px; }

/* ═══════════════════════════ TITRE DE LUXE + AVATAR VIVANT ═══════════════════
   La police est AUTO-HEBERGEE (`/polices/*.woff2`, 15-23 Ko) : un lien vers un
   CDN de polices ferait dépendre le titre du réseau — or l'app doit s'ouvrir
   hors ligne — et enverrait chaque visite chez un tiers. Trois polices sont
   téléchargées et comparables sur `/apercu-titre.html` ; c'est Cinzel qui sert
   (capitales romaines : la plus « luxe » et la seule qui reste nette en petit). */
@font-face {
  font-family: "Cinzel";
  src: url("/polices/cinzel-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
/* Deuxième police, pour les PAROLES : un serif fin se lit mieux qu'une police
   d'affiche sur du texte long. Elle vient du même téléchargement groupé. */
@font-face {
  font-family: "Cormorant";
  src: url("/polices/cormorant-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

.marque-texte strong, #profil-nom {
  font-family: "Cinzel", "Iowan Old Style", Georgia, serif;
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  font-size: 23px;                 /* plus imposant : 17 px -> 23 px */
}
#profil-nom { font-size: 31px; letter-spacing: .07em; }

/* Le reflet de COULEUR qui parcourt le titre : les teintes du site (violet,
   rose, cyan des halos) qui défilent, plus une lueur qui s'intensifie avec la
   musique et une respiration sur les basses.
   ⚠️ Le texte en dégradé devient INVISIBLE si `background-clip: text` n'est pas
   appliqué : le `color: transparent` est donc enfermé dans le `@supports`, pour
   que le titre reste lisible partout.
   ⚠️ Le défilé doit être SANS COUTURE : avec un fond de 200 % de large, glisser
   d'exactement une tuile (-200 %) ramène pile à l'image de départ, et le dégradé
   commence et finit sur la MÊME couleur — sinon on voit la soudure passer. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .marque-texte strong, #profil-nom {
    background-image: linear-gradient(100deg,
        var(--accent) 0%, #ffffff 10%, var(--accent-2) 20%, #ff2f92 28%,
        #ffffff 36%, #7fe3f5 46%, #22d3ee 52%, var(--accent) 62%,
        #ff2f92 74%, #ffffff 84%, var(--accent) 100%);
    background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
    animation: couleur-vive 5.5s linear infinite;
    filter: drop-shadow(0 0 calc(6px + 30px * var(--niveau, 0)) rgba(176, 123, 255, .75))
            drop-shadow(0 0 calc(2px + 12px * var(--niveau, 0)) rgba(255, 111, 174, .55));
  }
  #profil-nom { animation-duration: 7.5s; animation-direction: reverse; }
}

/* Respiration du titre sur les basses : `transform` ne déplace rien autour (il ne
   sort pas du flux), donc l'en-tête ne bouge pas — mais la pulsation se VOIT. */
#profil-nom {
  transform: scale(calc(1 + .055 * var(--basses, 0)));
  transform-origin: left center;
  transition: transform .09s linear;
}
.marque-texte strong {
  display: inline-block;
  transform-origin: left center;
  transform: scale(calc(1 + .07 * var(--basses, 0)));
  transition: transform .09s linear;
}

@keyframes couleur-vive {
  from { background-position: 0% 50%; }
  to   { background-position: -200% 50%; }
}

/* ── l'avatar, en haut à gauche : anneau vivant + particules mauves
   La boîte sert de repère : l'anneau et les particules se posent AUTOUR de la
   photo, sans jamais la recouvrir (le texte et le visage restent lisibles). */
.avatar-boite { position: relative; display: grid; place-items: center; flex: none; }
.logo-avatar { position: relative; z-index: 1; }
.avatar-anneau {
  position: absolute; inset: -3px; border-radius: 50%; padding: 1.5px;
  pointer-events: none; z-index: 2;
  background: conic-gradient(from var(--angle),
      transparent 0deg, var(--accent) 60deg, #ffffff 88deg, var(--accent-2) 118deg,
      transparent 190deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: tourner 7s linear infinite reverse;
  opacity: calc(.45 + .55 * var(--niveau, 0));
}
.particules {
  position: absolute; left: -33px; top: -12px; width: 108px; height: 66px;
  pointer-events: none; z-index: 0;
}

@media (prefers-reduced-motion: reduce) {
  .avatar-anneau { animation: none; }
  .marque-texte strong, #profil-nom { animation: none; }
  #profil-nom { transform: none; transition: none; }
  .particules { display: none; }
}

/* ───────────────────────────── outils */
main { padding: 0 18px; }
.outils { display: flex; gap: 10px; margin: 16px 0; }
#recherche {
  flex: 1 1 auto; min-width: 0; padding: 13px 16px; border-radius: 14px;
  border: 1px solid var(--bord); background: var(--verre); color: var(--texte);
  font-size: 15px; outline: none;
}
#recherche:focus { border-color: rgba(176, 123, 255, .55); background: var(--verre-fort); }
#tri {
  flex: none; max-width: 42%; padding: 13px 12px; border-radius: 14px;
  border: 1px solid var(--bord); background: var(--verre); color: var(--texte); font-size: 14px;
}
input::placeholder { color: var(--texte-doux); }

/* ═══════════════════════════ LA LUMIERE QUI SUIT LA MUSIQUE ═══════════════════
   Deux effets, et une seule idee : la lumiere n'est PAS decorative, elle est
   pilotee par le SON REEL. Deux variables CSS portent la mesure — `--niveau`
   (energie globale) et `--basses` (part des basses, celle qui fait pulser) —
   et le script les met a jour 60 fois par seconde depuis le spectre du morceau
   en cours. Silence = lumiere eteinte ; les coups de la chanson = pulsation.

   Pourquoi ainsi : une animation purement temporelle finit par mentir (elle
   pulse sur du silence, et jamais sur le rythme). Ici, si la musique s'arrete,
   la lumiere s'eteint d'elle-meme.

   `@property` est ce qui rend le contour capable de TOURNER : sans lui, un
   `conic-gradient(from var(--angle))` ne s'anime pas (l'angle est une chaine,
   pas un nombre). Les navigateurs qui ne le connaissent pas n'auront pas la
   rotation — la lueur, elle, marche partout. */
@property --angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }

:root {
  --niveau: 0;     /* 0 = silence */
  --basses: 0;
}

/* Contour lumineux qui tourne : un anneau en degrade conique, MASQUE pour ne
   garder que le liseré (sans le masque, le bouton serait recouvert). */
.rond, .pilule { position: relative; }
.rond::after, .pilule::after {
  content: ""; position: absolute; inset: -1.5px; border-radius: inherit;
  padding: 1.5px; pointer-events: none;
  background: conic-gradient(from var(--angle),
      transparent 0deg, var(--accent) 70deg, #ffffff 95deg, var(--accent-2) 125deg,
      transparent 195deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: tourner 4.5s linear infinite;
  opacity: calc(.16 + .84 * var(--niveau));
}
@keyframes tourner { to { --angle: 360deg; } }

/* Lueur qui respire, sur les boutons d'action. */
.rond-fort, .pilule-forte {
  box-shadow: 0 10px 24px rgba(176, 123, 255, .35),
              0 0 calc(6px + 28px * var(--niveau))
                  rgba(176, 123, 255, calc(.16 + .46 * var(--niveau)));
}

/* L'anneau de feu du bouton de LECTURE : un halo en couronne (transparent au
   centre, sans quoi il teinterait le bouton), dont l'echelle et l'eclat suivent
   les basses. `z-index: -1` le pose DERRIERE le bouton, donc autour. */
.rond-lecture { isolation: isolate; }
.rond-lecture::before {
  content: ""; position: absolute; inset: -9px; border-radius: 50%;
  pointer-events: none; z-index: -1; filter: blur(7px);
  background: radial-gradient(circle, transparent 40%, rgba(176, 123, 255, .75) 56%,
              rgba(255, 111, 174, .4) 74%, transparent 84%);
  transform: scale(calc(.84 + .48 * var(--basses)));
  opacity: calc(.1 + .72 * var(--basses));
  transition: transform .07s linear, opacity .1s linear;
}

/* La carte en cours de lecture s'allume avec la musique (elle est « branchée »). */
.carte.actif {
  border-color: rgba(176, 123, 255, calc(.34 + .46 * var(--niveau)));
  box-shadow: 0 0 calc(8px + 20px * var(--niveau))
              rgba(176, 123, 255, calc(.08 + .3 * var(--niveau)));
}

/* Repli honnete : si le navigateur refuse l'analyse du son (ou si le son ne
   passe pas par l'analyseur), la lumiere respire lentement au lieu de rester
   figee — et on le dit dans la console. */
html.sans-analyse .rond-lecture::before { animation: respirer 2.8s ease-in-out infinite; }
@keyframes respirer {
  0%, 100% { transform: scale(.86); opacity: .26; }
  50%      { transform: scale(1.08); opacity: .5; }
}

@media (prefers-reduced-motion: reduce) {
  .rond::after, .pilule::after { animation: none; }
  .rond-lecture::before { transition: none; }
  html.sans-analyse .rond-lecture::before { animation: none; }
}

/* ───────────────────────────── liste */
.liste { display: flex; flex-direction: column; gap: 10px; }
.carte {
  display: flex; align-items: center; gap: 12px; padding: 10px; border-radius: var(--rayon);
  border: 1px solid var(--bord); background: var(--verre); cursor: pointer;
  transition: transform .16s, background .16s, border-color .16s;
  min-width: 0;   /* sinon le titre en nowrap impose sa largeur mini (voir grille) */
}
.carte:active { transform: scale(.985); }
.carte.actif { border-color: rgba(176, 123, 255, .5); background: var(--verre-fort); }
.carte img { width: 56px; height: 56px; border-radius: 12px; object-fit: cover; flex: none;
  background: #241a3a; }
.carte-texte { flex: 1 1 auto; min-width: 0; }
.carte-texte strong { display: block; font-size: 15px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carte-texte span { display: block; color: var(--texte-doux); font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carte-droite { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.duree { color: var(--texte-doux); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.bouton-like {
  border: none; background: transparent; color: var(--texte-doux); cursor: pointer;
  font-size: 13px; padding: 2px 4px; border-radius: 10px; transition: transform .16s, color .16s;
}
.bouton-like.aime { color: var(--accent-2); }
.bouton-like:active { transform: scale(1.25); }

.etat { padding: 40px 10px; text-align: center; color: var(--texte-doux); }
.pied { color: var(--texte-doux); font-size: 12px; text-align: center; padding: 26px 0 10px; }

/* ───────────────────────────── mini lecteur */
.mini {
  position: fixed; left: 10px; right: 10px; bottom: 10px; z-index: 40;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 20px; border: 1px solid var(--bord);
  background: rgba(24, 16, 40, .82); backdrop-filter: blur(18px); box-shadow: var(--ombre);
}
.mini img { width: 44px; height: 44px; border-radius: 11px; object-fit: cover; flex: none; }
.mini-texte { flex: 1 1 auto; min-width: 0; }
.mini-texte strong { display: block; font-size: 14px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.mini-texte span { display: block; color: var(--texte-doux); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-barre, .vue-barre { display: none; }   /* remplaces par les curseurs ci-dessous */

/* ───────────────────────────── curseur de position (deplacable) */
/* Un `<input type=range>` plutot qu'une barre maison : sur telephone, le doigt
   n'a pas besoin de viser 2 px de haut, et le glissement est gere par le
   navigateur (inertie, precision, accessibilite). */
.curseur {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; margin: 0 auto; background: transparent;
  height: 28px;                      /* zone tactile confortable */
  max-width: 460px; cursor: pointer; touch-action: pan-y;
}
.curseur::-webkit-slider-runnable-track {
  height: 5px; border-radius: 5px; background: rgba(255, 255, 255, .16);
}
.curseur::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px; margin-top: -5.5px; border-radius: 50%;
  background: #fff; border: none; box-shadow: 0 2px 8px rgba(0, 0, 0, .5);
}
.curseur::-moz-range-track { height: 5px; border-radius: 5px; background: rgba(255, 255, 255, .16); }
.curseur::-moz-range-progress { height: 5px; border-radius: 5px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.curseur::-moz-range-thumb { width: 16px; height: 16px; border: none; border-radius: 50%;
  background: #fff; }
.curseur-mini {
  position: absolute; left: 10px; right: 10px; bottom: 0;
  height: 16px; max-width: none;
}
.curseur-mini::-webkit-slider-runnable-track { height: 3px; }
.curseur-mini::-webkit-slider-thumb { width: 12px; height: 12px; margin-top: -4.5px; }
.curseur-mini::-moz-range-track, .curseur-mini::-moz-range-progress { height: 3px; }
.curseur-mini::-moz-range-thumb { width: 12px; height: 12px; }

/* ═══════════════════════════ LECTEUR PLEIN ÉCRAN ═══════════════════════════
   La vidéo (qui porte les paroles synchronisées) remplit TOUT l'écran, et
   l'interface flotte par-dessus — comme sur YouTube Music. Plus de page qui
   défile : la scène occupe la place, les commandes sont posées dessus. */
.pilule.actif { border-color: rgba(176, 123, 255, .7); background: var(--verre-fort); }

.vue {
  position: fixed; inset: 0; z-index: 60; background: #05030a;
  overflow: hidden; animation: apparait .28s ease;
  /* ⚠️ Sans ceci, un swipe dans le lecteur plein ecran fait DEFILER LA PAGE
     derriere (mesure : 385 px pendant la lecture) : le lecteur du bas remonte et
     on croit voir un second lecteur. On coupe donc l'entrainement du defilement. */
  touch-action: none;
  overscroll-behavior: contain;
}
@keyframes apparait { from { opacity: 0; } to { opacity: 1; } }

/* `object-fit: contain` garde l'image ENTIÈRE : un cadrage plein écran rognerait
   les paroles incrustées, qui sont précisément ce qu'on vient voir. */
.scene {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; background: #05030a; display: block;
}

/* Les deux calques flottent au-dessus de la scène, sur un dégradé qui garantit
   la lisibilité quel que soit le fond de l'image. */
.calque { position: absolute; left: 0; right: 0; z-index: 3; }
.calque-haut {
  top: 0; display: flex; align-items: flex-start; gap: 12px;
  padding: calc(14px + env(safe-area-inset-top)) 14px 54px;
  background: linear-gradient(180deg, rgba(0,0,0,.78), rgba(0,0,0,.28) 60%, transparent);
}
.titre-scene { flex: 1 1 auto; min-width: 0; text-align: center; padding-top: 6px; }
.titre-scene strong { display: block; font-size: 15.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.titre-scene small { display: block; color: rgba(255, 255, 255, .66); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.calque-bas {
  bottom: 0; display: flex; flex-direction: column; gap: 6px;
  padding: 64px 16px calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(0deg, rgba(0,0,0,.9), rgba(0,0,0,.5) 55%, transparent);
}
/* ────────────────────── icônes SVG (jamais d'emoji) ────────────────────── */
.reserve { position: absolute; width: 0; height: 0; overflow: hidden; }
.icone { width: 20px; height: 20px; fill: currentColor; display: block; flex: none; }
.rond-mini { width: 38px; height: 38px; }
.rond-lecture { width: 48px; height: 48px; }
.rond-lecture .icone { width: 21px; height: 21px; }

/* Un bouton montre une icône OU l'autre selon son état : jamais les deux, et
   l'état est porté par une classe — donc l'affichage ne peut pas mentir. */
.icone-pause, .icone-piste, .icone-coeur-plein { display: none; }
.rond-lecture.en-lecture .icone-lecture { display: none; }
.rond-lecture.en-lecture .icone-pause { display: block; }
.rond.en-piste .icone-video { display: none; }
.rond.en-piste .icone-piste { display: block; }
.rond-like.aime .icone-coeur { display: none; }
.rond-like.aime .icone-coeur-plein { display: block; }

.rond-like {
  width: auto; min-width: 46px; padding: 0 11px; gap: 6px; border-radius: 999px;
}
.rond-like span { font-size: 13px; font-variant-numeric: tabular-nums; }

/* ─────────────────────── calques flottants + effacement ─────────────────── */
.calque {
  position: absolute; left: 0; right: 0; z-index: 3;
  /* L'interface s'efface toute seule quand on ne touche plus rien : en
     permanence, il ne reste que les paroles à l'écran. */
  transition: opacity .35s ease;
}
.vue.interface-cachee .calque { opacity: 0; pointer-events: none; }
.vue.interface-cachee { cursor: none; }

.calque-haut {
  top: 0; display: flex; align-items: flex-start; gap: 12px;
  padding: calc(12px + env(safe-area-inset-top)) 14px 46px;
  background: linear-gradient(180deg, rgba(0,0,0,.72), rgba(0,0,0,.22) 60%, transparent);
}
.titre-scene { flex: 1 1 auto; min-width: 0; text-align: center; padding-top: 4px; }
.titre-scene strong { display: block; font-size: 15px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.titre-scene small { display: block; color: rgba(255, 255, 255, .66); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Le bandeau du bas : DEUX lignes courtes, rien de plus. */
.calque-bas {
  bottom: 0; display: flex; flex-direction: column; gap: 1px;
  padding: 22px 14px calc(6px + env(safe-area-inset-bottom));
  background: linear-gradient(0deg, rgba(0,0,0,.88), rgba(0,0,0,.42) 55%, transparent);
}
.barre-position { display: flex; align-items: center; gap: 10px;
  width: 100%; max-width: 560px; margin: 0 auto; }
.barre-position .curseur { flex: 1 1 auto; max-width: none; height: 22px; }
.barre-position span { flex: none; min-width: 33px; font-size: 11px;
  color: rgba(255, 255, 255, .72); font-variant-numeric: tabular-nums; }
.barre-position span:last-child { text-align: right; }
.barre-actions { display: flex; align-items: center; gap: 8px;
  width: 100%; max-width: 560px; margin: 0 auto; }
.barre-actions .ecart { flex: 1 1 auto; }
.vue .rond { background: rgba(22, 15, 36, .55); backdrop-filter: blur(10px);
  border-color: rgba(255, 255, 255, .12); }
.vue .curseur { max-width: 560px; }

.pilule {
  padding: 10px 16px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .18);
  background: rgba(20, 14, 34, .55); backdrop-filter: blur(10px);
  color: var(--texte); font-size: 13.5px; cursor: pointer;
}
.pilule:active { transform: scale(.96); }
.pilule-forte { background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border: none; color: #fff; }

/* Panneau des paroles (notre texte), par-dessus la scène */
.panneau {
  position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column;
  background: rgba(8, 5, 16, .96); backdrop-filter: blur(20px);
  animation: monter .26s ease;
  /* Le lecteur a coupe le defilement (touch-action: none) ; les paroles, elles,
     DOIVENT pouvoir se faire défiler — on le rend explicite ici. */
  touch-action: pan-y;
  overscroll-behavior: contain;
}
@keyframes monter { from { transform: translateY(6%); opacity: .4; } to { transform: none; opacity: 1; } }
.panneau-tete { display: flex; align-items: center; justify-content: space-between;
  padding: calc(14px + env(safe-area-inset-top)) 16px 8px; }
.paroles { flex: 1 1 auto; overflow-y: auto; white-space: pre-wrap; text-align: left;
  padding: 4px 22px calc(30px + env(safe-area-inset-bottom));
  font-family: "Cormorant", "Iowan Old Style", Georgia, serif;
  font-size: 19.5px; line-height: 1.62; letter-spacing: .004em; color: #e6e1f5;
  max-width: 620px; margin: 0 auto; width: 100%; }
/* Paroles ouvertes : la barre de position et le bouton de lecture RESTENT
   visibles, posés AU-DESSUS du panneau (z-index 7 contre 6). Sans cela, le
   panneau plein écran les recouvrait et on lisait les paroles sans pouvoir
   mettre en pause. Les paroles reçoivent la place correspondante en bas, pour
   que la dernière ligne ne finisse pas cachée sous la barre. */
.vue.paroles-ouvertes .calque-bas { z-index: 7;
  background: linear-gradient(0deg, rgba(8, 5, 16, .98), rgba(8, 5, 16, .88) 62%, transparent); }
.vue.paroles-ouvertes .paroles { padding-bottom: calc(132px + env(safe-area-inset-bottom)); }
/* Les titres de section ([Verse], [Chorus]) portent la couleur du site qui
   défile — c'est la touche de luxe, réservée aux lignes COURTES : sur un texte
   long, un dégradé animé fatigue la lecture. */
.paroles b {
  display: block; font-family: "Cinzel", "Iowan Old Style", Georgia, serif;
  font-weight: 700; font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
  margin: 18px 0 6px; color: var(--accent);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .paroles b {
    background-image: linear-gradient(100deg, var(--accent) 0%, #ffffff 12%,
        var(--accent-2) 26%, #7fe3f5 44%, var(--accent) 62%, var(--accent-2) 82%,
        var(--accent) 100%);
    background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text; color: transparent;
    animation: couleur-vive 7s linear infinite;
  }
}
/* Apparition ligne par ligne a l'ouverture : l'effet ne prétend PAS suivre la
   musique (Suno ne livre aucun temps) — c'est une mise en page qui se dépose. */
.paroles .ligne { display: block; animation: deposer .45s ease both; }
@keyframes deposer {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
/* Karaoké : quand on a les minutes (lues dans la vidéo Suno), la ligne EN COURS
   prend la couleur du site qui défile et les lignes passées s'estompent — comme
   une appli de karaoké. Les autres lignes gardent leur teinte normale. Pas de
   changement de taille : la ligne qui grossit ferait sauter le défilement. */
.paroles .ligne.passee { color: rgba(230, 225, 245, .42); transition: color .3s ease; }
.paroles .ligne.en-cours { color: var(--texte); font-weight: 600; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .paroles .ligne.en-cours {
    background-image: linear-gradient(100deg, var(--accent) 0%, #ffffff 16%,
        var(--accent-2) 34%, #7fe3f5 54%, var(--accent) 76%, var(--accent-2) 100%);
    background-size: 220% 100%;
    -webkit-background-clip: text; background-clip: text; color: transparent;
    animation: couleur-vive 6s linear infinite;
  }
}
@media (prefers-reduced-motion: reduce) {
  .paroles .ligne { animation: none; }
  .paroles b { animation: none; }
  .paroles .ligne.en-cours { animation: none; }
}

/* ───────────────────────────── feuille des formats */
.feuille { position: fixed; inset: 0; z-index: 80; display: grid; align-items: end;
  background: rgba(6, 4, 12, .6); backdrop-filter: blur(3px); }
.feuille-boite {
  background: #150e26; border-top-left-radius: 24px; border-top-right-radius: 24px;
  padding: 22px 20px 26px; border-top: 1px solid var(--bord);
  animation: glisser .26s ease; max-height: 86vh; overflow-y: auto;
}
@keyframes glisser { from { transform: translateY(30%); } to { transform: none; } }
.feuille h3 { margin: 0 0 4px; font-size: 18px; }
.feuille-note { color: var(--texte-doux); font-size: 12.5px; margin: 0 0 16px; }
.formats { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.format {
  display: flex; align-items: center; gap: 12px; padding: 14px; border-radius: 16px;
  border: 1px solid var(--bord); background: var(--verre); text-decoration: none; color: var(--texte);
}
.format:active { transform: scale(.985); }
.format-icone { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center;
  background: linear-gradient(135deg, rgba(176, 123, 255, .35), rgba(255, 111, 174, .3)); font-size: 15px; }
.format-texte { flex: 1 1 auto; }
.format-texte strong { display: block; font-size: 14.5px; }
.format-texte span { display: block; color: var(--texte-doux); font-size: 12px; }
.etiquette { font-size: 10.5px; padding: 3px 8px; border-radius: 999px; border: 1px solid var(--bord);
  color: var(--texte-doux); flex: none; }
.etiquette-perte { border-color: rgba(255, 111, 174, .4); color: #ffb3d2; }

/* ───────────────────────────── ordinateur */
@media (min-width: 900px) {
  main { max-width: 880px; margin: 0 auto; }
  .entete { max-width: 880px; margin: 0 auto; }
  /* Le profil suit la MEME colonne que le reste : sinon la banniere s'etale sur
     toute la largeur pendant que la liste reste centree sur 880 px. */
  .profil { max-width: 880px; margin: 0 auto; }
  /* ⚠️ `1fr` vaut `minmax(auto, 1fr)` : la taille MINI d'une piste est alors la
     largeur MINIMALE du contenu — et un titre en `white-space: nowrap` la fait
     exploser (mesure : des cartes de 5101 px, une page large de 10905 px).
     `minmax(0, 1fr)` autorise la piste a se reduire, et c'est l'ellipse du
     titre qui reprend la main. */
  .liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .mini { max-width: 620px; margin: 0 auto; left: 0; right: 0; }
}
