/* Affichage tête haute posé sur la scène 3D.

   Trois règles gouvernent cette feuille.

   D'abord, rien ici ne capte le pointeur. Le HUD couvre la scène entière, et la
   scène se pilote à la souris : un bloc de chiffres qui intercepterait un
   glissement volerait la rotation de caméra. `pointer-events: none` est donc
   porté par la racine et par tout ce qu'elle contient, et le HUD n'expose aucun
   élément interactif — les dispositions se changent au clavier, depuis main.js.

   Ensuite, aucune dimension de canvas n'est écrite ici en pixels de dessin : le
   module fixe `width`/`height` d'après `devicePixelRatio`, et la feuille ne
   donne que la taille d'affichage. Un canvas dimensionné des deux côtés en CSS
   est un canvas flou.

   Enfin les couleurs : les blocs empruntent la couleur de série de leur
   emplacement par `--slot-color`, que hud.js renseigne depuis la palette de
   tokens.css, comme le font déjà le garage et le tableau. Aucune couleur de
   voiture n'est écrite dans cette feuille. Le fond des blocs est volontairement
   très sombre et translucide dans les deux thèmes : il est posé sur une image
   de synthèse, pas sur le fond de l'application, et un fond clair sur un ciel
   clair ne se lit plus. */

/* ================================================================== */
/* Ossature                                                            */
/* ================================================================== */

/* La racine, construite par hud.js dans #hud. Elle ne porte pas de position :
   #hud est déjà en absolu sur toute la scène (layout.css), et la racine se
   contente de le remplir. */
.hud {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: var(--sp-2);
  padding: var(--sp-3);
  pointer-events: none;
  font-family: var(--font-ui);
  /* Le HUD est au-dessus du canvas, au-dessous du bandeau de caméras et du
     panneau de rejeu, qui sont eux cliquables. */
  z-index: 5;
}

.hud * { pointer-events: none; }

.hud.is-hidden,
.hud[data-layout='masque'] { visibility: hidden; }

.hud-left {
  grid-column: 1;
  grid-row: 1;
  /* Sous le bandeau des caméras, qui s'étend jusqu'ici sur une scène étroite. */
  padding-top: var(--camera-bar-clear, 0px);
  display: grid;
  gap: var(--sp-2);
  align-content: start;
  min-width: 0;
}

.hud-marks {
  grid-column: 2;
  grid-row: 1;
  /* Sous le bandeau des caméras, qui flotte au même niveau sur un autre
     calque : sa hauteur réelle arrive par --camera-bar-clear. */
  padding-top: var(--camera-bar-clear, 0px);
  display: grid;
  gap: var(--sp-1);
  justify-items: center;
  align-content: start;
  min-width: 0;
}

.hud-gg {
  grid-column: 1;
  grid-row: 3;
  align-self: end;
  justify-self: start;
}

/* Disposition sobre : la vitesse et l'écart, rien d'autre. C'est la vue d'une
   capture d'écran ou d'une démonstration, où les barres et le diagramme g-g
   encombrent plus qu'ils n'informent. */
.hud[data-layout='sobre'] .hud-gauge,
.hud[data-layout='sobre'] .hud-aux,
.hud[data-layout='sobre'] .hud-start-label,
.hud[data-layout='sobre'] .hud-gg,
.hud[data-layout='sobre'] .hud-gaps { display: none; }

/* ================================================================== */
/* Bloc d'une voiture                                                  */
/* ================================================================== */

.hud-cars {
  display: grid;
  gap: var(--sp-2);
  min-width: 0;
}

.hud-car {
  display: grid;
  gap: 2px;
  width: 182px;
  padding: var(--sp-1) var(--sp-2) 6px;
  border-left: 3px solid var(--slot-color, var(--accent));
  border-radius: 0 var(--radius-2) var(--radius-2) 0;
  /* Fond translucide, mais sans `backdrop-filter` : un flou d'arrière-plan
     oblige le compositeur à relire la scène 3D sous chaque bloc à chaque image,
     et la cible est un portable sans carte graphique dédiée. */
  background: rgb(7 9 13 / 0.62);
  box-shadow: var(--shadow-2);
  color: #f2f5f9;
}

/* Le meneur porte un liseré plus franc : la position se lit alors sans
   comparer les distances, d'un seul coup d'œil. */
.hud-car[data-leader='true'] { box-shadow: var(--shadow-2), inset 1px 0 0 0 var(--slot-color); }

/* La voiture cadrée est entourée d'un trait clair, comme sa pastille sur la
   mini-carte et comme son jeton dans la barre de rejeu : une même chose
   montrée à trois endroits mérite un même signe. */
.hud-car[data-followed='true'] { outline: 1px solid rgb(242 245 249 / 0.75); outline-offset: -1px; }

.hud-car-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  min-width: 0;
}

.hud-car-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slot-color, var(--accent));
}

.hud-car-pos {
  font-family: var(--font-num);
  font-size: var(--fs-xs);
  color: #8a96a7;
}

.hud-car-main {
  display: flex;
  align-items: baseline;
  gap: 4px;
  min-width: 0;
}

/* La vitesse est le seul chiffre lisible de loin : elle occupe la place, et
   garde une largeur de caractère fixe pour ne pas tressauter à chaque image. */
.hud-speed {
  flex: 1;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-3xl);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  text-align: right;
  color: #f2f5f9;
}

.hud-speed-unit {
  font-size: var(--fs-xs);
  color: #8a96a7;
}

/* Le rapport engagé, dans un carré : c'est l'information qui change le plus
   souvent après la vitesse, et un chiffre nu se perdrait à côté d'elle. */
.hud-gear {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid rgb(255 255 255 / 0.14);
  border-radius: var(--radius-1);
  background: rgb(255 255 255 / 0.06);
  font-family: var(--font-num);
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1;
  color: #f2f5f9;
}

.hud-gauge {
  display: block;
  width: 100%;
  height: 20px;
}

/* Départ différé. Sur une épreuve de freinage, les voitures rapides attendent
   sur la grille que la plus lente ait de l'avance : le bloc le dit, dans le
   langage des feux de départ — un chiffre qui descend, puis le signal. Le
   compte prend la couleur de la voiture, le signal celle de la réussite, et
   le reste du bloc s'estompe le temps de l'attente : une vitesse à zéro n'a
   rien à dire tant que la voiture n'a pas le droit de partir. */
.hud-start {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
  min-width: 0;
}

.hud-start[hidden] { display: none; }

.hud-start-label {
  white-space: nowrap;
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #c3ccd9;
}

.hud-start-value {
  white-space: nowrap;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: 1;
  color: var(--slot-color, var(--accent));
}

.hud-car[data-waiting='go'] .hud-start-value {
  flex: 1;
  text-align: right;
  letter-spacing: 0.12em;
  color: var(--ok);
}

.hud-car[data-waiting='attente'] .hud-car-main,
.hud-car[data-waiting='attente'] .hud-gauge,
.hud-car[data-waiting='attente'] .hud-car-foot { opacity: 0.35; }

/* Handicap d'une mise en vitesse, ou vitesse d'où a freiné une voiture qui
   n'a pas atteint celle des autres : une ligne d'information, pas un signal.
   Le chiffre reste à la taille du texte courant pour ne pas rivaliser avec la
   vitesse, juste en dessous. */
.hud-car[data-waiting='differe'] .hud-start-value,
.hud-car[data-waiting='entree'] .hud-start-value {
  font-size: var(--fs-sm);
  color: #c3ccd9;
}

/* Freinage. Le signal s'allume avec les feux stop de la voiture, au même
   instant : un bandeau rouge posé sur la jauge, et le bloc qui prend un liseré
   rouge le temps du freinage. Le nom de la voiture reste entier dans
   l'en-tête, et la couleur de la voiture garde le bord gauche, qui
   l'identifie ; le rouge est celui du feu, pas celui d'une erreur. */
.hud-gauge-wrap {
  position: relative;
  min-width: 0;
}

.hud-brake {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  border-radius: var(--radius-1);
  background: var(--bad);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1;
  white-space: nowrap;
  text-transform: uppercase;
  color: #07090d;
}

.hud-car[data-braking='true'] .hud-brake {
  display: grid;
  animation: hud-brake-on 0.45s var(--ease);
}

/* Sans jauge, le bandeau n'a rien à recouvrir : il prend sa propre ligne le
   temps du freinage. */
.hud[data-layout='sobre'] .hud-brake {
  position: static;
  padding: 2px 0;
}

.hud-car[data-braking='true'] {
  box-shadow: var(--shadow-2), inset 0 0 0 1px var(--bad);
}

/* L'allumage marque l'instant : un éclat bref, puis la pastille tient. La
   préférence de mouvement réduit le ramène à un allumage sec, comme toutes
   les transitions de l'application. */
@keyframes hud-brake-on {
  from { transform: scaleY(1.5); filter: brightness(1.7); }
  to { transform: none; filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hud-car[data-braking='true'] .hud-brake { animation: none; }
}

.hud-car-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
  min-width: 0;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
}

.hud-gap { color: #c3ccd9; }
.hud-car[data-leader='true'] .hud-gap { color: var(--ok); }
/* Sur un bloc étroit, une valeur coupée en deux lignes (« 4 450 » puis
   « tr/min ») ferait sauter la hauteur du bloc au rythme du régime. */
.hud-gap,
.hud-aux { white-space: nowrap; }
.hud-aux { color: #8a96a7; }

/* ================================================================== */
/* Écarts et diagramme g-g                                             */
/* ================================================================== */

/* Deux canvas, deux raisons. Les écarts et le g-g changent à chaque image et
   demanderaient autant d'écritures dans le DOM ; dessinés, ils ne coûtent que
   quelques dizaines de lignes par image. */

.hud-gaps {
  display: block;
  width: 182px;
  height: 0;                   /* hauteur imposée par hud.js : une ligne par voiture */
  border-radius: var(--radius-1);
  background: rgb(7 9 13 / 0.62);
  box-shadow: var(--shadow-2);
  font-family: var(--font-num);
  font-size: var(--fs-xs);
}

.hud-gg {
  display: block;
  width: 148px;
  height: 148px;
  border-radius: var(--radius-2);
  background: rgb(7 9 13 / 0.58);
  box-shadow: var(--shadow-2);
  font-family: var(--font-num);
  font-size: var(--fs-xs);
}

/* ================================================================== */
/* Repères franchis                                                    */
/* ================================================================== */

/* Un repère tombe, s'affiche quelques secondes, puis s'efface. L'opacité est
   portée par une classe et non par une valeur en ligne : la politique de
   contenu interdit les attributs `style` écrits en dur, et une transition CSS
   coûte moins qu'une animation pilotée en JavaScript. */
.hud-mark {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  max-width: min(440px, 100%);
  padding: 3px var(--sp-3);
  border-left: 3px solid var(--slot-color, var(--accent));
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
  background: rgb(7 9 13 / 0.72);
  box-shadow: var(--shadow-2);
  font-size: var(--fs-sm);
  color: #f2f5f9;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}

.hud-mark.is-visible { opacity: 1; transform: none; }
.hud-mark[hidden] { display: none; }

.hud-mark-car {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 11ch;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slot-color, var(--accent));
}

.hud-mark-label { color: #c3ccd9; }

.hud-mark-value {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

/* L'épreuve en cours, au-dessus des repères dont elle partage la colonne :
   elle rappelle ce qu'on regarde sur une capture d'écran sortie de son
   contexte. */
.hud-scenario {
  order: -1;
  padding: 2px var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #8a96a7;
  text-shadow: 0 1px 3px rgb(0 0 0 / 0.8);
}

/* Mise en vitesse d'une épreuve de freinage : un bandeau sobre sous le nom
   de l'épreuve, tant que les voitures se lancent. Il dit que les départs sont
   décalés exprès, avant que l'œil ne lise une course là où il n'y en a pas. */
.hud-staging {
  display: grid;
  justify-items: center;
  gap: 1px;
  max-width: min(580px, 100%);
  padding: 4px var(--sp-3);
  border-radius: var(--radius-2);
  background: rgb(7 9 13 / 0.72);
  box-shadow: var(--shadow-2);
  text-align: center;
  color: #f2f5f9;
}

.hud-staging[hidden] { display: none; }

.hud-staging-title {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hud-staging-detail {
  font-size: var(--fs-sm);
  color: #c3ccd9;
}

/* ================================================================== */
/* Mini-carte                                                          */
/* ================================================================== */

/* La mini-carte (render/minimap.js) est construite dans #hud, juste après la
   racine du HUD : elle n'est pas dans la grille de celui-ci, et elle lit sa
   disposition par le sélecteur de frère. C'est la seule surface du HUD qui
   reçoit le pointeur, pour qu'un clic sur une voiture la désigne.

   Elle est posée en bas à droite, au-dessus de la barre de rejeu. Le coin bas
   gauche est déjà pris : la colonne des voitures y descend avec quatre
   voitures, et le diagramme g-g occupe le pied de cette colonne. À droite, il
   n'y a que la barre de caméras, en haut, et les repères, centrés et brefs.

   La barre de rejeu occupe toute la largeur du bas de la scène, et sa hauteur
   dépend de son contenu : main.js la publie dans --playback-clear. La valeur
   de secours est celle de la barre sur une seule ligne de réglages.

   Les tailles se règlent sur la scène et non sur la fenêtre : #hud est déclaré
   conteneur, ce qui donne les unités cqw et cqh et permet de masquer la carte
   quand la scène est trop basse pour la loger au-dessus de la barre. */

#hud { container: hud / size; }

.minimap {
  position: absolute;
  right: var(--sp-3);
  bottom: calc(var(--playback-clear, 140px) + var(--sp-2));
  z-index: 6;
  width: clamp(150px, 30cqw, 244px);
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-2);
  /* Même fond que les blocs du HUD, sans flou d'arrière-plan pour la même
     raison : relire la scène 3D sous la carte à chaque image coûte trop sur
     un portable sans carte graphique dédiée. */
  background: rgb(7 9 13 / 0.58);
  box-shadow: var(--shadow-2);
  pointer-events: auto;
  font-family: var(--font-num);
  overflow: hidden;
}

/* Une règle des distances, ou une piste ouverte comme le slalom, est longue
   et basse : un cadre carré y serait vide aux deux tiers. */
.minimap[data-shape='wide'] {
  width: clamp(190px, 42cqw, 320px);
  aspect-ratio: 3 / 1;
}

/* Le canvas remplit le cadre ; sa taille de dessin est fixée par le module
   d'après la densité de l'écran. */
.minimap-canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* Un glissement commencé sur la carte n'est pas un geste de caméra. */
  touch-action: none;
}

.minimap.is-pointing .minimap-canvas { cursor: pointer; }

/* Dispositions du HUD : la sobre réduit la carte, la masquée la retire. Le
   retrait passe par display et non par visibility : le module mesure alors un
   canvas de taille nulle et cesse de dessiner. */
.hud[data-layout='sobre'] ~ .minimap { width: clamp(120px, 22cqw, 180px); }
.hud[data-layout='sobre'] ~ .minimap[data-shape='wide'] { width: clamp(160px, 32cqw, 240px); }
.hud[data-layout='masque'] ~ .minimap,
.hud.is-hidden ~ .minimap { display: none; }

/* Scène trop basse : la carte se poserait sur la barre de caméras. */
@container hud (max-height: 400px) {
  .minimap { display: none; }
}

:root[data-theme='light'] .minimap {
  background: rgb(7 9 13 / 0.74);
  box-shadow: var(--shadow-3);
}

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

/* Sous 920 px la scène occupe toute la largeur et le panneau de rejeu, centré
   et large, vient mordre le coin bas gauche : le diagramme g-g remonte
   au-dessus de lui. Sous 620 px il n'y a plus de place du tout, et la vitesse
   seule vaut mieux qu'un empilement illisible. */
@media (max-width: 920px) {
  .hud { padding: var(--sp-2) var(--sp-2) 84px; }
  .hud-car { width: 150px; }
  .hud-gaps { width: 150px; }
  .hud-gg { width: 112px; height: 112px; }
  .hud-speed { font-size: var(--fs-2xl); }
}

@media (max-width: 620px) {
  .hud-gg, .hud-gaps { display: none; }
  .hud-scenario { display: none; }
}

/* Thème clair : le HUD reste sombre — il est posé sur la scène 3D, pas sur le
   fond de l'application — mais son contour se détache un peu plus, sans quoi un
   bloc sombre sur un ciel clair paraît collé n'importe où. */
:root[data-theme='light'] .hud-car,
:root[data-theme='light'] .hud-gaps,
:root[data-theme='light'] .hud-gg,
:root[data-theme='light'] .hud-mark,
:root[data-theme='light'] .hud-staging {
  background: rgb(7 9 13 / 0.78);
  box-shadow: var(--shadow-3);
}
