/* =========================================================
   RÈGLES NON NÉGOCIABLES — valables pour tout le fichier.
   Toute nouvelle règle doit s'y conformer, à chaque phase.

   1. LUMIÈRE : une source unique, chaude, venant du haut-gauche
      à ~35°. Toute surface (carton, vinyle, tranches) est éclairée
      en haut-gauche et assombrie en bas-droite. L'ombre portée de
      la scène tombe donc vers le bas-droite. Ne jamais introduire
      une deuxième source ni une lumière plate/frontale.

   2. ACCENT (--accent) : filets, liserés, texte, et l'étiquette
      centrale du disque — son seul aplat autorisé. Partout ailleurs,
      jamais en fond de bloc ni en arrière-plan de bouton (le bouton
      de thème n'a pas de fond plein) : c'est un signal, pas une
      couleur de remplissage.

   3. OBJETS PHYSIQUES : la pochette (--ink) et sa cover art, les
      faces internes du gatefold (photo d'arrière-plan imprimée) et
      la pochette intérieure du disque (--sleeve) sont des objets
      réels, imprimés une fois pour toutes — leurs couleurs/images ne
      changent PAS avec le thème du site. Seuls les jetons sémantiques
      (--bg, --bg-deep, --text, --text-muted, --rule) suivent le
      thème : la pièce, le contenu sous la pochette, le hint, les
      ombres de la scène.
   ========================================================= */

/* =========================================================
   0. POLICES — deux familles, variables/statiques, locales
      titres  : Fraunces (serif de labeur, chaleureuse en grand corps)
      labels  : Archivo Narrow (condensée, UI/texte courant)
      woff2 latin uniquement, aucune requête externe.
   ========================================================= */
@font-face{
  font-family: 'Archivo Narrow';
  src: url('../fonts/archivo-narrow-variable.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face{
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* =========================================================
   1. JETONS — change une valeur ici, tout le site suit
   ========================================================= */
:root{
  /* --- objets physiques : fixes, ne suivent jamais le thème --- */
  --ink:         #0B0B0C;  /* encre d'impression de la pochette */
  --ink-edge:    #232325;  /* tranche/dos de la pochette : un peu plus clair que --ink, jamais crème */
  --card:        #F1EADB;  /* crème papier : texte/filets clairs sur les faces internes (photo sombre) */
  --sleeve:      #FBF7ED;  /* pochette intérieure, papier fin */
  --vinyl:       #15161a;
  --vinyl-deep:  #0a0a0c;
  --vinyl-groove: rgba(255,255,255,.05);
  --accent:      #FFB020;  /* remplace le laiton (filets/texte) et le rouge (étiquette) */

  /* --- jetons sémantiques : suivent le thème, cf. règle 3 ---
     valeurs par défaut = thème sombre ; surchargées plus bas
     (media prefers-color-scheme + [data-theme] forcé par le bouton) */
  --bg:          #1E2024;  /* la pièce, derrière la pochette */
  --bg-deep:     #0F1317;
  --text:        #F1EADB;
  --text-muted:  color-mix(in srgb, var(--text) 70%, var(--bg));
  --rule:        color-mix(in srgb, var(--text) 14%, transparent);
  --accent-text: var(--accent); /* accent utilisé comme texte : lisible tel quel en sombre */
  color-scheme: dark light;

  --font-titres: 'Fraunces', Georgia, 'Iowan Old Style', 'Times New Roman', serif;
  --font-labels: 'Archivo Narrow', 'Arial Narrow', Arial, sans-serif;

  --panel: 380px;          /* largeur/hauteur d'un volet — carré strict, pochette 12" */
  --thick: 6px;             /* épaisseur de carton (~4-5mm à l'échelle du panel) */
  --open: 0;                /* approche/redressement 0-15%, piloté par le JS */
  --flip: 0;                /* pivot du volet 15-70%, piloté par le JS */
  --disc: 0;                /* sortie du disque 60-85%, piloté par le JS */
  --reveal: 0;               /* recul caméra 85-100%, piloté par le JS */
  --p: 0;                    /* progression brute 0-100%, non répartie */
  --mx: 0;                  /* parallaxe souris, -1..1 (piloté par le JS) */
  --my: 0;
}

/* thème clair : suit le système par défaut (CSS pur), sauf si l'utilisateur
   a forcé --data-theme="dark" via le bouton (cf. js/main.js) */
@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]){
    --bg: #E8E4DB;
    --bg-deep: #DFDBD3;
    --text: #1E2024;
    --accent-text: #7C5000; /* --accent échoue en AA sur fond clair (1.44:1) : variante assombrie, ~5:1 */
    color-scheme: light dark;
  }
}
/* thème forcé par le bouton (écrase le système, cf. règle "auto/clair/sombre") */
:root[data-theme="light"]{
  --bg: #E8E4DB;
  --bg-deep: #DFDBD3;
  --text: #1E2024;
  --accent-text: #7C5000;
  color-scheme: light;
}
:root[data-theme="dark"]{
  --bg: #1E2024;
  --bg-deep: #0F1317;
  --text: #F1EADB;
  --accent-text: var(--accent);
  color-scheme: dark;
}

*, *::before, *::after{ box-sizing: border-box; }
html{
  scroll-behavior: smooth;
  scrollbar-width: none;     /* Firefox */
  -ms-overflow-style: none;  /* vieux Edge */
}
html::-webkit-scrollbar{ display: none; } /* Chrome/Safari/Edge */
body{
  margin:0; overflow-x:hidden;
  background: radial-gradient(120% 90% at 50% 0%,
    color-mix(in srgb, var(--bg) 85%, white) 0%, var(--bg) 45%, var(--bg-deep) 100%);
  color: var(--text);
  font-family: var(--font-labels);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}
a{ color: inherit; }
:focus-visible{ outline: 2px solid var(--accent-text); outline-offset: 4px; border-radius: 1px; }
/* titre de page réel pour l'accessibilité/SEO (un seul h1) : le recto de la
   pochette est maintenant une photo imprimée qui porte déjà ce texte
   visuellement (cf. .face--cover) — celui-ci ne duplique rien à l'écran. */
.sr-only{
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* =========================================================
   1bis. BOUTON DE THÈME — coin haut-droit, hors de la scène 3D
   (une position:fixed à l'intérieur d'un ancêtre transformé/perspective
   se recale sur cet ancêtre ; le bouton doit donc rester un enfant
   direct de body, jamais dans .stage/.scene/.gatefold)
   ========================================================= */
.theme-toggle{
  position: fixed; top: 18px; right: 18px; z-index: 50;
  font-family: var(--font-labels); font-size: 12px; letter-spacing: .04em;
  color: var(--text);
  background: color-mix(in srgb, var(--bg-deep) 70%, transparent);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 8px 14px;
  cursor: pointer;
  backdrop-filter: blur(6px);
}
.theme-toggle:hover{ border-color: color-mix(in srgb, var(--accent) 50%, transparent); }

/* =========================================================
   2. LA SCÈNE — pochette collante pendant qu'on défile
   ========================================================= */
.intro{ height: 420vh; }                 /* longueur du défilement d'ouverture */
.stage{
  position: sticky; top: 0;
  height: 100svh;
  display: grid; place-items: center;
  perspective: 1700px;
  perspective-origin: 50% 45%;
  overflow: hidden;
}

.scene{
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
  /* parallaxe légère, amortie côté JS avant d'arriver ici ;
     85-100% : léger recul de caméra vers le contenu */
  transform:
    rotateY(calc(var(--mx) * 4deg))
    rotateX(calc(var(--my) * -3deg))
    scale(calc(1 - var(--reveal) * .1))
    translateY(calc(var(--reveal) * -30px));
  /* entrée au chargement, une fois : la pochette monte du bas avec un
     léger tangage qui se remet à plat. transform+opacity uniquement,
     sans fill:forwards/both (cf. plus bas pourquoi). Animée ici sur
     .scene et non sur .gatefold : .gatefold établit le contexte 3D
     (preserve-3d) dont dépendent .disc-slot et .face--cover pour se
     départager correctement (le disque doit rester derrière la
     pochette fermée) — lui appliquer une animation, même sans fill,
     l'a fait passer sur son propre calque de composition PENDANT
     toute sa durée actives, cassant ce tri (.disc-slot peignait par-
     dessus .face--cover). Animer l'ancêtre .scene à la place laisse
     .gatefold hors de l'animation, sans casser rien. */
  animation: scene-rise 650ms cubic-bezier(.16,1,.3,1);
}
@keyframes scene-rise{
  from{
    opacity: 0;
    transform:
      rotateY(calc(var(--mx) * 4deg))
      rotateX(calc(var(--my) * -3deg + 16deg))
      scale(calc(1 - var(--reveal) * .1))
      translateY(calc(var(--reveal) * -30px + 48px));
  }
  to{
    opacity: 1;
    transform:
      rotateY(calc(var(--mx) * 4deg))
      rotateX(calc(var(--my) * -3deg))
      scale(calc(1 - var(--reveal) * .1))
      translateY(calc(var(--reveal) * -30px));
  }
}

/* fondu qui masque la scène vers le contenu en 85-100%, pour éviter une coupe nette */
.stage__fade{
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 55%, var(--bg-deep) 100%);
  opacity: var(--reveal);
  pointer-events: none;
}

.gatefold{
  position: relative;
  width: calc(var(--panel) * 2);
  height: var(--panel);
  max-width: 92vw;
  transform-style: preserve-3d;
  will-change: transform;
  /* fermée, on décale à gauche pour que le volet droit (seul visible tant
     que le volet n'est pas ouvert) reste centré à l'écran, malgré la boîte
     .gatefold deux fois plus large que lui ; état fermé frontal (aucune
     inclinaison statique — seule la parallaxe souris, sur .scene, incline
     légèrement la scène) ;
     0-15% : redressement + approche (voir js/main.js — progress()) */
  transform:
    translateX(calc((1 - var(--open)) * -25%))
    translateZ(calc(var(--open) * 60px))
    rotateX(calc(var(--open) * 4deg));
}

/* --- ombre portée dynamique : s'allonge et se déforme à l'ouverture,
       jamais une ombre CSS statique. Toujours sombre (une ombre reste
       plus foncée que le sol qui la porte, quel que soit le thème). --- */
.shadow{
  position: absolute; left: 50%; top: 100%;
  width: calc(var(--panel) * 1.7); height: calc(var(--panel) * .46);
  margin-top: calc(var(--panel) * -.1);
  background: radial-gradient(ellipse at 50% 50%,
    rgba(2,2,3,.55) 0%, rgba(2,2,3,.32) 38%, rgba(2,2,3,0) 72%);
  transform-origin: 50% 20%;
  transform:
    translateX(calc(-50% + var(--open) * 6%))
    translateY(calc(var(--open) * 14px))
    scaleX(calc(1 + var(--open) * .55))
    skewX(calc(var(--open) * -10deg));
  will-change: transform;
  pointer-events: none;
}

/* --- volet intérieur droit : ce qu'on découvre en ouvrant --- */
.page{
  position: absolute; inset: 0 0 0 50%;
  /* moitié droite du panorama intérieur (cf. .face--liner pour la moitié
     gauche) : même image, même background-size (2 panels de large,
     1 panel de haut), position "right" ici pour un raccord exact au pli.
     Overlay noir à .86 (pas juste "léger") : la zone la plus claire de
     la photo (le halo en haut-gauche) tombe pile sous "Notes de
     pochette" côté .face--liner — mesuré par échantillonnage réel des
     pixels (canvas) sous le texte, un overlay à .72 n'y laissait que
     2.71:1 avec --card, .86 remonte à 4.7:1 (AA) même sur ce pixel le
     plus clair, pas seulement en moyenne. */
  background:
    linear-gradient(rgba(0,0,0,.86), rgba(0,0,0,.86)),
    url('../assets/img/Gemini_Generated_Image_vc65l5vc65l5vc65.jpg') right top / calc(var(--panel) * 2) var(--panel) no-repeat;
  color: var(--card);
  padding: 30px 32px;
  box-shadow: inset 6px 0 18px rgba(0,0,0,.14);
  overflow: hidden;
  container-type: inline-size; /* cf. .face : les titres internes suivent --panel, pas le viewport */
  /* le volet droit est maintenant une vraie pochette (sleeve) : sans
     transform, .page reste au z implicite (0) de .gatefold — déjà
     devant .disc-slot (translateZ(-3px), cf. plus bas) et déjà derrière
     .face--cover (translateZ ~5px net). Donner à .page un translateZ
     explicite, même positif et proche de 0, cassait le tri de
     profondeur 3D face à .face--cover (le contenu de .page se mettait
     à peindre par-dessus la pochette fermée) — probablement lié au
     fond photo (gros bitmap) plutôt qu'un dégradé ; vérifié en
     isolant : transform:none suffit, aucun besoin d'un Z explicite ici. */
}


/* --- le volet qui pivote : recto = la pochette, verso = la page de gauche ---
       axe de pivot sur le pli, pas sur le bord arbitraire */
.flipper{
  position: absolute; inset: 0 0 0 50%;
  transform-origin: left center;
  transform-style: preserve-3d;
  will-change: transform;
  /* 15-70% : pivot du volet, easing non-linéaire calculé en JS (voir progress()) */
  transform: translateZ(2px) rotateY(calc(var(--flip) * -180deg));
}
.face{
  position: absolute; inset: 0;
  backface-visibility: hidden;
  overflow: hidden;
  /* le texte de la pochette (titre, label, pied) se dimensionne en cqw,
     relatif à cette boîte (~--panel), jamais au viewport : sinon un
     clamp() en vw sature à son maximum dès que la fenêtre s'élargit,
     indépendamment de la taille réelle — encore fixe — du volet. */
  container-type: inline-size;
}
.face--cover{
  transform: translateZ(calc(var(--thick) / 2));
  /* cover art imprimée une fois pour toutes (objet physique, cf. règle 3) :
     photo plein cadre, le hype sticker est déjà dedans (coin haut-droit) */
  background: var(--ink) url('../assets/img/Gemini_Generated_Image_r9l6g0r9l6g0r9l6.jpg') center / cover no-repeat;
  box-shadow: 0 40px 70px rgba(0,0,0,.6), 0 2px 0 rgba(255,255,255,.06) inset;
}
.face--liner{
  transform: rotateY(180deg) translateZ(calc(var(--thick) / 2));
  /* moitié gauche du même panorama, cf. .page */
  background:
    linear-gradient(rgba(0,0,0,.86), rgba(0,0,0,.86)),
    url('../assets/img/Gemini_Generated_Image_vc65l5vc65l5vc65.jpg') left top / calc(var(--panel) * 2) var(--panel) no-repeat;
  color: var(--card);
  padding: 30px 32px;
  box-shadow: inset -6px 0 18px rgba(0,0,0,.14);
}

/* =========================================================
   2bis. ÉPAISSEUR DE CARTON — tranches visibles en 3D
   Technique : chaque tranche est une bande hinge-ée sur la ligne
   de jonction entre recto et verso, puis rabattue de 90° pour
   combler l'épaisseur --thick entre les deux faces.
   ========================================================= */
.edges{
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  pointer-events: none;
}
.edge{
  position: absolute;
  background: var(--ink-edge); /* fine tranche unie, couleur de la pochette — plus de bandes crème */
}
.edge--top{
  top:0; left:0; width:100%; height: var(--thick);
  transform-origin: 50% 0%;
  transform: translateZ(calc(var(--thick) / 2)) rotateX(-90deg);
}
.edge--bottom{
  bottom:0; left:0; width:100%; height: var(--thick);
  transform-origin: 50% 100%;
  transform: translateZ(calc(var(--thick) / 2)) rotateX(90deg);
}
/* tranche extérieure (bord libre, opposé au pli) : la plus visible en cours de pivot */
.edge--outer{
  top:0; right:0; width: var(--thick); height:100%;
  transform-origin: 100% 50%;
  transform: translateZ(calc(var(--thick) / 2)) rotateY(90deg);
}

/* --- dos (spine) au pli : fine tranche unie, couleur de la pochette
       (un peu plus claire) — plus de lames ni de bandes crème --- */
.spine{
  position: absolute; left: 50%; top: 0; bottom: 0;
  width: var(--thick);
  margin-left: calc(var(--thick) * -.5);
  background: var(--ink-edge);
  pointer-events: none;
  /* le dos de carton n'a de sens tant que le volet pivote (il simule son
     épaisseur) ; une fois le volet ouvert (--flip proche de 1), il se
     retrouve à plat dans l'axe de la caméra et passait devant le disque
     qui sort du volet — on l'efface plutôt que de le laisser flotter
     devant une pièce censée être rangée derrière lui */
  opacity: clamp(0, calc(1 - (var(--flip) - .7) * 3.334), 1);
}

/* --- recto de pochette : un vrai disque, pas un livre — la cover art
       (photo, cf. .face--cover) est plein cadre, pas de titre ni de
       sticker HTML : l'image contient déjà tout le texte imprimé --- */
.cover{
  position: relative;
  height: 100%;
}
/* grain d'impression offset : bruit subtil en superposition, aucune image lourde */
.cover::before{
  content:"";
  position:absolute; inset:0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.045 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
  opacity: .5;
  pointer-events: none;
}

/* --- pages intérieures (volet droit fixe + verso du volet qui pivote) --- */
.page h2, .face--liner h2{
  position: relative;
  font-family: var(--font-titres); font-weight: 700;
  font-size: clamp(13px, 4cqw, 17px); letter-spacing: .01em;
  margin: 0 0 12px;
}
.page h2 + h2{ margin-top: 18px; }
.liner-note{ position: relative; font-size: 14px; line-height: 1.75; max-width: 34em; }
.liner-note p{ margin: 0 0 12px; }

.tracks{ position: relative; list-style: none; margin: 0; padding: 0; font-size: 13.5px; }
.tracks li{
  display: grid; grid-template-columns: 26px 1fr;
  gap: 10px; padding: 6px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--card) 20%, transparent);
}
.tracks b{ font-family: var(--font-labels); font-weight: 700; color: var(--card); }

/* =========================================================
   3. LE DISQUE — rangé dans le volet droit, se dégage à l'ouverture
   ========================================================= */
.disc-slot{
  position: absolute; top: 50%;
  /* centré sur le volet droit *visible* (50%-100% du gatefold, donc à 1.5×panel
     de son bord gauche) — pas sur 50% du gatefold entier, qui inclut l'espace
     vide que le volet balaie en pivotant. left:50% + une petite marge plaçait
     le disque à cheval sur cette zone vide : il débordait "dans le noir". */
  left: calc(var(--panel) * 1.5);
  width: calc(var(--panel) * .84); height: calc(var(--panel) * .84);
  margin: calc(var(--panel) * -.42) 0 0 calc(var(--panel) * -.42);
  /* derrière .page (z implicite 0 > -3px ici) : le disque est cousu dans
     la pochette, invisible tant qu'il n'a pas glissé au-delà du bord
     droit de .page (opaque et sans transform, cf. plus haut — pourquoi
     pas de Z explicite dessus) ; 60-85% : il glisse hors du volet par
     la tranche extérieure (voir progress()) */
  transform: translateZ(-3px) translateX(calc(var(--disc) * 58%));
  will-change: transform;
}
/* pochette intérieure (inner sleeve) : masquée — le disque glisse
   maintenant hors d'une vraie pochette (.page, cf. section 2), le carré
   crème qui dépassait autour du vinyle n'a plus lieu d'être. Seul .disc
   doit rester visible pendant le glissement. */
.sleeve{ display: none; }

.disc{
  position:absolute; inset:0;
  border-radius: 50%;
  transform-style: preserve-3d;
  box-shadow: 0 20px 40px rgba(0,0,0,.55);
}
/* tourne avec le scroll (pas en boucle infinie) : 2 tours complets sur
   toute la durée de .intro, cf. var(--p) dans js/main.js — progress(). */
.disc__vinyl{
  position:absolute; inset:0;
  border-radius:50%;
  background:
    repeating-radial-gradient(circle at 50% 50%,
      var(--vinyl-groove) 0 1px, transparent 1px 4px),
    radial-gradient(circle at 50% 50%, var(--vinyl) 0 21%, var(--vinyl-deep) 21% 100%);
  transform: rotate(calc(var(--p) * 720deg));
  will-change: transform;
}

/* reflet spéculaire fixe dans l'espace écran : le vinyle tourne dessous,
   l'éclat semble donc balayer la surface — cohérent avec la lumière haut-gauche */
.disc__sheen{
  position:absolute; inset:0; border-radius:50%;
  background: linear-gradient(125deg,
    transparent 30%, rgba(255,255,255,.16) 47%, rgba(255,255,255,.02) 56%, transparent 68%);
  mix-blend-mode: screen;
  opacity: calc(var(--disc) * .9);
}
/* étiquette centrale imprimée — seul aplat d'accent autorisé (règle 2) */
.disc__label{
  position:absolute; left:50%; top:50%;
  width: 21%; height: 21%; margin: -10.5% 0 0 -10.5%;
  border-radius:50%;
  background: radial-gradient(circle at 38% 32%, #FFC65D 0%, var(--accent) 55%, #C37E00 100%);
}
/* texte courbé au-dessus du trou seulement (cercle de guidage invisible,
   cf. <path id="label-curve"> dans le HTML) — un texte droit traversait
   le trou central au lieu de le contourner. Encre sombre (--ink) : l'accent
   est clair, un texte clair par-dessus n'y serait plus lisible. */
.disc__label svg{ width:100%; height:100%; overflow: visible; }
.disc__label path{ fill:none; stroke:none; }
.disc__label text{
  font-family: var(--font-labels); font-weight: 700; font-size: 9px; letter-spacing:.12em;
  fill: color-mix(in srgb, var(--ink) 85%, transparent); text-transform:uppercase;
}
.disc__hole{
  position:absolute; left:50%; top:50%;
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  border-radius:50%;
  background: var(--vinyl-deep); /* le trou est vide, pas "la pièce" : toujours sombre, jamais le thème */
}

/* =========================================================
   4. INVITE À OUVRIR
   ========================================================= */
/* au-dessus du bouton : indique qu'il faut scroller (pas seulement
   cliquer). Disparaît vite et pour de bon dès que le scroll démarre
   (dès --p > 0.05, ×20 = 1/0.05) — sinon il resterait affiché par-
   dessus la pochette qui s'ouvre. */
.scroll-indicator{
  position: absolute; bottom: calc(5vh + 34px); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  font-family: var(--font-labels); font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted);
  pointer-events: none;
  opacity: calc(1 - var(--p) * 20);
  animation: hint-in 280ms ease-out backwards;
  animation-delay: 1330ms;
}
.scroll-indicator__arrow{
  animation: scroll-bounce 1.6s ease-in-out infinite;
}
@keyframes scroll-bounce{
  0%, 100%{ transform: translateY(0); }
  50%{ transform: translateY(6px); }
}
.hint{
  position: absolute; bottom: 5vh; left: 50%; transform: translateX(-50%);
  font-family: var(--font-labels); font-size: 12.5px; letter-spacing: .1em;
  color: var(--text-muted);
  background: none; border: 0; cursor: pointer;
  opacity: calc(1 - var(--p) * 3.5);
  /* dernier maillon de la séquence d'entrée : apparaît après le sticker */
  animation: hint-in 280ms ease-out backwards;
  animation-delay: 1330ms;
}
@keyframes hint-in{
  from{ opacity: 0; }
  to{ opacity: calc(1 - var(--p) * 3.5); }
}

/* =========================================================
   5. NOTES DE POCHETTE — le contenu long, sous la scène
   Composition en colonnes, hiérarchie typographique imprimée —
   pas de cartes arrondies, pas d'ombre douce.
   ========================================================= */
main{
  position: relative; z-index: 2;
  background: var(--bg-deep);
  border-top: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  padding: clamp(54px, 9vw, 96px) 24px;
}
.wrap{ max-width: 920px; margin: 0 auto; }
section + section{ margin-top: clamp(52px, 8vw, 88px); }

.side-head{
  display:flex; flex-wrap: wrap; align-items:baseline; gap: 8px 14px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  padding-bottom: 10px; margin-bottom: 26px;
}
.side-head__num{
  font-family: var(--font-labels); font-weight: 700; font-size: 13px;
  letter-spacing:.1em; color: var(--accent-text);
}
h2.side{
  font-family: var(--font-titres); font-weight: 700;
  font-size: clamp(22px, 3.2vw, 30px); letter-spacing: -.01em;
  margin: 0;
}
.side-sub{ color: var(--text-muted); font-size: 14px; margin: 0 0 0 auto; font-family: var(--font-labels); letter-spacing:.02em; }

.tracklist{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0 40px;
}
.entry{
  display: grid; grid-template-columns: 40px 1fr; gap: 16px;
  padding: 18px 0;
  border-top: 1px solid var(--rule);
}
.entry b{ font-family: var(--font-labels); font-weight: 700; color: var(--accent-text); font-size: 13px; }
.entry h3{ font-family: var(--font-labels); font-weight: 700; font-size: 16px; margin: 0 0 6px; letter-spacing: -.005em; }
.entry p{ margin: 0; font-size: 15px; color: var(--text-muted); max-width: 60ch; }

.specs{ display: grid; gap: 0 32px; grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); }
.specs div{ border-top: 1px solid var(--rule); padding: 14px 0; }
.specs span{
  display:block; font-family: var(--font-labels); font-weight:600; font-size: 11.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent-text); margin-bottom: 4px;
}
.specs p{ margin:0; font-size: 14.5px; color: var(--text-muted); }

footer{
  margin-top: 64px; padding-top: 18px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  font-family: var(--font-labels); font-size: 13px; letter-spacing:.02em; color: var(--text-muted);
}

/* =========================================================
   6. PETITS ÉCRANS + ACCESSIBILITÉ
   ========================================================= */
@media (max-width: 860px){
  :root{
    /* la pochette doit toujours tenir entière dans l'écran, largeur ET
       hauteur (portrait, paysage, fenêtre courte...) : vmin = la plus
       petite des deux dimensions du viewport, donc toujours la plus
       contraignante des deux. 320px reste le plafond "normal" (inchangé
       sur un téléphone en portrait classique, ex. 390×844) ; 85vmin ne
       prend le relais que si l'écran est trop court ou trop étroit pour
       ça, évitant le rognage par .stage{overflow:hidden}. */
    --panel: min(320px, 85vmin, 90vw);
    --thick: 5px;
  }
  /* même correction qu'en desktop : état fermé frontal, aucune inclinaison
     statique (cf. .gatefold plus haut — un rotateX statique y provoquait
     aussi le z-fighting sur la face fermée). L'animation d'entrée est sur
     .scene (pas .gatefold, cf. plus haut pourquoi) : sa formule ne
     dépend pas de --panel, donc rien à adapter ici pour elle. */
  .gatefold{
    width: var(--panel);
    transform: rotateX(calc(var(--open) * 5deg)) translateZ(calc(var(--open) * 40px));
  }
  .page, .flipper{ inset: 0; }
  .flipper{ transform: translateZ(2px) rotateY(calc(var(--flip) * -165deg)); }
  /* .page/.flipper couvrent ici tout le gatefold (inset:0, un seul panel) au lieu
     de sa moitié droite : le centre du disque doit suivre, sinon il retombe dans
     le même défaut que le bug desktop corrigé plus haut. */
  .disc-slot{ left: calc(var(--panel) * .5); margin-left: calc(var(--panel) * -.42); }
  /* même raison : le pli (transform-origin de .flipper) est ici au bord
     gauche du gatefold (inset:0), pas à son centre — le dos de carton doit
     suivre, sinon il dessine une barre au milieu de la pochette fermée */
  .spine{ left: 0; }
  .cover, .page, .face--liner{ padding: 24px; }
  .theme-toggle{ top: 12px; right: 12px; padding: 7px 12px; font-size: 11px; }
}
/* plus de palier fixe à 400px : la formule vmin/vw ci-dessus au-dessus
   (≤860px) s'adapte déjà en continu, y compris sur les très petits
   écrans — un palier séparé n'apportait plus rien. */

/* Pochette ouverte d'emblée, en pile lisible (recto puis verso puis page) —
   ni le titre ni les notes de pochette ne doivent disparaître. Même bloc
   repris tel quel dans le <noscript> du HTML pour le cas sans JS. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  .intro{ height: auto; }
  .stage{ position: static; height: auto; padding: 48px 0; overflow: visible; }
  .scene{ transform: none; }
  .gatefold{
    transform: none; height: auto; display: block;
    width: min(92vw, calc(var(--panel) * 2)); margin: 0 auto;
  }
  .flipper{ position: static; inset: auto; transform: none; }
  .face{ position: static; inset: auto; backface-visibility: visible; width: 100%; }
  /* .face--cover n'a plus de contenu en flux normal (photo de fond +
     ::before décoratif seulement) : elle s'effondrerait à une hauteur
     nulle ici (position:static). Le panel est toujours un carré
     (cf. --panel) : aspect-ratio le rétablit sans dépendre du contenu. */
  .face--cover{ transform: none; aspect-ratio: 1; }
  .face--liner{ transform: none; }
  .page{ position: static; width: 100%; margin-top: 16px; }
  .edges, .spine, .shadow{ display: none; }
  /* position:relative (pas static) : .sleeve et .disc, en position:absolute,
     ont besoin de .disc-slot comme bloc de référence pour rester en place */
.disc-slot{
  position: relative;
  top: auto; left: auto;
  transform: none;
  margin: 24px auto;
}
  .hint, .scroll-indicator{ display: none; }
  /* aucune animation d'entrée sous ce mode */
  .scene{ animation: none; }
}
