/* ==========================================================================
   omnidash.css — page du projet Omnidash
   Structure : fond en paliers → écran encadré (remplissage noir 50 %)
   → header (fond + titre) → contour blanc du cadre, au-dessus de tout.
   ========================================================================== */

.omnidash {
  /* Palette */
  --om-cyan: #1fe8d6;
  --om-purple: #2a0050;
  --om-magenta: #e61db9;
  --om-yellow: #ffe169;
  --om-red: #ff005a;

  /* Cadre */
  --om-frame-inset: 0px;  /* distance entre le cadre et le bord de la fenêtre */
  --om-frame-border: 3px; /* épaisseur du contour blanc */

  /* Ombres portées : nettes, sans flou (en pixels de l'image d'origine) */
  --om-shadow-offset: 6;
  --om-shadow-color: rgb(0 0 0 / 0.5);

  /* Boutons précédent / suivant : à l'intérieur du cadre */
  --project-nav-inset: calc(var(--om-frame-inset) + var(--om-frame-border) + 12px);

  /* Hauteur du titre du header (96 px sur 1920) + marge : haut du contenu */
  --om-content-top: calc((100vw - 2 * var(--om-frame-inset)) * 96 / 1920 + 2rem);

  /* Textes du contenu */
  --om-text: #efe3ff;
  --om-text-muted: #c9b3e6;

  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Fond : fondu par paliers #2A0050 → #E61DB9, 20 paliers
   -------------------------------------------------------------------------- */

.omnidash::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to bottom,
    #2a0050 0% 5%,
    #340256 5% 10%,
    #3e035b 10% 15%,
    #480561 15% 20%,
    #520666 20% 25%,
    #5b086c 25% 30%,
    #650971 30% 35%,
    #6f0b77 35% 40%,
    #790c7c 40% 45%,
    #830e82 45% 50%,
    #8d0f87 50% 55%,
    #97118d 55% 60%,
    #a11292 60% 65%,
    #ab1498 65% 70%,
    #b5159d 70% 75%,
    #be17a3 75% 80%,
    #c818a8 80% 85%,
    #d21aae 85% 90%,
    #dc1bb3 90% 95%,
    #e61db9 95% 100%
  );
}

/* --------------------------------------------------------------------------
   Écran encadré
   -------------------------------------------------------------------------- */

.om-screen {
  position: fixed;
  inset: var(--om-frame-inset);
  overflow: hidden; /* rien (ombres comprises) ne dépasse du cadre */
  background: rgb(0 0 0 / 0.5);
}

/* Contour blanc, posé au-dessus du header et du contenu */
.om-screen::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 30;
  border: var(--om-frame-border) solid #fff;
  pointer-events: none;
}

/* Zone de contenu défilante, sous le header */
.om-content {
  position: absolute;
  inset: var(--om-frame-border);
  overflow-x: hidden;
  overflow-y: auto;
  padding: var(--om-content-top) var(--gutter) 9rem;
  color: var(--om-text);
  scrollbar-color: var(--om-magenta) transparent;
}

@media (prefers-reduced-motion: no-preference) {
  .om-content {
    scroll-behavior: smooth;
  }
}

/* --------------------------------------------------------------------------
   Header
   Les images sont dessinées pour 1920 px de large : --px vaut un pixel
   de l'image d'origine, mis à l'échelle de la largeur du header.
   -------------------------------------------------------------------------- */

.om-header {
  container-type: inline-size;
  position: absolute;
  z-index: 10;
  top: 0;
  left: 0;
  right: 0;
  --px: calc(100cqw / 1920);
}

.om-header img {
  filter: drop-shadow(0 calc(var(--om-shadow-offset) * var(--px)) 0 var(--om-shadow-color));
}

.om-header__bg {
  width: 100%;
  height: auto;
}

.om-header__title {
  position: absolute;
  top: 0;
  left: 50%;
  width: calc(481 * var(--px));
  translate: -50% 0;
}

.om-header__title img {
  width: 100%;
  height: auto;
}

/* Textes LCD */
.om-header__title h1,
.om-header__label {
  margin: 0;
  font-family: "LCD2", var(--font-sans);
  font-weight: 700;
  line-height: 1;
  color: #fff;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: calc(2 * var(--px)) calc(2 * var(--px)) 0 var(--om-shadow-color);
}

.om-header__title h1 {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: calc(62 * var(--px));
}

/* Étiquettes de part et d'autre du titre, centrées dans la bande du fond */
.om-header__label {
  position: absolute;
  top: calc(34 * var(--px));
  translate: -50% -50%;
  font-size: calc(40 * var(--px));
}

.om-header__label--left {
  left: 27%;
}

a.om-header__label {
  text-decoration: none;
  transition: color 0.2s ease;
}

a.om-header__label:hover,
a.om-header__label:focus-visible {
  color: var(--om-yellow);
  outline: none;
}

.om-header__label--right {
  left: 71%;
}

/* Au-delà de 1920 px, garder les marches des images nettes */
@media (min-width: 1921px) {
  .om-header img {
    image-rendering: pixelated;
  }
}

/* ==========================================================================
   HUD du header (étiquette de droite) : section en cours + effet
   Piloté par js/omnidash.js ; les tailles suivent --px comme le header.
   ========================================================================== */

.om-hud {
  z-index: 1;
  display: flex;
  align-items: center;
  gap: calc(14 * var(--px));
}

/* Section Testa : Roustel (écriture néon), jamais en capitales, un peu plus
   grande que le LCD pour compenser ses traits fins */
.om-hud[data-font="roustel"] {
  font-family: "Roustel", var(--font-sans);
  font-size: calc(50 * var(--px));
  font-weight: 400;
  text-transform: none;
}

.om-hud[data-font="roustel"] .om-hud__text {
  translate: 0 calc(4 * var(--px)); /* centrage optique : la police est haute sur sa ligne */
}

/* Flammes (SVG créé par le script), sous le cartouche OMNIDASH d'où elles
   sortent. Hauteur = bandeau (68) + débordement (50), en pixels des images */
.om-hud-fire {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 100%;
  height: calc(118 * var(--px));
  overflow: visible;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}

.om-hud-fire.is-on {
  opacity: 1;
}

.om-header__title {
  z-index: 1;
}

.om-hud__char {
  display: inline-block;
  white-space: pre;
}

/* Changement de section : petit « pop » */
.om-hud.is-switching {
  animation: om-hud-pop 0.35s ease-out;
}

@keyframes om-hud-pop {
  0%   { scale: 1.35; filter: brightness(1.8); }
  100% { scale: 1; filter: none; }
}

/* Effet « wave » : les lettres ondulent l'une après l'autre */
.om-hud[data-effect="wave"] .om-hud__char {
  animation: om-wave 1.3s ease-in-out infinite;
  animation-delay: calc(var(--i) * -0.1s);
}

@keyframes om-wave {
  0%, 100% { translate: 0 calc(3 * var(--px)); }
  50%      { translate: 0 calc(-5 * var(--px)); }
}

/* Effet « sparks » : texte chauffé à blanc (le jet de flammes vient du script) */
.om-hud[data-effect="sparks"] {
  color: #fff4cf;
  text-shadow:
    calc(2 * var(--px)) calc(2 * var(--px)) 0 var(--om-shadow-color),
    0 0 calc(10 * var(--px)) rgb(255 120 40 / 0.85);
}

/* Effet « speedo » : compte-tours horizontal à côté du texte */
.om-speedo {
  display: flex;
  align-items: flex-end;
  gap: calc(3 * var(--px));
  height: calc(30 * var(--px));
}

.om-speedo i {
  width: calc(7 * var(--px));
  height: calc((10 + var(--n) * 1.7) * var(--px));
  background: rgb(255 255 255 / 0.25);
  box-shadow: calc(2 * var(--px)) calc(2 * var(--px)) 0 var(--om-shadow-color);
}

.om-speedo i.is-on                 { background: var(--om-cyan); }
.om-speedo i.is-on:nth-child(n+7)  { background: var(--om-yellow); }
.om-speedo i.is-on:nth-child(n+11) { background: var(--om-red); }

/* ==========================================================================
   Contenu : les « stages »
   ========================================================================== */

.om-todo {
  color: var(--om-yellow);
  font-style: italic;
}

.om-stage {
  position: relative;
  max-width: 1200px;
  margin-inline: auto;
  scroll-margin-top: var(--om-content-top);
}

.om-stage + .om-stage {
  margin-top: clamp(8rem, 18vh, 12rem);
}

/* Transition synthwave : grille en perspective au-dessus de chaque stage */
.om-stage + .om-stage::before {
  content: "";
  position: absolute;
  top: calc(-1 * clamp(6.5rem, 14vh, 9.5rem));
  left: 0;
  right: 0;
  height: clamp(4rem, 9vh, 5.5rem);
  background:
    linear-gradient(var(--om-magenta) 0 0) top / 100% 2px no-repeat,
    repeating-linear-gradient(90deg, rgb(230 29 185 / 0.6) 0 2px, transparent 2px 64px),
    repeating-linear-gradient(rgb(230 29 185 / 0.6) 0 2px, transparent 2px 16px);
  transform: perspective(260px) rotateX(58deg);
  transform-origin: top;
  mask-image: linear-gradient(#000 15%, transparent);
  opacity: 0.55;
  pointer-events: none;
}

.om-stage__head {
  max-width: 64rem;
  margin: 0 auto clamp(2rem, 5vh, 3.5rem);
  text-align: center;
}

.om-stage__tag {
  margin: 0 0 0.6rem;
  color: var(--om-cyan);
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(0.95rem, 1.2vw, 1.2rem);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-shadow: 0 0 8px rgb(31 232 214 / 0.7);
  text-transform: uppercase;
}

.om-stage__title {
  margin: 0;
  color: #fff;
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(2.2rem, 4.5vw, 4rem);
  font-weight: 700;
  line-height: 1;
  text-shadow:
    3px 3px 0 var(--om-magenta),
    0 0 18px rgb(230 29 185 / 0.6);
  text-transform: uppercase;
}

.om-stage__intro {
  margin: 1.25rem 0 0;
  color: var(--om-text-muted);
  font-size: 1.1rem;
  line-height: 1.6;
}

/* Mot en Roustel dans un texte : écriture néon, un peu plus grande pour
   compenser ses traits fins, sans agrandir l'interligne */
.om-roustel {
  font-family: "Roustel", var(--font-sans);
  font-size: 1.5em;
  line-height: 0;
  color: #fff;
  text-shadow:
    0 0 2px #fff,
    0 0 8px var(--om-magenta),
    0 0 18px var(--om-magenta);
}

/* Écran (vidéo / capture) : cadre blanc, ombre nette, lignes de balayage */
.om-media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 2px solid #fff;
  background: #14002a;
  box-shadow: 6px 6px 0 rgb(0 0 0 / 0.5);
}

/* En attendant la vidéo : le cartouche du header avec « Bientôt disponible »
   (LCD2 n'a pas de « ô » : écrit sans accent). La vidéo le recouvre dès
   qu'elle est chargée. */
.om-media::before {
  content: "Bientot disponible";
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: min(60%, 26rem);
  aspect-ratio: 481 / 96;
  translate: -50% -50%;
  background: url("../../ressources/omnidash/header_title.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 4px 0 rgb(0 0 0 / 0.5));
  color: #fff;
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(0.85rem, 1.5vw, 1.35rem);
  font-weight: 700;
  line-height: 1;
  text-shadow: 2px 2px 0 rgb(0 0 0 / 0.5);
  text-transform: uppercase;
  white-space: nowrap;
}

.om-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: repeating-linear-gradient(rgb(0 0 0 / 0.12) 0 1px, transparent 1px 3px);
  pointer-events: none;
}

.om-media video,
.om-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.om-media video,
.om-showroom__media video {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.om-media video.is-loaded,
.om-showroom__media video.is-loaded {
  opacity: 1;
}

/* Pixel art : agrandi sans flou */
.om-media--pixel video {
  object-fit: contain;
  image-rendering: pixelated;
}

/* Écran contenant une planche animée (css/sprite.css), centrée */
.om-media--sprite {
  display: grid;
  place-items: center;
}

.om-media--sprite::before {
  content: none; /* pas de message d'attente : la planche est là */
}

/* Écran non carré (16:9) : zone carrée centrée, à pleine hauteur, qui joue
   le rôle de la case d'origine (même échelle que dans la galerie) */
.om-sprite-cell {
  position: relative;
  height: 100%;
  aspect-ratio: 1;
}

/* Fond « grille bleue » : un sol en perspective qui s'estompe vers l'horizon,
   même principe que les grilles qui séparent les sections */
.om-media--grid {
  background:
    radial-gradient(ellipse at 50% 100%, rgb(61 125 255 / 0.28), transparent 65%),
    #0c0626;
}

.om-media--grid::before {
  content: "";
  inset: auto -50% 0;
  width: auto;          /* annule le cartouche d'attente (.om-media::before) */
  height: 62%;
  aspect-ratio: auto;
  translate: none;
  filter: none;
  padding: 0;
  background:
    linear-gradient(rgb(110 170 255) 0 0) top / 100% 2px no-repeat,
    repeating-linear-gradient(90deg, rgb(61 125 255 / 0.75) 0 2px, transparent 2px 56px),
    repeating-linear-gradient(rgb(61 125 255 / 0.75) 0 2px, transparent 2px 22px);
  transform: perspective(320px) rotateX(60deg);
  transform-origin: bottom;
  mask-image: linear-gradient(transparent, #000 45%);
  pointer-events: none;
}

/* Bouton façon jeu : dégradé du header, ombre nette, enfoncement au clic */
.om-button {
  padding: 0.7em 1.6em;
  border: 3px solid #fff;
  background: linear-gradient(#ffd07a, var(--om-magenta));
  box-shadow: 5px 5px 0 rgb(0 0 0 / 0.5);
  color: #fff;
  cursor: pointer;
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(1.1rem, 1.5vw, 1.4rem);
  font-weight: 700;
  text-shadow: 2px 2px 0 rgb(0 0 0 / 0.5);
  text-transform: uppercase;
  transition: translate 0.1s ease, box-shadow 0.1s ease, filter 0.15s ease;
}

.om-button:hover,
.om-button:focus-visible {
  translate: -2px -2px;
  box-shadow: 7px 7px 0 rgb(0 0 0 / 0.5);
  filter: brightness(1.1);
  outline: none;
}

.om-button:active {
  translate: 3px 3px;
  box-shadow: 2px 2px 0 rgb(0 0 0 / 0.5);
}

/* --------------------------------------------------------------------------
   STAGE 01 — La Testa : showroom
   -------------------------------------------------------------------------- */

/* Pleine largeur, collée sous le header, de la hauteur de l'écran */
.om-showroom {
  display: flex;
  align-items: flex-end;
  max-width: none;
  height: calc(100svh - 2 * var(--om-frame-inset) - 2 * var(--om-frame-border));
  min-height: 32rem;
  margin: calc(-1 * var(--om-content-top)) calc(-1 * var(--gutter)) 0;
  overflow: hidden;
}

/* En attendant la vidéo : un coucher de soleil synthwave */
.om-showroom__media {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 68% 52%, #ffe169 0 8%, #ff8a5c 12%, rgb(230 29 185 / 0.6) 20%, transparent 34%),
    linear-gradient(#12002a, #3a0a5e 55%, #2a0050);
}

.om-showroom__media::before {
  content: "Vidéo à venir\A" attr(data-placeholder);
  position: absolute;
  top: 32%;
  left: 68%;
  translate: -50% -50%;
  color: rgb(255 255 255 / 0.6);
  font-size: 0.85rem;
  line-height: 1.6;
  text-align: center;
  white-space: pre;
}

.om-showroom__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Léger fondu depuis le coin bas-gauche, où se trouve le texte */
.om-showroom__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top right, rgb(10 0 25 / 0.92) 0%, rgb(10 0 25 / 0.55) 32%, transparent 62%);
}

.om-showroom__text {
  position: relative;
  z-index: 1;
  max-width: 36rem;
  padding: 0 var(--gutter) clamp(6.5rem, 15vh, 9rem);
}

.om-showroom .om-stage__tag {
  text-align: left;
}

/* Nom du modèle en Roustel, comme un monogramme de carrosserie */
.om-showroom__name {
  margin: 0 0 0.15em;
  color: #fff;
  font-family: "Roustel", var(--font-sans);
  font-size: clamp(4.5rem, 11vw, 10rem);
  font-weight: 400;
  line-height: 1.05;
  text-shadow:
    0 0 2px #fff,
    0 0 12px #ff8a5c,
    0 0 30px var(--om-magenta),
    0 0 60px rgb(230 29 185 / 0.6);
}

.om-showroom__pitch {
  margin: 0;
  color: var(--om-text);
  font-size: clamp(1.05rem, 1.3vw, 1.2rem);
  line-height: 1.6;
}

/* Fiche technique façon constructeur */
.om-specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 2rem;
  margin: 1.75rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid rgb(255 255 255 / 0.25);
}

.om-specs dt {
  color: var(--om-cyan);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.om-specs dd {
  margin: 0.3rem 0 0;
  color: #fff;
  font-size: 1.15rem;
}

.om-showroom__scroll {
  position: absolute;
  z-index: 1;
  bottom: 1.25rem;
  left: 50%;
  translate: -50% 0;
  color: #fff;
  font-family: "LCD2", var(--font-sans);
  font-size: 1.8rem;
  font-weight: 700;
  text-decoration: none;
  text-shadow: 2px 2px 0 rgb(0 0 0 / 0.5);
  animation: om-bob 1.6s ease-in-out infinite;
}

@keyframes om-bob {
  0%, 100% { translate: -50% 0; }
  50%      { translate: -50% 6px; }
}

/* --------------------------------------------------------------------------
   STAGE 02 — Gameplay : Clay et la Testa encadrent la vidéo
   -------------------------------------------------------------------------- */

/* Section un peu plus large que les autres, pour une vidéo plus grande */
#gameplay {
  max-width: 1440px;
}

.om-gameplay {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 3.4fr) minmax(0, 1fr);
  grid-template-areas: "clay video testa";
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2.5rem);
}

.om-gameplay__video         { grid-area: video; }
.om-gameplay__art--clay     { grid-area: clay; }
.om-gameplay__art--testa    { grid-area: testa; }

/* Personnage et voiture posés à côté de l'écran, sans cadre */
.om-gameplay__art {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 12rem;
  margin: 0;
}

.om-gameplay__art img {
  width: 100%;
  max-height: 26rem;
  object-fit: contain;
  filter: drop-shadow(6px 6px 0 rgb(0 0 0 / 0.5));
}

/* Clay : assis contre l'écran, le bras par-dessus la vidéo.
   L'image (1024 × 1024, personnage dans le coin bas-droit) est posée sur la
   zone de la vidéo et dimensionnée par rapport à elle : 119,6 % de sa largeur
   = taille d'origine pour une vidéo de 856 px. Pixels nets à l'agrandissement. */
.om-gameplay__art--clay {
  grid-area: video;
  align-self: stretch;
  z-index: 2;
  min-height: 0;
  pointer-events: none;
}

.om-gameplay__art--clay img {
  position: absolute;
  bottom: -1.5%;
  left: -91.5%;
  width: 119.6%;
  max-width: none; /* base.css limite les images à leur conteneur */
  max-height: none;
  image-rendering: pixelated;
}

/* La Testa : garée derrière l'écran, l'avant dépasse à droite.
   L'image (1960 × 1120, voiture au centre) est posée sur la zone de la
   vidéo, sous elle, et dimensionnée par rapport à elle (≈ 62 % de sa taille
   d'origine pour une vidéo de 855 px). Pixels nets à l'agrandissement. */
.om-gameplay__video {
  z-index: 1; /* devant la Testa */
}

.om-gameplay__art--testa {
  grid-area: video;
  align-self: stretch;
  z-index: 0;
  min-height: 0;
  pointer-events: none;
}

.om-gameplay__art--testa img {
  position: absolute;
  bottom: -12.5%;
  left: 36.7%;
  width: 141.5%;
  max-width: none; /* base.css limite les images à leur conteneur */
  max-height: none;
  image-rendering: pixelated;
}

/* Images pas encore déposées : retour dans leur colonne, de part et d'autre de la vidéo */
.om-gameplay__art--clay:has(img.is-missing) {
  grid-area: clay;
  align-self: center;
  min-height: 12rem;
}

.om-gameplay__art--testa:has(img.is-missing) {
  grid-area: testa;
  align-self: center;
  min-height: 12rem;
}

/* En attendant l'image : un emplacement en pointillés avec le nom du fichier */
.om-gameplay__art:has(img.is-missing) {
  border: 2px dashed rgb(255 255 255 / 0.35);
}

.om-gameplay__art:has(img.is-missing)::before {
  content: "Image à venir\A" attr(data-placeholder);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0.75rem;
  color: rgb(255 255 255 / 0.55);
  font-size: 0.8rem;
  line-height: 1.6;
  text-align: center;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   STAGE 03 — Le dash : liste des coups
   -------------------------------------------------------------------------- */

/* Liste des dashs à gauche, écran à droite, centrés l'un par rapport à l'autre */
.om-moves {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: 0.75rem clamp(1.5rem, 3vw, 3rem);
  align-items: center;
}

.om-moves__list {
  display: grid;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.om-moves__screen {
  grid-column: 2;
}

.om-moves__item {
  display: flex;
  align-items: center;
  gap: 0.6em;
  width: 100%;
  padding: 0.42em 0.8em;
  border: 0;
  background: none;
  color: rgb(255 255 255 / 0.55);
  cursor: pointer;
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(1rem, 1.5vw, 1.4rem);
  font-weight: 700;
  text-align: left;
  text-transform: uppercase;
  transition: color 0.15s ease;
}

/* Curseur : petit triangle pixel (le « > » de LCD2 ressemble à une parenthèse) */
.om-moves__item::before {
  content: "";
  flex: none;
  width: 0.5em;
  height: 0.7em;
  background: var(--om-yellow);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  filter: drop-shadow(2px 2px 0 rgb(0 0 0 / 0.5));
  opacity: 0;
}

.om-moves__item:hover,
.om-moves__item:focus-visible {
  color: #fff;
  outline: none;
}

.om-moves__item[aria-selected="true"] {
  background: linear-gradient(90deg, rgb(230 29 185 / 0.5), transparent);
  color: #fff;
  text-shadow: 2px 2px 0 rgb(0 0 0 / 0.5);
}

.om-moves__item[aria-selected="true"]::before {
  opacity: 1;
  animation: om-blink 0.9s steps(1) infinite;
}

@keyframes om-blink {
  50% { opacity: 0; }
}

/* --------------------------------------------------------------------------
   STAGE 04 — La ville : « Nouvelle run »
   -------------------------------------------------------------------------- */

.om-runs {
  display: grid;
  justify-items: center;
  gap: 1.75rem;
}

.om-runs__screen {
  width: 100%;
}

/* Image pas encore déposée (voir js/omnidash.js) : le message d'attente reste visible */
img.is-missing {
  visibility: hidden;
}

.om-runs__label {
  position: absolute;
  z-index: 2;
  bottom: 0.9rem;
  left: 1rem;
  margin: 0;
  padding: 0.35em 0.7em;
  border: 1px solid rgb(255 255 255 / 0.5);
  background: rgb(20 0 42 / 0.75);
  color: var(--om-cyan);
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(0.9rem, 1.3vw, 1.2rem);
  font-weight: 700;
  text-transform: uppercase;
}

/* Transition « glitch » entre deux runs */
.om-runs__screen.is-glitching {
  animation: om-glitch 0.45s steps(1);
}

@keyframes om-glitch {
  0%   { clip-path: inset(0); translate: 0; filter: none; }
  15%  { clip-path: inset(10% 0 55% 0); translate: -12px 0; filter: hue-rotate(90deg) saturate(2); }
  30%  { clip-path: inset(60% 0 8% 0); translate: 10px 0; filter: hue-rotate(-60deg); }
  45%  { clip-path: inset(30% 0 35% 0); translate: -6px 0; filter: brightness(1.8); }
  60%  { clip-path: inset(0 0 70% 0); translate: 8px 0; filter: hue-rotate(160deg); }
  75%  { clip-path: inset(45% 0 20% 0); translate: -3px 0; filter: none; }
  100% { clip-path: inset(0); translate: 0; filter: none; }
}

/* --------------------------------------------------------------------------
   STAGE 05 — Modélisation et animation
   -------------------------------------------------------------------------- */

.om-counter {
  margin-bottom: clamp(2.5rem, 6vh, 3.5rem);
  text-align: center;
}

.om-counter__value {
  margin: 0;
  color: var(--om-yellow);
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(5rem, 14vw, 11rem);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  line-height: 1;
  text-shadow:
    6px 6px 0 var(--om-red),
    0 0 30px rgb(255 225 105 / 0.45);
}

.om-counter.is-done .om-counter__value {
  animation: om-hud-pop 0.4s ease-out;
}

.om-counter__caption {
  margin: 0.5rem 0 0;
  color: var(--om-cyan);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.om-anims {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.om-anim {
  margin: 0;
}

.om-anim .om-media {
  aspect-ratio: 1;
}

.om-anim figcaption {
  margin-top: 0.7rem;
  color: #fff;
  font-family: "LCD2", var(--font-sans);
  font-size: clamp(0.95rem, 1.2vw, 1.15rem);
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   STAGE 06 — Interface juicy
   -------------------------------------------------------------------------- */

.om-ui {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
}

/* --------------------------------------------------------------------------
   Écran étroit
   -------------------------------------------------------------------------- */

@media (max-width: 860px) {
  /* La vidéo d'abord, Clay et la Testa côte à côte en dessous */
  .om-gameplay {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "video video"
      "clay  testa";
  }

  /* Clay reprend sa place sous la vidéo, recadré sur le personnage
     (zone visible de l'image : x 278 → 949, y 603 → 1024 sur 1024) */
  .om-gameplay__art--clay {
    grid-area: clay;
    display: block;
    place-items: normal; /* sinon l'image, plus large que le cadre, serait recentrée */
    overflow: hidden;
  }

  .om-gameplay__art--clay img {
    position: static;
    width: 152.6%;       /* 1024 / 671 : le personnage occupe toute la colonne */
    max-width: none;
    margin: -89.9% 0 0 -41.4%; /* décale les marges transparentes hors du cadre */
  }

  /* Idem pour la Testa (zone visible : x 407 → 1562, y 297 → 1034 sur 1960 × 1120) */
  .om-gameplay__art--testa {
    grid-area: testa;
    display: block;
    place-items: normal;
    overflow: hidden;
  }

  .om-gameplay__art--testa img {
    position: static;
    width: 169.7%;       /* 1960 / 1155 */
    margin: -25.7% 0 -7.4% -35.2%;
  }

  .om-moves {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }

  .om-moves__screen {
    grid-column: auto;
    grid-row: 1; /* l'écran d'abord : la liste est longue, l'animation reste visible */
  }

  .om-anims {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .om-ui,
  .om-specs {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --------------------------------------------------------------------------
   Moins d'animations
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .om-hud .om-hud__char,
  .om-hud.is-switching,
  .om-showroom__scroll,
  .om-moves__item[aria-selected="true"]::before,
  .om-runs__screen.is-glitching,
  .om-counter.is-done .om-counter__value {
    animation: none;
  }
}
