/* Système commun aux trois pages : « l'affiche » au pastel.
   Du papier blanc, une encre noire franche, et quatre aplats pastel
   pour les chapitres : rose, bleu, jaune, lilas. La notation se lit toujours
   en noir sur blanc. Pendant le jeu, deux couleurs ont un métier : le
   surligneur jaune = où tu en es, le rouge = une faute. Coins carrés, pas de
   filet, pas d'ombre au repos : les surfaces se séparent par un cran de ton. */

:root {
  --papier: #ffffff;       /* fond, papier de la notation */
  --papier-2: #f3f3f1;     /* un cran : rangées, barres */
  --papier-3: #e6e6e2;     /* deux crans : survol, pistes, touches éteintes */
  --encre: #161616;        /* texte, notation, boutons pleins */
  --encre-2: #57534c;      /* texte secondaire */
  --encre-3: #857f76;      /* notes déjà jouées, traits discrets (3:1 au moins sur les fonds clairs) */
  --rose: #ffcdc5;         /* aplat : l'ouverture */
  --bleu: #c8d7fb;         /* aplat : bandeau de jeu, réglages */
  --jaune: #ffe9a8;        /* aplat : morceaux */
  --lilas: #ddd6f5;        /* aplat : pied, diagnostic */
  --surligneur: #ffd970;   /* où tu en es : note courante, sélection, touche enfoncée */
  --rouge: #c02e2e;        /* la faute, seulement */

  --display: "Red Hat Display", "Arial Black", system-ui, sans-serif;
  --ui: "Red Hat Text", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* Cinq tailles, pas une de plus. */
  --t-petit: 14px;
  --t-corps: 18px;
  --t-lead: clamp(20px, 1.2rem + .6vw, 26px);
  --t-titre: clamp(40px, 1.2rem + 5vw, 88px);
  --t-affiche: clamp(96px, 14vw, 220px);

  --sortie: cubic-bezier(0.23, 1, 0.32, 1);
  --glisse: cubic-bezier(0.77, 0, 0.175, 1);
  --tiroir: cubic-bezier(0.32, 0.72, 0, 1);
  --cote: 32px;
  --largeur: 1100px;
  --bord: max(var(--cote), calc((100% - var(--largeur)) / 2 + var(--cote)));
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html {
  background: var(--papier);
  touch-action: manipulation;
  scroll-padding-top: 100px;
  color-scheme: light;
}
body {
  margin: 0;
  min-height: 100dvh;
  background: var(--papier);
  color: var(--encre);
  font: 400 var(--t-corps)/1.5 var(--ui);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  overscroll-behavior: none;
}
[hidden] { display: none !important; }
h1, h2, h3, p { margin: 0; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
::selection { background: var(--surligneur); color: var(--encre); }
:focus-visible { outline: 3px solid var(--encre); outline-offset: 3px; }
* { scrollbar-width: thin; scrollbar-color: var(--encre-3) transparent; }

/* Navigation entre pages : un fondu, l'en-tête reste en place. */
@view-transition { navigation: auto; }

/* ---------- Bandeau des écrans de travail ---------- */
.bandeau {
  position: sticky;
  top: 0;
  z-index: 10;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 16px;
  min-height: 80px;
  padding: env(safe-area-inset-top) var(--bord) 0;
  background: var(--papier-2);
  color: var(--encre);
  view-transition-name: bandeau;
}
.bandeau.bleu { background: var(--bleu); }
.bandeau .gauche { justify-self: start; display: flex; align-items: center; gap: 8px; min-width: 0; }
.bandeau .droite { justify-self: end; display: flex; align-items: center; gap: 12px; min-width: 0; }
.bandeau h1 {
  font: 900 28px/1.3 var(--display);
  letter-spacing: -.02em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 46vw;
}

.onglets { display: flex; gap: 4px; }
.onglets a {
  position: relative;
  color: inherit;
  font: 500 var(--t-corps)/1 var(--ui);
  text-decoration: none;
  padding: 14px 12px;
}
.onglets a::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 6px;
  height: 3px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms var(--sortie);
}
.onglets a[aria-current="page"]::after { transform: scaleX(1); }

/* ---------- Boutons : carrés, d'un seul aplat ou d'un trait plein ---------- */
.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 22px;
  font: 500 var(--t-corps)/1 var(--ui);
  color: inherit;
  background: transparent;
  border: 2px solid currentColor;
  border-radius: 0;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 160ms var(--sortie), background-color 160ms ease, color 160ms ease;
}
.bouton:active { transform: scale(0.97); }
.bouton.plein { background: var(--encre); color: var(--papier); border-color: var(--encre); }
.bouton:disabled { opacity: .4; cursor: default; transform: none; }
.bouton svg { width: 20px; height: 20px; flex: none; }
.bouton .fleche { transition: transform 220ms var(--sortie); }

.bouton-texte {
  font: 500 var(--t-corps)/1.2 var(--ui);
  color: inherit;
  background: none;
  border: 0;
  padding: 12px 2px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 2px;
}
.bouton-texte:disabled { cursor: default; text-decoration: none; opacity: .6; }
.lien { color: inherit; text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 2px; }

@media (hover: hover) and (pointer: fine) {
  .bouton:hover { background: rgba(22, 22, 22, .07); }
  .bouton.plein:hover { background: #000000; }
  .bouton:hover .fleche { transform: translateX(4px); }
  .bouton-texte:hover, .lien:hover { text-decoration-thickness: 3px; }
}

/* ---------- Rangées de réglages (chapitre bleu de l'accueil, panneau) ---------- */
.reglages { display: grid; gap: 8px; }
.reglage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px 24px;
  padding: 22px 24px;
  background: rgba(255, 255, 255, .6);
}
.reglage .quoi { flex: 1 1 220px; font-weight: 700; }
.reglage .quoi small { display: block; margin-top: 4px; font-size: var(--t-corps); font-weight: 400; }
.reglage .segments { background: var(--papier); }
.reglage .interrupteur:not(:checked) { background: var(--papier); }
label.reglage { cursor: pointer; }
/* L'interrupteur dit aussi son état en toutes lettres. */
.reglage .bascule { display: inline-flex; align-items: center; gap: 14px; }
.reglage .etat-bascule { min-width: 3ch; font-weight: 700; text-align: right; }
.reglage .actions { display: flex; flex-wrap: wrap; gap: 8px; }
.reglage .actions .bouton { min-height: 48px; font-weight: 700; }
.etat-sauvegarde { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 16px; font-weight: 500; }

/* ---------- Le panneau des réglages ----------
   Un tiroir bleu qui glisse de la droite, par-dessus l'écran en cours
   (l'affiche, une série, un morceau) ; on le referme et on reprend. Pleine
   largeur au téléphone. */
.panneau {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(560px, 100vw);
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0 0 calc(32px + env(safe-area-inset-bottom));
  border: 0;
  background: var(--bleu);
  color: var(--encre);
  overflow: auto;
  overscroll-behavior: contain;
}
.panneau::backdrop { background: rgba(22, 22, 22, .4); }
.panneau .tete-panneau {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: calc(16px + env(safe-area-inset-top)) 24px 16px;
  background: var(--bleu);
}
.panneau h2 { font: 900 40px/1 var(--display); letter-spacing: -.03em; text-transform: uppercase; }
.panneau .fermer { width: 52px; padding: 0; }
.panneau .note-panneau { margin: 0 24px 16px; font-weight: 500; }
.panneau .contenu-panneau { padding: 0 24px; }
@media (prefers-reduced-motion: no-preference) {
  .panneau[open] { animation: tiroir-entree 320ms var(--tiroir); }
  .panneau[open]::backdrop { animation: voile-entree 320ms ease; }
}
@keyframes tiroir-entree { from { transform: translateX(100%); } }
@keyframes voile-entree { from { opacity: 0; } }

/* ---------- L'en-tête : écoute et réglages, toujours en haut à droite ---------- */
.actions-entete { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* L'écoute en cours, en une étiquette : une icône (piano, micro, clavier à
   l'écran) et le nom du piano ou l'état. La toucher ouvre ses réglages. */
.etat-ecoute { min-height: 44px; min-width: 0; max-width: 24ch; padding: 0 12px; gap: 8px; font-size: 16px; }
.etat-ecoute .icone { display: none; width: 20px; height: 20px; flex: none; }
.etat-ecoute[data-mode="piano"] .icone-piano,
.etat-ecoute[data-mode="micro"] .icone-micro,
.etat-ecoute[data-mode="ecran"] .icone-ecran { display: block; }
.etat-ecoute .statut::before { display: none; }
.etat-ecoute:not(.ok) .icone { opacity: .45; }
.ouvrir-reglages { min-height: 44px; padding: 0 14px; }

/* ---------- Statut du piano ---------- */
/* Un nom de piano trop long se coupe d'une ellipse au lieu de pousser le
   reste de l'en-tête (les pages n'en affichent déjà que le modèle). */
.statut { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; }
.statut::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 8px; border: 2px solid currentColor; vertical-align: .02em; }
.statut.ok::before { background: currentColor; }

/* Problème de connexion : un aplat d'encre, impossible à rater sur le pastel. */
.alerte {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 20px;
  padding: 16px var(--bord);
  background: var(--encre);
  color: var(--papier);
}
.alerte strong { font-weight: 700; color: var(--rose); }
.alerte .detail { flex: 1 1 320px; }
/* Téléphone en « version pour ordinateur » : la page est rétrécie, donc
   l'avertissement se dimensionne sur la largeur de la page (vw) pour rester
   lisible une fois réduit. */
.alerte-ordinateur { position: fixed; left: 0; right: 0; bottom: 0; z-index: 70; padding: 3vw 4vw calc(3vw + env(safe-area-inset-bottom)); font-size: 3.6vw; line-height: 1.35; }
.alerte-ordinateur .detail { flex-basis: 100%; }
.alerte-ordinateur .bouton { font-size: 3.6vw; min-height: 10vw; padding: 0 5vw; }

/* ---------- Règle de progression du jeu ---------- */
.regle { display: flex; align-items: center; gap: 20px; padding: 24px var(--bord) 0; }
.regle .compte { font: 900 44px/1 var(--display); letter-spacing: -.02em; white-space: nowrap; }
.regle .compte span { font: 500 var(--t-corps)/1 var(--ui); letter-spacing: 0; color: var(--encre-2); }
.regle .trait { position: relative; flex: 1; height: 6px; background: var(--papier-3); }
.regle .trait i { position: absolute; left: 0; top: 0; width: 0; height: 6px; background: var(--encre); }
.regle .fautes { color: var(--rouge); font-weight: 700; white-space: nowrap; }

/* ---------- Faute : liseré bref sur le bord de l'écran ---------- */
.lisere { position: fixed; inset: 0; z-index: 50; pointer-events: none; border: 8px solid var(--rouge); opacity: 0; }

/* ---------- Contrôles ---------- */
/* Contrôle segmenté : la pastille d'encre glisse vers le choix (voir
   placerPastille dans les pages). */
.segments {
  position: relative;
  display: inline-flex;
  padding: 4px;
  background: var(--papier-3);
  isolation: isolate;
}
.segments::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: var(--pastille-l, 0);
  background: var(--encre);
  transform: translateX(var(--pastille-x, 0));
  transition: transform 300ms var(--sortie), width 300ms var(--sortie);
}
.segments button {
  min-width: 60px;
  min-height: 48px;
  padding: 0 16px;
  font: 700 var(--t-corps)/1 var(--ui);
  color: var(--encre);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color 200ms ease, background-color 0s;
}
/* Le bouton choisi prend lui-même l'aplat quand la pastille est arrivée. */
.segments button[aria-pressed="true"] { color: var(--papier); background: var(--encre); transition: color 200ms ease, background-color 0s 300ms; }

.interrupteur {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: 64px;
  height: 36px;
  margin: 0;
  background: var(--papier-3);
  cursor: pointer;
  transition: background-color 200ms ease;
}
.interrupteur::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: 28px;
  height: 28px;
  background: var(--encre);
  transition: transform 260ms var(--sortie), background-color 200ms ease;
}
.interrupteur:checked { background: var(--encre); }
.interrupteur:checked::after { transform: translateX(28px); background: var(--papier); }

.avert { margin-top: 24px; padding: 16px 20px; background: var(--papier-2); color: var(--encre-2); }

/* ---------- Pied de page ---------- */
.pied {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 48px var(--bord) calc(32px + env(safe-area-inset-bottom));
  color: var(--encre-2);
}

/* Altérations dans un nom de note : dessinées en SVG. Dans un nom courant,
   le signe a la hauteur d'une lettre ; dans un nom monumental (.grand), il se
   fait petit et surélevé. */
svg.alt {
  width: .42em;
  height: .84em;
  margin: 0 .03em 0 .05em;
  vertical-align: -.1em;
  fill: none;
  stroke: currentColor;
  overflow: visible;
}
.grand { letter-spacing: -.02em; }
.grand svg.alt { width: .27em; height: .54em; vertical-align: .25em; margin-right: 0; }

@media (max-width: 760px) {
  :root { --cote: 16px; }
  .reglage { padding: 18px 16px; }
  .panneau .tete-panneau { padding-left: 16px; padding-right: 16px; }
  .panneau .contenu-panneau { padding: 0 12px; }
  .panneau .note-panneau { margin: 0 16px 12px; }
  .etat-ecoute { max-width: 11em; padding: 0 8px; gap: 6px; font-size: 15px; }
  .ouvrir-reglages { padding: 0 11px; }
  .ouvrir-reglages .libelle { display: none; }
  .bandeau { gap: 8px; min-height: 68px; }
  .bandeau h1 { font-size: 22px; }
  .bandeau .libelle { display: none; }
  .bandeau .bouton { padding: 0 14px; }
  /* Les onglets gardent leur place ; l'étiquette d'écoute, à droite, se
     coupe d'une ellipse s'il le faut. */
  body:not(.mode-jeu) .bandeau:has(.onglets) { grid-template-columns: auto minmax(0, 1fr); }
  body:not(.mode-jeu) .bandeau:has(.onglets) h1 { display: none; }
}

/* ---------- Changement d'écran (View Transitions) ----------
   L'ancien écran s'efface en montant, le nouveau arrive d'en dessous ; au
   retour, l'inverse. Un élément nommé (le niveau touché) peut se transformer
   en bandeau : c'est l'entrée dans le niveau. */
::view-transition-group(root) { animation-duration: 340ms; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 340ms; animation-timing-function: var(--sortie); animation-fill-mode: both; }
html[data-sens="avant"]::view-transition-old(root) { animation-name: ecran-part-haut; }
html[data-sens="avant"]::view-transition-new(root) { animation-name: ecran-vient-bas; }
html[data-sens="retour"]::view-transition-old(root) { animation-name: ecran-part-bas; }
html[data-sens="retour"]::view-transition-new(root) { animation-name: ecran-vient-haut; }
html[data-sens="fondu"]::view-transition-old(root) { animation-name: ecran-fond-sortie; }
html[data-sens="fondu"]::view-transition-new(root) { animation-name: ecran-fond-entree; }
::view-transition-group(*) { animation-duration: 420ms; animation-timing-function: var(--sortie); }
/* Entrée dans un niveau : la rangée touchée s'étire jusqu'au bandeau et son
   nom monte prendre la place du titre ; le reste de l'écran passe en fondu. */
html[data-sens="niveau"]::view-transition-old(root) { animation: 220ms ease both ecran-fond-sortie; }
html[data-sens="niveau"]::view-transition-new(root) { animation: 380ms var(--sortie) 160ms both ecran-fond-entree; }
html[data-sens="niveau"]::view-transition-group(bandeau),
html[data-sens="niveau"]::view-transition-group(titre-jeu) { animation-duration: 560ms; animation-timing-function: var(--tiroir); }
html[data-sens="niveau"]::view-transition-old(bandeau),
html[data-sens="niveau"]::view-transition-new(bandeau) { width: 100%; height: 100%; object-fit: fill; }
html[data-sens="niveau"]::view-transition-old(bandeau) { animation: 280ms ease both ecran-fond-sortie; }
html[data-sens="niveau"]::view-transition-new(bandeau) { animation: 300ms ease 140ms both ecran-fond-entree; }
/* Le nom du niveau qui devient titre : un léger flou pendant le fondu
   efface la double image des deux écritures superposées. */
html[data-sens="niveau"]::view-transition-old(titre-jeu) { animation: 240ms ease both flou-sortie; }
html[data-sens="niveau"]::view-transition-new(titre-jeu) { animation: 320ms ease 120ms both flou-entree; }
@keyframes flou-sortie { to { opacity: 0; filter: blur(2px); } }
@keyframes flou-entree { from { opacity: 0; filter: blur(2px); } }
@keyframes ecran-part-haut { to { opacity: 0; transform: translateY(-24px) scale(.98); } }
@keyframes ecran-vient-bas { from { opacity: 0; transform: translateY(32px); } }
@keyframes ecran-part-bas { to { opacity: 0; transform: translateY(24px) scale(.98); } }
@keyframes ecran-vient-haut { from { opacity: 0; transform: translateY(-32px); } }
@keyframes ecran-fond-sortie { to { opacity: 0; } }
@keyframes ecran-fond-entree { from { opacity: 0; } }

/* ---------- Apparition au défilement ----------
   Les éléments marqués [data-apparait] montent en se révélant quand ils
   entrent à l'écran (classe .vu posée par la page). Sans script, ils restent
   visibles : la classe .anime n'est posée sur <html> que si le script tourne. */
.anime [data-apparait] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 700ms var(--sortie), transform 800ms var(--sortie);
  transition-delay: calc(var(--rang, 0) * 80ms);
}
.anime [data-apparait].vu { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .bouton, .interrupteur, .interrupteur::after, .segments::before, .onglets a::after { transition: none; }
  .panneau[open], .panneau[open]::backdrop { animation: voile-entree 200ms ease; }
  html[data-sens]::view-transition-old(root) { animation-name: ecran-fond-sortie; }
  html[data-sens]::view-transition-new(root) { animation-name: ecran-fond-entree; }
  .anime [data-apparait] { transform: none; transition: opacity 300ms ease; }
}
