/* Commandes : onglets d'épreuve, bouton de lancement, barre de rejeu, frise des
   repères et panneau des conditions d'essai.

   La barre de rejeu flotte au-dessus de la scène 3D — layout.css la place, cette
   feuille l'habille. Elle doit rester lisible sur une image de plein soleil
   comme sur une image de nuit : d'où le fond semi-opaque et le flou
   d'arrière-plan, avec un repli entièrement opaque là où le flou n'existe pas.
   Un chrono blanc sur un ciel blanc n'est pas un défaut d'esthétique, c'est une
   information perdue.

   La barre de progression n'a volontairement pas de remplissage dégradé : la
   position est portée par la tête de lecture et par la frise, et un dégradé
   obligerait à réécrire un style soixante fois par seconde.

   Les couleurs, les espacements et les durées viennent toutes de tokens.css. Les
   seules valeurs écrites en dur ici sont des géométries de quelques pixels, qui
   n'ont de sens que pour ce composant. */

/* ================================================================== */
/* Onglets d'épreuve                                                   */
/* ================================================================== */

.scenario-tab {
  border: 1px solid transparent;
  border-bottom-width: 2px;
  border-radius: var(--radius-1) var(--radius-1) 0 0;
  background: transparent;
  color: var(--ink-2);
  font-weight: 500;
}

.scenario-tab:hover:not([aria-disabled='true']) {
  background: var(--bg-2);
  border-color: transparent;
  color: var(--ink-0);
}

.scenario-tab[aria-selected='true'] {
  background: var(--bg-3);
  border-color: transparent;
  border-bottom-color: var(--accent);
  color: var(--ink-0);
}

/* Pendant un calcul, les onglets restent visibles et focalisables mais inertes :
   un onglet réellement désactivé perdrait le focus au milieu d'une navigation
   au clavier. */
.scenario-tab[aria-disabled='true'] {
  opacity: 0.5;
  cursor: progress;
}

/* ================================================================== */
/* Bouton de lancement                                                 */
/* ================================================================== */

/* Résultat périmé : le bouton change de couleur et bat lentement. C'est ce qui
   évite de lire un tableau qui décrit la voiture précédente. */
#run-button[data-stale='true'] {
  background: linear-gradient(180deg, var(--warn), color-mix(in srgb, var(--warn) 82%, black));
  border-color: color-mix(in srgb, var(--warn) 62%, black);
  color: var(--accent-ink);
  animation: run-stale 1.8s var(--ease) infinite;
}

#run-button[data-stale='true']:hover:not(:disabled) {
  background: linear-gradient(180deg, color-mix(in srgb, var(--warn) 85%, white), var(--warn));
  box-shadow: none;
}

#run-button[aria-busy='true'] {
  cursor: progress;
}

@keyframes run-stale {
  0%,
  100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--warn) 55%, transparent);
  }
  50% {
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--warn) 0%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  #run-button[data-stale='true'] {
    animation: none;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--warn) 45%, transparent);
  }
}

/* Pastille du bouton des conditions : les conditions ne sont plus celles de
   référence, et cela doit se voir même panneau fermé. */
#conditions-button {
  position: relative;
}

#conditions-button[data-off='true']::after {
  content: '';
  position: absolute;
  top: 2px;
  right: 2px;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--warn);
  box-shadow: 0 0 0 2px var(--bg-1);
}

/* Bouton de l'historique : l'icône et son libellé. Sur un écran étroit,
   l'icône seule ; le libellé, masqué à l'œil seulement, reste le nom du
   bouton pour un lecteur d'écran. */
#history-button {
  gap: var(--sp-1);
}

#history-button svg {
  flex: none;
}

@media (max-width: 920px) {
  #history-button .history-button-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
}

/* Sur un téléphone, la barre du haut ne loge pas à la fois le nom de
   l'application et ses quatre commandes : le sélecteur de langue était réduit
   à une flèche. Le nom s'efface à l'œil — la marque rayée reste, et le lien
   garde son nom pour un lecteur d'écran —, et les commandes se resserrent. */
@media (max-width: 480px) {
  .topbar-actions {
    gap: var(--sp-1);
  }

  #topbar .brand-name {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ================================================================== */
/* Barre de rejeu                                                      */
/* ================================================================== */

#playback {
  /* La largeur minimale vient de layout.css ; le maximum appartient à la barre,
     qui doit pouvoir accueillir un long résumé de conditions sans déborder de
     la scène. */
  max-width: calc(100% - 2 * var(--sp-4));
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-3);
  background: var(--bg-1);
  background: color-mix(in srgb, var(--bg-1) 80%, transparent);
  box-shadow: var(--shadow-2);
  color: var(--ink-1);
  backdrop-filter: blur(12px) saturate(1.25);
}

@supports not (backdrop-filter: blur(2px)) {
  #playback {
    background: var(--bg-1);
  }
}

.pb {
  display: grid;
  gap: var(--sp-2);
}

/* ---- Avertissements et résumé des conditions ---- */

.pb-notices {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.pb-stale,
.pb-note {
  margin: 0;
}

.pb-stale {
  color: var(--warn);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.pb-stale:empty,
.pb-note:empty {
  display: none;
}

.pb-chip {
  margin-inline-start: auto;
  max-width: 100%;
  border-color: color-mix(in srgb, var(--warn) 60%, transparent);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  color: var(--warn);
  font-size: var(--fs-xs);
  font-weight: 500;
  text-align: start;
  white-space: normal;
}

.pb-chip:hover:not(:disabled) {
  border-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 22%, transparent);
  color: var(--warn);
}

/* ---- Frise : repères au-dessus, curseur en dessous ---- */

.pb-frise {
  --pb-thumb: 16px;
  display: grid;
  gap: 0;
}

.pb-marks {
  position: relative;
  height: 15px;
}

/* Le repère est placé sur la course utile du curseur, qui est amputée d'un
   demi-pouce de chaque côté : sans cette correction, le repère de fin tomberait
   à droite de la position que la tête de lecture peut atteindre. */
.pb-mark {
  position: absolute;
  bottom: 0;
  left: calc(var(--pb-thumb) / 2 + (100% - var(--pb-thumb)) * var(--at, 0));
  width: 15px;
  height: 15px;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: none;
  transform: translateX(-50%);
  cursor: pointer;
}

.pb-mark::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 2px;
  height: 9px;
  border-radius: 1px;
  background: var(--ink-3);
  transform: translateX(-50%);
  transition: background var(--t-fast) var(--ease), height var(--t-fast) var(--ease);
}

.pb-mark:hover:not(:disabled)::after,
.pb-mark:focus-visible::after {
  background: var(--accent);
  height: 13px;
}

.pb-mark:disabled {
  cursor: default;
  opacity: 0.45;
}

/* Le libellé reste dans le document même invisible : c'est lui qui donne son nom
   au bouton pour un lecteur d'écran. */
.pb-mark-label {
  position: absolute;
  bottom: calc(100% - 2px);
  left: 50%;
  padding: 2px var(--sp-2);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-1);
  background: var(--bg-3);
  color: var(--ink-0);
  font-size: var(--fs-xs);
  white-space: nowrap;
  transform: translateX(-50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-fast) var(--ease);
}

.pb-mark:hover:not(:disabled) .pb-mark-label,
.pb-mark:focus-visible .pb-mark-label {
  opacity: 1;
}

.pb-scrub {
  width: 100%;
  height: var(--pb-thumb);
  margin: 0;
  padding: 0;
  background: transparent;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

.pb-scrub::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-2);
}

.pb-scrub::-moz-range-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-2);
}

.pb-scrub::-webkit-slider-thumb {
  width: var(--pb-thumb);
  height: var(--pb-thumb);
  margin-top: calc((4px - var(--pb-thumb)) / 2);
  border: 2px solid var(--accent-ink);
  border-radius: var(--radius-pill);
  background: var(--accent);
  box-shadow: var(--shadow-1);
  appearance: none;
  -webkit-appearance: none;
}

.pb-scrub::-moz-range-thumb {
  width: var(--pb-thumb);
  height: var(--pb-thumb);
  border: 2px solid var(--accent-ink);
  border-radius: var(--radius-pill);
  background: var(--accent);
  box-shadow: var(--shadow-1);
}

.pb-scrub:disabled {
  cursor: default;
  opacity: 0.45;
}

/* ---- Transport ---- */

.pb-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.pb-icon {
  min-width: 34px;
  justify-content: center;
  font-size: var(--fs-md);
  line-height: 1;
}

/* Le chrono change cent fois par seconde : une largeur réservée empêche la
   rangée de se réorganiser à chaque centième. */
.pb-time {
  min-width: 15ch;
  color: var(--ink-0);
  font-size: var(--fs-sm);
  text-align: center;
}

.pb-sep {
  color: var(--ink-3);
}

.pb-total {
  color: var(--ink-2);
}

/* ---- Vitesses de rejeu ---- */

/* Vrais boutons radio, masqués mais focalisables : le groupe ne prend qu'une
   seule tabulation et les flèches passent d'une vitesse à l'autre, ce qu'une
   rangée de six boutons ne saurait pas faire. */
.pb-rates {
  position: relative;
}

.pb-rate-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.pb-rate {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.pb-rate-input:checked + .pb-rate {
  background: var(--bg-4);
  border-color: var(--accent);
  color: var(--ink-0);
}

.pb-rate-input:focus-visible + .pb-rate {
  outline: 2px solid var(--line-focus);
  outline-offset: 2px;
}

.pb-rate-input:disabled + .pb-rate {
  opacity: 0.45;
  cursor: not-allowed;
}

.pb-mute[data-muted='true'] span {
  color: var(--ink-3);
  text-decoration: line-through;
}

/* ---- Voiture suivie par la caméra ---- */

.pb-follow-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

/* Le groupe disparaît quand il n'y a qu'une voiture : sans cette règle,
   `display: flex` l'emporterait sur l'attribut et laisserait une rangée vide. */
.pb-follow-row[hidden] {
  display: none;
}

.pb-follow-legend {
  flex: none;
}

/* Quatre voitures et un nom complet dépassent la largeur de la barre sur un
   écran étroit : le groupe passe à la ligne plutôt que de pousser la barre
   hors de la scène. */
.pb-follow {
  flex-wrap: wrap;
  max-width: 100%;
}

.pb-follow-pick {
  display: inline-flex;
  gap: var(--sp-1);
  align-items: center;
  cursor: pointer;
}

.pb-follow-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--slot-color, var(--ink-3));
}

/* « Mercedes-AMG GT Black Series » tiendrait sur la moitié de la barre : le nom
   est coupé à l'affichage, et l'infobulle le donne en entier. */
.pb-follow-name {
  overflow: hidden;
  max-width: 13ch;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La touche est écrite dans le jeton et non seulement dans l'infobulle : un
   raccourci qui demande de survoler pour être découvert ne l'est jamais. */
.pb-follow-key {
  flex: none;
  padding: 0 3px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  color: var(--ink-2);
  font-family: var(--font-num);
  font-size: var(--fs-xs);
  line-height: 1.4;
}

.pb-follow-pick.is-active .pb-follow-key {
  border-color: var(--ink-3);
  color: var(--ink-1);
}

/* Mode meneur : la voiture cadrée en ce moment. La marque entoure la pastille
   de couleur et non le jeton entier, d'abord parce que c'est ainsi que la
   mini-carte désigne déjà la voiture suivie, ensuite parce qu'un second cadre
   autour du jeton se confondrait avec celui du choix pressé — on ne saurait
   plus lequel des deux dit ce qu'on a demandé. */
.pb-follow-pick[data-live='true'] .pb-follow-dot {
  box-shadow: 0 0 0 2px rgb(242 245 249 / 0.85);
}

/* ================================================================== */
/* Panneau des conditions d'essai                                      */
/* ================================================================== */

/* Tiroir ancré sous la barre haute, du côté du bouton qui l'ouvre. Il n'est pas
   modal : on règle une température pour voir ce qu'elle change, et il faut
   pouvoir relancer l'épreuve sans refermer le panneau. */
aside.cond {
  position: fixed;
  top: calc(var(--topbar-h) + var(--sp-2));
  right: var(--sp-3);
  z-index: 40;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: min(430px, calc(100vw - 2 * var(--sp-3)));
  max-height: calc(100vh - var(--topbar-h) - 2 * var(--sp-3));
  max-height: calc(100dvh - var(--topbar-h) - 2 * var(--sp-3));
  border: 1px solid var(--line-2);
  border-radius: var(--radius-3);
  background: var(--bg-2);
  box-shadow: var(--shadow-3);
  color: var(--ink-1);
}

aside.cond > .panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line-1);
}

aside.cond > .cond-body {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-4);
  overflow-y: auto;
  overflow-x: hidden;
}

aside.cond > .cond-foot {
  display: flex;
  justify-content: flex-end;
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--line-1);
}

/* L'écart aux conditions de référence, en tête du panneau. Même couleur que la
   pastille du bouton et que la pastille de la barre de rejeu : trois endroits,
   un seul signal. */
.cond-summary {
  margin: 0;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid color-mix(in srgb, var(--warn) 60%, transparent);
  border-radius: var(--radius-1);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  color: var(--warn);
  font-size: var(--fs-sm);
}

.cond-summary:empty {
  display: none;
}

/* Raccourcis vers les groupes du bas : une ligne de liens qui revient à la
   ligne dans un volet étroit plutôt que de déborder. */
.cond-jump {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-3);
}

.cond-jump-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.cond-jump-link:hover {
  color: var(--ink-0);
}

.cond-group {
  display: grid;
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-4) 0 0;
  border: 0;
  border-top: 1px solid var(--line-1);
}

.cond-group:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.cond-group > legend {
  grid-column: 1 / -1;
  padding: 0;
  color: var(--ink-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cond-label {
  color: var(--ink-1);
  font-size: var(--fs-sm);
}

.cond-value {
  color: var(--ink-0);
  font-size: var(--fs-sm);
}

.cond-hint {
  margin: 0;
  line-height: 1.4;
}

.cond-field.is-off {
  opacity: 0.5;
}

/* ---- Choix exclusifs décrits un à un ---- */

.cond-choices {
  display: grid;
  gap: var(--sp-3);
}

.cond-choice {
  display: grid;
  gap: 2px;
}

.cond-choice-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--ink-0);
  font-size: var(--fs-md);
  cursor: pointer;
}

.cond-choice-cost,
.cond-check .cond-hint {
  margin: 0;
  margin-inline-start: var(--sp-5);
  line-height: 1.4;
}

.cond-check-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--ink-0);
  font-size: var(--fs-md);
  cursor: pointer;
}

.cond-note {
  margin: 0;
  color: var(--info);
}

.cond-note:empty {
  display: none;
}

/* Intertitre à l'intérieur d'un groupe : plus discret que la légende, qui
   reste le premier niveau de lecture du panneau. */
.cond-subhead {
  margin: var(--sp-2) 0 0;
  color: var(--ink-0);
  font-size: var(--fs-sm);
  font-weight: 600;
}

/* Un réglage sans effet dans l'état présent reste réglable mais se grise ; sa
   phrase d'état, elle, garde tout son contraste, puisque c'est elle qui dit
   pourquoi. */
.cond-field.is-inert .field-row,
.cond-field.is-inert input[type='range'],
.cond-field.is-inert .cond-hint {
  opacity: 0.5;
}

.cond-off-note {
  color: var(--ink-1);
}

/* ================================================================== */
/* Réglages d'image appliqués au document                              */
/* ================================================================== */

/* Le HUD est construit par render/hud.js ; sa visibilité est un réglage de
   l'interface, pas du rendu, et se règle donc ici plutôt qu'en démontant la
   surimpression. */
body[data-hud='off'] #hud {
  display: none;
}

/* ================================================================== */
/* Export vidéo                                                        */
/* ================================================================== */

/* Le bouton de la barre de rejeu, à côté du partage. Le point rouge est celui
   de tout bouton d'enregistrement : il dit « vidéo » avant qu'on lise le mot. */
.pb-video {
  gap: var(--sp-1);
}

.pb-video-icon {
  color: var(--bad);
  font-size: 0.8em;
  line-height: 1;
}

.pb-video:disabled .pb-video-icon {
  color: var(--ink-3);
}

/* Fenêtres de l'export : réglages, progression, fichier prêt. */
.video-export {
  display: grid;
  gap: var(--sp-3);
  min-width: min(440px, 80vw);
}

.vx-group {
  display: grid;
  gap: var(--sp-1);
  margin: 0;
  padding: 0;
  border: 0;
}

.vx-legend {
  padding: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.vx-choices {
  position: relative;
  justify-self: start;
}

/* Vrais boutons radio, masqués mais focalisables, comme les vitesses de rejeu. */
.vx-choice-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.vx-choice {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.vx-choice-input:checked + .vx-choice {
  background: var(--bg-4);
  border-color: var(--accent);
  color: var(--ink-0);
}

.vx-choice-input:focus-visible + .vx-choice {
  outline: 2px solid var(--line-focus);
  outline-offset: 2px;
}

.vx-format,
.vx-summary {
  margin: 0;
  color: var(--ink-1);
  font-size: var(--fs-sm);
}

/* Un enregistrement en temps réel ou un WebM n'est pas ce qu'on attendait : la
   phrase prend la couleur d'un avertissement. */
.vx-format[data-state='realtime'],
.vx-format[data-state='none'],
.vx-warn {
  color: var(--warn);
}

.vx-note {
  margin: 0;
}

.vx-file {
  font-family: var(--font-num);
  overflow-wrap: anywhere;
}

/* Aperçu de la dernière image enregistrée : la scène de la page est mise de
   côté pendant l'export, c'est le seul endroit où l'on voit ce qui se filme. */
.vx-preview {
  display: block;
  width: 100%;
  max-width: 480px;
  aspect-ratio: 16 / 9;
  justify-self: center;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-2);
  background: var(--bg-0);
}

.vx-bar {
  width: 100%;
  height: 6px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--bg-3);
  accent-color: var(--accent);
}

.vx-bar::-webkit-progress-bar { background: var(--bg-3); border-radius: var(--radius-pill); }
.vx-bar::-webkit-progress-value { background: var(--accent); border-radius: var(--radius-pill); }
.vx-bar::-moz-progress-bar { background: var(--accent); border-radius: var(--radius-pill); }

.vx-status {
  margin: 0;
  min-height: 1.5em;
}

/* ================================================================== */
/* Écrans étroits                                                      */
/* ================================================================== */

@media (max-width: 920px) {
  aside.cond {
    left: var(--sp-3);
    right: var(--sp-3);
    width: auto;
  }

  /* Sur une tablette, la rangée de transport se replie plutôt que de rogner le
     chrono : la durée et la vitesse de rejeu valent une deuxième ligne. */
  .pb-time {
    min-width: 13ch;
  }
}
