/* =============================================================================
   SOUNDFOLIO — Page d'accueil (playlist)
   -----------------------------------------------------------------------------
   Sommaire
     1. Liste
     2. Piste : ligne de résumé
     3. Bouton lecture / arrêt
     4. Titre, rôle et glitch
     5. Durée et égaliseur
     6. Chevron
     7. Panneau déplié
     8. Galerie de médias
     9. Visionneuse (lightbox)
   -----------------------------------------------------------------------------
   Les variables --eq-* sont posées par le script à partir du génome de
   chaque expérience : chaque égaliseur a donc son propre rythme.
   ========================================================================== */


/* =============================================================================
   1. LISTE
   ========================================================================== */

.playlist {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-4) 0;
}

/* Playlist sans aucune expérience publiée */
.playlist-vide {
  padding: var(--sp-4);
  color: var(--text-secondary);
}

/* Introduction facultative, en tête de playlist.
   Un filet ambré la rattache à la charte sans l'alourdir, et l'écart
   avec la première piste reprend celui qui sépare deux pistes. */
.playlist-intro {
  margin-bottom: var(--sp-2);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid rgba(232, 163, 60, .18);
  font-size: 13px;
  line-height: 1.6;
}
.playlist-intro > *:last-child { margin-bottom: 0; }


/* =============================================================================
   2. PISTE : LIGNE DE RÉSUMÉ
   ========================================================================== */

.track {
  background: var(--bordeaux-light);
  border-radius: var(--radius-lg);
  border-left: 2px solid transparent;
  transition:
    border-color var(--dur) var(--ease),
    box-shadow var(--dur-fast) var(--ease);
}
.track.is-playing { border-left-color: var(--amber); }

/* Ombre au survol du résumé uniquement, et jamais sur le bouton de lecture
   d'une piste déjà ouverte — cohérent avec le comportement du chevron. */
.track:has(> summary:hover) { box-shadow: 3px 3px 0 0 rgba(232, 163, 60, .28); }
.track[open]:has(> summary .play-btn:hover) { box-shadow: none; }

.track > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  list-style: none;
}
.track > summary::-webkit-details-marker { display: none; }
.track > summary::marker { content: ""; }

.track-columns {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-3);
  flex: 1;
  min-width: 0;
}
.track-info { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.track-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); flex-shrink: 0; }


/* =============================================================================
   3. BOUTON LECTURE / ARRÊT
   Le morphing repose sur .icon-btn (voir site.css) : le cercle se remplit,
   le triangle s'efface au profit du carré.
   ========================================================================== */

.play-btn { position: relative; width: 34px; height: 34px; }

.play-btn .icon-play,
.play-btn .icon-stop {
  position: absolute;
  z-index: 1;
  top: 50%;
  transform: translate(-50%, -50%);
  transition:
    opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.play-btn .icon-play {
  left: calc(50% + 1px);
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 6px 0 6px 9px;
  border-color: transparent transparent transparent var(--cream);
}
.play-btn .icon-stop {
  left: 50%;
  width: 10px;
  height: 10px;
  background: var(--bordeaux);
  border-radius: 2px;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0);
}

.track.is-playing .play-btn { border-color: var(--amber); }
.track.is-playing .play-btn::before { clip-path: circle(72% at 50% 50%); }
.track.is-playing .icon-play { opacity: 0; transform: translate(-50%, -50%) scale(.5); }
.track.is-playing .icon-stop { opacity: 1; transform: translate(-50%, -50%) scale(1); }

.track:not(.is-playing) .play-btn:hover {
  border-color: var(--cream);
  transform: scale(1.06);
}
.track.is-playing .play-btn:hover {
  transform: scale(1.06);
  box-shadow: 0 0 0 4px rgba(232, 163, 60, .18);
}


/* =============================================================================
   4. TITRE, RÔLE ET GLITCH
   ========================================================================== */

/* h2/h3 : balisage sémantique pour le référencement, apparence maîtrisée ici */
.track-title {
  margin: 0;
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 15px;
  line-height: 20px;
  letter-spacing: -0.01em;
}
.track-client-type {
  font-family: var(--font-body);
  font-weight: 100;
  font-style: italic;
  line-height: 1.15;
  letter-spacing: 0;
  color: var(--text-secondary);
}

.track-role {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.track-role .hash { font-weight: 100; }

/* Aberration chromatique brève au démarrage d'une piste */
@keyframes glitch-lock {
  0%   { text-shadow: none; transform: translate(0, 0); }
  15%  { text-shadow: -2px 0 var(--amber), 2px 0 var(--glitch-cyan); transform: translate(-1px, 0); }
  30%  { text-shadow: 2px 0 var(--amber), -2px 0 var(--glitch-cyan); transform: translate(1px, 0); }
  45%  { text-shadow: -1px 0 var(--amber), 1px 0 var(--glitch-cyan); transform: translate(0, 0); }
  60%  { text-shadow: 1px 0 var(--amber), -1px 0 var(--glitch-cyan); transform: translate(-1px, 0); }
  100% { text-shadow: none; transform: translate(0, 0); }
}
.track-client-name.is-locking { animation: glitch-lock .26s steps(1, end) 1; }


/* =============================================================================
   5. DURÉE ET ÉGALISEUR
   La durée cède la place aux barres pendant la lecture.
   ========================================================================== */

.track-meta { position: relative; width: 44px; height: 20px; }

.duration,
.eq {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: flex-end;
  transition: opacity .25s var(--ease);
}
.duration {
  align-items: center;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--amber);
}
.eq { align-items: flex-end; gap: 3px; opacity: 0; }

.eq span {
  width: 3px;
  background: var(--amber);
  border-radius: 1px;
  animation-name: eq-bounce;
  animation-duration: var(--eq-duration, .9s);
  animation-timing-function: var(--eq-easing, ease-in-out);
  animation-iteration-count: infinite;
  animation-play-state: paused;
}
.eq span:nth-child(1) { height: 8px;  animation-delay: 0s; }
.eq span:nth-child(2) { height: 14px; animation-delay: calc(var(--eq-duration, .9s) * var(--eq-stagger, .16)); }
.eq span:nth-child(3) { height: 10px; animation-delay: calc(var(--eq-duration, .9s) * var(--eq-stagger, .16) * 2); }

@keyframes eq-bounce {
  0%, 100% { transform: scaleY(var(--eq-amp-min, .3)); }
  50%      { transform: scaleY(1); }
}

.track.is-playing .duration { opacity: 0; }
.track.is-playing .eq { opacity: 1; }
.track.is-playing .eq span { animation-play-state: running; }


/* =============================================================================
   6. CHEVRON
   Signale qu'une piste est dépliable ; pivote une fois ouverte.
   ========================================================================== */

.chevron {
  width: 14px;
  height: 14px;
  color: var(--text-secondary);
  transition: transform var(--dur) var(--ease);
}
.track[open] .chevron { transform: rotate(180deg); }

@keyframes chevron-hint {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}
@keyframes chevron-hint-open {
  0%, 100% { transform: rotate(180deg) translateY(0); }
  50%      { transform: rotate(180deg) translateY(4px); }
}

.track:not([open]) > summary:hover .chevron { animation: chevron-hint 1s ease-in-out infinite; }
.track[open] > summary:hover:not(:has(.play-btn:hover)) .chevron { animation: chevron-hint-open 1s ease-in-out infinite; }


/* =============================================================================
   7. PANNEAU DÉPLIÉ
   L'ouverture est animée par le script (Web Animations API) : le CSS ne
   fixe que l'état fermé.
   ========================================================================== */

.track-body {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  padding: 0 var(--sp-4) var(--sp-4) 64px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}
.track-body p { margin: 0 0 .6em; }
.track-body p:last-child { margin-bottom: 0; }
.track-body strong { color: var(--cream); font-weight: 700; }
.track-body em { font-style: italic; }

.track-body a {
  color: var(--amber);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.track-body a:hover,
.track-body a:focus-visible { color: var(--cream); }

/* Lecteur intégré en attente de chargement.
   Le cadre réserve la place dès le départ : quand le lecteur arrive, il ne
   pousse pas le texte qui le suit. */
.embed-defer {
  position: relative;
  aspect-ratio: 16 / 9;
  margin: var(--sp-4) 0;
  background: var(--bordeaux);
  border-radius: var(--radius);
  overflow: hidden;
}
.embed-defer iframe {
  width: 100%;
  height: 100%;
  border: 0;
  opacity: 0;
  transition: opacity .25s var(--ease);
}
.embed-defer.is-loaded iframe { opacity: 1; }

/* Période // durée réelle */
.track-meta-line {
  margin: 0 0 var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid rgba(232, 163, 60, .18);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  color: var(--text-secondary);
}


/* =============================================================================
   8. GALERIE DE MÉDIAS
   ========================================================================== */

.track-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}

.track-media {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  padding: 0;
  background: var(--bordeaux);
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-secondary);
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.track-media:hover {
  border-color: var(--amber);
  color: var(--amber);
  transform: scale(1.05);
}
.track-media svg { width: 20px; height: 20px; }


/* =============================================================================
   9. VISIONNEUSE
   Plein écran : le média occupe tout l'espace, les commandes flottent.
   ========================================================================== */

.lightbox {
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--cream);
  overflow: hidden;
}
.lightbox:focus { outline: none; }
.lightbox::backdrop { background: rgba(42, 7, 16, .94); }

.lightbox-inner {
  display: grid;
  grid-template-rows: 1fr auto;
  height: 100%;
  padding: 64px var(--sp-5) var(--sp-5);
}

.lightbox-close {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-5);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: var(--border-width) solid var(--text-secondary);
  border-radius: 50%;
  background: transparent;
  color: var(--cream);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}
.lightbox-close:hover { border-color: var(--amber); color: var(--amber); }

.lightbox-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  /* Le glissement horizontal sert à changer de média : on empêche le
     navigateur de l'interpréter comme un geste de navigation arrière. */
  touch-action: pan-y;
}

/* Flèches superposées aux bords : elles ne réduisent pas la place du média. */
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: var(--border-width) solid var(--text-secondary);
  border-radius: 50%;
  background: rgba(42, 7, 16, .55);
  backdrop-filter: blur(4px);
  color: var(--cream);
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    opacity var(--dur-fast) var(--ease);
}
.lightbox-prev { left: 0; }
.lightbox-next { right: 0; }
.lightbox-nav:hover:not(:disabled) { border-color: var(--amber); color: var(--amber); }
.lightbox-nav:disabled { opacity: 0; pointer-events: none; }
.lightbox-nav svg { width: 20px; height: 20px; }

/* Le média impose sa propre forme : aucun rapport figé. */
.lightbox-visual {
  position: relative;   /* repère pour le loader, placé hors du flux */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  max-width: 1400px;
  border-radius: var(--radius);
  color: var(--amber);
  overflow: hidden;
}
.lightbox-visual :is(img, video) {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius);
}
.lightbox-visual iframe {
  width: min(100%, 1280px);
  max-height: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--radius);
}
.lightbox-visual audio { width: min(100%, 560px); }
.lightbox-visual > svg { width: 64px; height: 64px; opacity: .5; }

/* --- Indicateur de chargement ---
   Trois barres qui pulsent, dans l'esprit de l'égaliseur des pistes :
   l'attente reprend ainsi le vocabulaire visuel du site plutôt qu'un
   sablier générique. Le média n'apparaît qu'une fois prêt, ce qui évite
   de le voir se dessiner par bandes. */
/* Hors du flux : sans cela, le loader et le média occupent la même ligne,
   et le loader se décale vers la gauche à mesure que le média prend sa
   place — juste avant de disparaître. */
.lightbox-loader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 28px;
}
.lightbox-loader span {
  width: 4px;
  height: 100%;
  background: var(--amber);
  border-radius: 2px;
  transform-origin: bottom;
  animation: loader-pulse 1s ease-in-out infinite;
}
.lightbox-loader span:nth-child(2) { animation-delay: .15s; }
.lightbox-loader span:nth-child(3) { animation-delay: .3s; }

@keyframes loader-pulse {
  0%, 100% { transform: scaleY(.25); opacity: .45; }
  50%      { transform: scaleY(1); opacity: 1; }
}

/* Le média reste invisible tant qu'il n'est pas chargé, puis se révèle. */
.lightbox-visual :is(img, video).is-loading { opacity: 0; }
.lightbox-visual :is(img, video) {
  opacity: 1;
  transition: opacity .25s var(--ease);
}

.lightbox-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding-top: var(--sp-4);
}
.lightbox-label { margin: 0; font-size: 14px; color: var(--cream); }
.lightbox-counter {
  flex-shrink: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}


/* =============================================================================
   ADAPTATIONS
   ========================================================================== */

/* Appareils sans survol : le chevron s'anime en continu, faute de survol
   pour le déclencher, et aucune surbrillance ne reste « collée ». */
@media (hover: none) {
  .track:not([open]) .chevron { animation: chevron-hint 1s ease-in-out infinite; }
  .track[open] .chevron { animation: chevron-hint-open 1s ease-in-out infinite; }

  .track:has(> summary:hover),
  .track[open] { box-shadow: none; }
  .track:active { box-shadow: 3px 3px 0 0 rgba(232, 163, 60, .28); }
}

@media (max-width: 600px) {
  .playlist { overflow-y: visible; }

  /* Aucun texte tronqué : le rôle passe à la ligne */
  .track-role { white-space: normal; overflow: visible; text-overflow: clip; }
  .track-title { white-space: normal; }

  /* Sur une largeur réduite, chacune des quatre informations occupe sa
     propre ligne — client, type de structure, rôle, type de contrat — avec
     le même écart entre elles que celui séparant les deux titres
     (var(--sp-1)), pour un rythme régulier de haut en bas. */
  .track-client-type,
  .track-contract {
    display: block;
    margin-top: var(--sp-1);
  }
  .track-columns { align-items: flex-start; }

  .lightbox-inner { padding: 56px var(--sp-3) var(--sp-4); }
  .lightbox-close { top: var(--sp-3); right: var(--sp-3); width: 36px; height: 36px; }
  .lightbox-nav { width: 40px; height: 40px; }
  .lightbox-nav svg { width: 17px; height: 17px; }
  .lightbox-label { font-size: 13px; }
}
