/* =========================================================================
   PIQSEL — Thème « Arcade 1985 »
   Tokens (couleurs, polices, tailles, effets) : css/tokens.css
   Documentation des composants : DESIGN.md

   Technique « bordure pixel » : 4 box-shadows décalées d'un gros pixel (--px) dessinent
   un cadre aux coins crénelés, sans image ni clip-path (les halos restent visibles).
   Les éléments encadrés réservent une marge de --px pour ne jamais déborder.
   ========================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  background: var(--c-bg);
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--c-bg);
  color: var(--c-text);
  font: 16px/1.55 var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

h1,
h2,
p {
  margin: 0;
}

button,
select,
input {
  font: inherit;
  color: inherit;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

:focus-visible {
  outline: 3px solid var(--c-cyan);
  outline-offset: calc(var(--px) + 3px);
}

::selection {
  background: var(--c-pink);
  color: var(--c-ink);
}

/* ======================================================================== */
/* Décor : ciel étoilé et sol quadrillé                                      */
/* ======================================================================== */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgb(139 92 246 / 0.22), transparent 70%),
    radial-gradient(ellipse 60% 30% at 50% 100%, rgb(255 45 149 / 0.16), transparent 70%),
    var(--c-bg);
}

.backdrop__stars,
.backdrop__stars::after {
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 2px;
  content: '';
}

.backdrop__stars {
  box-shadow: 40.3vw 22.9vh 0 0px #ff2d95, 59.7vw 18.7vh 0 1px #f5f5f5, 46vw 49.2vh 0 0px #ffe45c, 29.9vw 33.8vh 0 0px #ff2d95, 49.2vw 55.6vh 0 0px #ffe45c, 30.8vw 21.2vh 0 0px #ffe45c, 65.1vw 29vh 0 0px #ffe45c, 46.2vw 49.7vh 0 0px #00e5ff, 19.6vw 24.7vh 0 0px #f5f5f5, 94.1vw 32vh 0 0px #ff2d95, 96.3vw 29.2vh 0 1px #f5f5f5, 26.4vw 1.8vh 0 1px #f5f5f5, 15.7vw 29vh 0 0px #ffe45c, 26.8vw 16.3vh 0 0px #ffe45c, 29.7vw 7vh 0 0px #00e5ff, 6.1vw 58.3vh 0 0px #00e5ff, 14.2vw 50.5vh 0 0px #ff2d95, 69.4vw 10.4vh 0 0px #ffe45c, 4.6vw 7.1vh 0 0px #f5f5f5, 33.7vw 48.6vh 0 1px #ffe45c, 80.1vw 14vh 0 1px #00e5ff, 6.3vw 7.5vh 0 0px #ff2d95, 58.7vw 0.2vh 0 0px #00e5ff, 68.6vw 25vh 0 0px #ffe45c, 75.6vw 13.2vh 0 0px #ff2d95, 43.9vw 43.5vh 0 0px #f5f5f5, 26.7vw 13vh 0 0px #ffe45c, 82.4vw 30.2vh 0 0px #00e5ff, 98.5vw 39.7vh 0 0px #f5f5f5, 76vw 5.7vh 0 1px #f5f5f5, 80.2vw 33.4vh 0 0px #f5f5f5, 63.5vw 11.4vh 0 0px #f5f5f5, 58.6vw 3vh 0 0px #ff2d95, 74.6vw 10.8vh 0 0px #f5f5f5;
  opacity: 0.7;
}

/* Seconde couche d'étoiles : scintillement lent (opacité seule, composité). */
.backdrop__stars::after {
  box-shadow: 38.4vw 39.7vh 0 1px #ff2d95, 30.1vw 44.6vh 0 0px #ff2d95, 64.2vw 33.6vh 0 0px #f5f5f5, 25.1vw 48.8vh 0 0px #ffe45c, 60.6vw 53.5vh 0 0px #f5f5f5, 81.6vw 7vh 0 0px #00e5ff, 49.2vw 29.7vh 0 0px #ffe45c, 93.6vw 59vh 0 0px #00e5ff, 38vw 0.9vh 0 0px #ff2d95, 30.8vw 46.3vh 0 0px #f5f5f5, 93.6vw 34.7vh 0 0px #ffe45c, 80.2vw 32.8vh 0 0px #f5f5f5, 23.1vw 23.5vh 0 0px #f5f5f5, 72.2vw 11.4vh 0 0px #ff2d95, 34.8vw 4.1vh 0 0px #f5f5f5, 45vw 2.8vh 0 0px #f5f5f5, 12.6vw 45.6vh 0 1px #00e5ff, 78.3vw 48.3vh 0 0px #f5f5f5, 36.6vw 52.8vh 0 0px #f5f5f5, 72.1vw 29.2vh 0 0px #00e5ff, 24.8vw 39.4vh 0 0px #ffe45c, 16.1vw 39.5vh 0 0px #ff2d95, 96.9vw 37.5vh 0 0px #f5f5f5, 76.1vw 22.3vh 0 0px #ffe45c, 57.7vw 45.4vh 0 0px #f5f5f5, 14.7vw 39vh 0 0px #ff2d95;
  animation: twinkle 3.2s steps(2, end) infinite;
}

@keyframes twinkle {
  50% {
    opacity: 0.25;
  }
}

.backdrop__floor {
  position: absolute;
  left: -50%;
  right: -50%;
  bottom: 0;
  height: 34vh;
  perspective: 240px;
  perspective-origin: 50% 0%;
  -webkit-mask-image: linear-gradient(to top, #000 25%, transparent 95%);
  mask-image: linear-gradient(to top, #000 25%, transparent 95%);
  opacity: 0.5;
}

.backdrop__grid {
  position: absolute;
  inset: -60px 0 0 0;
  transform-origin: 50% 0%;
  transform: rotateX(58deg);
  background-image:
    linear-gradient(var(--c-pink) 2px, transparent 2px),
    linear-gradient(90deg, var(--c-violet) 2px, transparent 2px);
  background-size: 64px 64px;
  background-position: center top;
  will-change: transform;
  animation: grid-scroll 2.8s linear infinite;
}

@keyframes grid-scroll {
  to {
    transform: rotateX(58deg) translateY(64px);
  }
}

/* Aucune animation décorative pendant le calcul, l'animation des pixels ou l'export. */
body:is([data-state='preparing'], [data-state='playing'], [data-state='exporting'], .is-animating) .backdrop *,
body:is([data-state='preparing'], [data-state='playing'], [data-state='exporting'], .is-animating) .backdrop *::after {
  animation-play-state: paused;
}

/* ======================================================================== */
/* HUD                                                                       */
/* ======================================================================== */
.hud {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  padding: 14px clamp(14px, 4vw, 36px);
  font-family: var(--font-display);
  font-size: var(--fs-hud);
  letter-spacing: 0.08em;
  border-bottom: 2px solid #221f38;
  background: linear-gradient(rgb(16 16 28 / 0.9), rgb(16 16 28 / 0.6));
}

.hud__brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--c-text);
  text-decoration: none;
  font-size: 12px;
  justify-self: start;
}

.hud__mark {
  width: 22px;
  height: 22px;
}

.mk-pink {
  fill: var(--c-pink);
}
.mk-cyan {
  fill: var(--c-cyan);
}
.mk-violet {
  fill: var(--c-violet);
}
.mk-yellow {
  fill: var(--c-yellow);
}

.hud__score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  line-height: 1;
}

.hud__label {
  color: var(--c-pink);
  font-size: 9px;
}

.hud__value {
  color: var(--c-yellow);
  font-size: 13px;
  text-shadow: var(--glow-yellow);
  font-variant-numeric: tabular-nums;
}

.hud__btn {
  justify-self: end;
  padding: 8px 10px;
  border: 0;
  background: transparent;
  color: var(--c-cyan);
  font: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  box-shadow: inset 0 0 0 2px var(--c-cyan-shade);
}

.hud__btn:hover {
  box-shadow: inset 0 0 0 2px var(--c-cyan), var(--glow-cyan);
}

/* ======================================================================== */
/* Page et fronton (marquee)                                                 */
/* ======================================================================== */
.page {
  flex: 1;
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap);
}

.marquee {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: clamp(20px, 5vw, 44px) 0 clamp(4px, 2vw, 12px);
  text-align: center;
}

.logo {
  line-height: 0;
}

.logo__svg {
  width: min(560px, 90vw);
  height: auto;
  overflow: visible;
  filter: drop-shadow(0 0 10px rgb(255 45 149 / 0.45)) drop-shadow(0 0 2px rgb(255 228 92 / 0.4));
  animation: neon-flicker 1s 1.6s steps(1, end) 1 both;
}

.logo__face {
  fill: url(#logo-grad);
}

.logo__shadow {
  fill: #2a0f52;
}

/* Apparition : les pixels du logo tombent en place (délai --d calculé par pixel-art.js). */
.logo__px {
  animation: px-drop 0.62s var(--ease-bounce) both;
  animation-delay: var(--d, 0ms);
}

@keyframes px-drop {
  from {
    transform: translateY(-11px);
    opacity: 0;
  }
  35% {
    opacity: 1;
  }
}

/* Petit grésillement de néon, une seule fois, faible amplitude. */
@keyframes neon-flicker {
  0%,
  30%,
  60% {
    filter: drop-shadow(0 0 10px rgb(255 45 149 / 0.45)) drop-shadow(0 0 2px rgb(255 228 92 / 0.4));
  }
  15%,
  45% {
    filter: drop-shadow(0 0 4px rgb(255 45 149 / 0.25));
  }
}

.slogan {
  font-family: var(--font-display);
  font-size: clamp(8px, 2.3vw, 12px);
  letter-spacing: 0.18em;
  color: var(--c-cyan);
  text-shadow: var(--glow-cyan);
  animation: px-in 0.5s 1.4s var(--steps) backwards;
}

.caret {
  display: inline-block;
  width: 0.8em;
  height: 1em;
  margin-left: 0.4em;
  vertical-align: -0.1em;
  background: var(--c-cyan);
  animation: blink 1.1s steps(1, end) infinite;
}

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

.lede {
  max-width: 34rem;
  color: var(--c-muted);
  font-size: clamp(0.95rem, 2.4vw, 1.05rem);
}

/* ======================================================================== */
/* Borne : zone de jeu                                                       */
/* ======================================================================== */
.cabinet {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap);
  padding: clamp(4px, 2vw, 28px) 0 8px;
}

/* Grand écran : panneau de borne avec moulures néon latérales (« T-molding »). */
@media (min-width: 1120px) {
  .cabinet {
    padding: 32px 36px 36px;
    background: linear-gradient(180deg, rgb(29 27 48 / 0.7), rgb(16 16 28 / 0.35));
    box-shadow:
      inset 0 0 0 2px #26223e,
      inset 0 24px 40px -30px rgb(139 92 246 / 0.5);
  }

  .cabinet::before,
  .cabinet::after {
    content: '';
    position: absolute;
    top: 28px;
    bottom: 28px;
    width: 8px;
    background: linear-gradient(180deg, var(--c-pink), var(--c-violet) 50%, var(--c-cyan));
    box-shadow: 0 0 14px rgb(255 45 149 / 0.45);
    opacity: 0.75;
  }

  .cabinet::before {
    left: -16px;
  }

  .cabinet::after {
    right: -16px;
  }
}

.stage {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap);
}

/* Les états passent par l'attribut hidden : apparition « pixelisée » en 4 paliers
   (opacité + décalage uniquement : l'élément reste cliquable dès la première image,
   ce qu'un clip-path empêcherait). */
[data-show]:not([hidden]) {
  animation: px-in 0.36s var(--steps) backwards;
}

@keyframes px-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* ======================================================================== */
/* Zone d'import : « INSERT YOUR IMAGE »                                     */
/* ======================================================================== */
.dropzone {
  --bc: var(--c-cyan);
  position: relative;
  width: calc(100% - 2 * var(--px));
  max-width: 640px;
  min-height: 300px;
  margin: var(--px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 36px 22px;
  text-align: center;
  cursor: pointer;
  background:
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.025) 0 2px, transparent 2px 4px),
    radial-gradient(ellipse at 50% 30%, rgb(0 229 255 / 0.09), transparent 70%),
    var(--c-surface);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    0 0 28px -4px color-mix(in srgb, var(--bc) 55%, transparent);
  transition:
    box-shadow var(--t-base) var(--steps),
    transform var(--t-fast) var(--steps);
}

/* Fente d'insertion intérieure */
.dropzone::before {
  content: '';
  position: absolute;
  inset: 14px;
  border: 2px dashed color-mix(in srgb, var(--bc) 40%, transparent);
  pointer-events: none;
}

.dropzone:hover,
.dropzone:focus-within,
.dropzone.is-over {
  --bc: var(--c-pink);
}

.dropzone.is-over {
  transform: scale(1.015);
}

.dropzone input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.dropzone__icon {
  width: 92px;
  height: auto;
  margin-bottom: 6px;
  animation: bob 1.6s steps(1, end) infinite;
}

.dropzone:hover .dropzone__icon,
.dropzone.is-over .dropzone__icon {
  animation-duration: 0.6s;
}

/* Sprite à 2 images : le cadre « sautille » d'un pixel. */
@keyframes bob {
  50% {
    transform: translateY(-4px);
  }
}

.dropzone__title {
  font-family: var(--font-display);
  font-size: clamp(14px, 4vw, 22px);
  line-height: 1.4;
  color: var(--c-yellow);
  text-shadow:
    3px 3px 0 var(--c-pink-shade),
    var(--glow-yellow);
}

.dropzone__blink {
  font-family: var(--font-pixel);
  font-size: clamp(14px, 3.6vw, 17px);
  letter-spacing: 0.05em;
  color: var(--c-cyan);
  animation: soft-blink 1.6s steps(1, end) infinite;
}

/* Clignotement doux (jamais d'extinction complète, < 1 Hz). */
@keyframes soft-blink {
  50% {
    opacity: 0.35;
  }
}

.dropzone__hint {
  max-width: 30rem;
  color: var(--c-muted);
  font-size: 0.85rem;
}

/* ======================================================================== */
/* Aperçu « PLAYER 1 VS TARGET »                                            */
/* ======================================================================== */
.versus {
  width: 100%;
  max-width: 860px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(8px, 3vw, 28px);
}

.card {
  --bc: var(--c-violet);
  position: relative;
  min-width: 0;
  margin: var(--px);
  padding: 22px 12px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  background: var(--c-surface);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc);
}

.card img {
  display: block;
  max-width: 100%;
  max-height: min(40vh, 320px);
  object-fit: contain;
  background: var(--c-ink);
  box-shadow: 0 0 0 2px var(--c-ink);
}

.card figcaption {
  font-family: var(--font-pixel);
  font-size: 0.95rem;
  color: var(--c-muted);
  text-align: center;
  overflow-wrap: anywhere;
}

.card__tag {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 8px;
  font-family: var(--font-display);
  font-size: 9px;
  white-space: nowrap;
  color: var(--c-ink);
  box-shadow: 0 0 0 2px var(--c-ink);
}

.card__tag--p1 {
  background: var(--c-yellow);
}

.card__tag--target {
  background: var(--c-cyan);
}

.versus__vs {
  font-family: var(--font-display);
  font-size: clamp(16px, 4.6vw, 30px);
  color: var(--c-yellow);
  text-shadow:
    3px 3px 0 var(--c-pink),
    6px 6px 0 var(--c-violet);
  animation: vs-pop 0.5s 0.15s var(--ease-bounce) backwards;
}

@keyframes vs-pop {
  from {
    transform: scale(2.4);
    opacity: 0;
  }
}

/* ======================================================================== */
/* Écran CRT                                                                 */
/* ======================================================================== */
.crt {
  position: relative;
  width: 100%;
  padding: var(--crt-bezel) var(--crt-bezel) 0;
  border-radius: calc(var(--crt-radius) + 12px);
  background: linear-gradient(180deg, #2c2945 0%, #1b1930 55%, #131120 100%);
  box-shadow:
    inset 0 2px 0 rgb(255 255 255 / 0.1),
    inset 0 -3px 0 rgb(0 0 0 / 0.5),
    0 0 0 3px var(--c-ink),
    0 26px 60px -20px rgb(0 0 0 / 0.85),
    0 0 50px -12px rgb(139 92 246 / 0.45);
}

.crt__screen {
  position: relative;
  height: min(64vh, 640px);
  min-height: 260px;
  border-radius: var(--crt-radius);
  overflow: hidden;
  background: #080810;
  box-shadow:
    0 0 0 3px var(--c-ink),
    0 0 0 6px #3a3658;
}

.crt__screen canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* Effets CRT : couche statique au-dessus du canvas (aucun impact sur le rendu ni l'export). */
.crt__fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(155deg, rgb(255 255 255 / 0.07) 0%, rgb(255 255 255 / 0.02) 22%, transparent 34%),
    radial-gradient(ellipse 75% 70% at 50% 50%, transparent 62%, rgb(0 0 0 / var(--crt-vignette)) 100%),
    repeating-linear-gradient(
      0deg,
      rgb(0 0 0 / var(--crt-scanline-opacity)) 0 1px,
      transparent 1px var(--crt-scanline-size)
    );
  box-shadow: inset 0 0 40px rgb(0 0 0 / 0.55);
}

/* Mise sous tension : un trait lumineux s'ouvre à chaque apparition de l'écran. */
.crt__fx::after {
  content: '';
  position: absolute;
  inset: 0;
  background: #e8fbff;
  opacity: 0;
  animation: crt-on 0.55s ease-out 1 backwards;
}

@keyframes crt-on {
  0% {
    opacity: 0.9;
    transform: scale(0.15, 0.006);
  }
  40% {
    opacity: 0.8;
    transform: scale(1, 0.006);
  }
  75% {
    opacity: 0.25;
    transform: scale(1, 1);
  }
  100% {
    opacity: 0;
    transform: scale(1, 1);
  }
}

body.crt-off .crt__fx {
  display: none;
}

.crt__chin {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 4px;
  font-family: var(--font-display);
  font-size: 8px;
  color: var(--c-muted);
  letter-spacing: 0.12em;
}

.crt__led {
  width: 8px;
  height: 8px;
  background: var(--c-pink);
  box-shadow: var(--glow-pink);
}

body:is([data-state='preparing'], [data-state='exporting']) .crt__led {
  background: var(--c-yellow);
  box-shadow: var(--glow-yellow);
  animation: blink 0.9s steps(1, end) infinite;
}

.crt__brand {
  flex: 1;
}

.crt__toggle {
  min-height: 32px;
  padding: 0 10px;
  border: 0;
  background: var(--c-ink);
  color: var(--c-cyan);
  font: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  box-shadow: inset 0 0 0 2px var(--c-cyan-shade);
}

.crt__toggle[aria-pressed='false'] {
  color: var(--c-muted);
  box-shadow: inset 0 0 0 2px #3a3658;
}

/* Voile de préparation */
.viewer__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 20px;
  text-align: center;
  background:
    repeating-linear-gradient(0deg, rgb(255 255 255 / 0.02) 0 2px, transparent 2px 4px),
    rgb(8 8 16 / 0.92);
}

.viewer__loading {
  font-family: var(--font-display);
  font-size: clamp(12px, 3.4vw, 18px);
  color: var(--c-yellow);
  text-shadow: 3px 3px 0 var(--c-pink-shade);
  letter-spacing: 0.1em;
}

.viewer__label {
  font-family: var(--font-pixel);
  font-size: 1rem;
  color: var(--c-muted);
}

.dots::after {
  content: '...';
  display: inline-block;
  width: 0;
  overflow: hidden;
  vertical-align: bottom;
  animation: dots 1.4s steps(4, end) infinite;
}

@keyframes dots {
  to {
    width: 4ch;
  }
}

/* Spinner 8 cases (style chargement 8-bit). */
.px-spinner {
  display: grid;
  grid-template-columns: repeat(3, 10px);
  grid-template-rows: repeat(3, 10px);
  gap: 4px;
}

.px-spinner i {
  background: var(--c-cyan);
  opacity: 0.2;
  animation: px-spin 0.96s steps(1, end) infinite;
}

.px-spinner i:nth-child(1) { grid-area: 1 / 1; animation-delay: 0s; }
.px-spinner i:nth-child(2) { grid-area: 1 / 2; animation-delay: 0.12s; }
.px-spinner i:nth-child(3) { grid-area: 1 / 3; animation-delay: 0.24s; }
.px-spinner i:nth-child(4) { grid-area: 2 / 3; animation-delay: 0.36s; }
.px-spinner i:nth-child(5) { grid-area: 3 / 3; animation-delay: 0.48s; }
.px-spinner i:nth-child(6) { grid-area: 3 / 2; animation-delay: 0.6s; }
.px-spinner i:nth-child(7) { grid-area: 3 / 1; animation-delay: 0.72s; }
.px-spinner i:nth-child(8) { grid-area: 2 / 1; animation-delay: 0.84s; }

@keyframes px-spin {
  0%,
  24% {
    opacity: 1;
    background: var(--c-pink);
  }
  25% {
    opacity: 0.2;
  }
}

/* ======================================================================== */
/* Barres de progression 8-bit (segments, avancée par paliers)               */
/* ======================================================================== */
.bar {
  --bc: var(--c-violet);
  width: min(320px, calc(100% - 2 * var(--px)));
  height: 20px;
  margin: var(--px);
  padding: 3px;
  background: var(--c-ink);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc);
}

.bar--wide {
  width: calc(100% - 2 * var(--px));
}

.bar > span {
  --p: 0;
  display: block;
  height: 100%;
  width: calc(var(--p) * 100%);
  background: repeating-linear-gradient(90deg, var(--c-yellow) 0 8px, transparent 8px 11px);
  box-shadow: 0 0 8px rgb(255 228 92 / 0.35);
  transition: width var(--t-base) steps(3, end);
}

@supports (width: round(down, 50%, 11px)) {
  .bar > span {
    width: round(down, calc(var(--p) * 100%), 11px);
  }
}

/* ======================================================================== */
/* Boutons « physiques »                                                     */
/* ======================================================================== */
.btn {
  --bc: #3d3960;
  --face: var(--c-surface-2);
  --shade: #141222;
  --fg: var(--c-text);
  --lift: var(--depth);
  --halo: 0 0 0 transparent;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  margin: var(--px) var(--px) calc(var(--px) + var(--depth));
  padding: 6px 18px;
  border: 0;
  background: var(--face);
  color: var(--fg);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: var(--fs-btn);
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  box-shadow:
    inset 0 calc(-1 * var(--px)) 0 0 var(--shade),
    inset 0 var(--px) 0 0 rgb(255 255 255 / 0.16),
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    0 calc(var(--px) + var(--lift)) 0 0 var(--shade),
    var(--halo);
  transition:
    transform var(--t-fast) steps(2, end),
    box-shadow var(--t-fast) steps(2, end),
    filter var(--t-fast);
}

.btn:not(:disabled):hover {
  filter: brightness(1.12);
}

/* Enfoncement : le bouton descend de toute sa profondeur. */
.btn:not(:disabled):active {
  --lift: 0px;
  transform: translateY(var(--depth));
  filter: brightness(0.95);
}

.btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.btn--sm {
  min-height: 40px;
  padding: 4px 14px;
  font-size: 15px;
}

.btn--cyan {
  --bc: var(--c-ink);
  --face: #123842;
  --shade: #0a1f26;
  --fg: var(--c-cyan);
}

.btn--cyan:not(:disabled):hover {
  --halo: 0 0 18px rgb(0 229 255 / 0.35);
}

.btn--ghost:not(:disabled):hover {
  --bc: var(--c-muted);
}

/* Bouton de borne d'arcade : rose néon, relief, halo pulsé. */
.btn--arcade {
  --bc: var(--c-ink);
  --face: linear-gradient(180deg, var(--c-pink-light) 0%, var(--c-pink) 45%, #e0157c 100%);
  --shade: var(--c-pink-shade);
  --fg: var(--c-ink);
  --halo: 0 0 26px rgb(255 45 149 / 0.45);
  min-height: 66px;
  padding: 8px 28px;
  font-size: clamp(17px, 4vw, 21px);
}

/* « START TRANSFORMATION » : seul bouton en Press Start 2P (libellé sans accent). */
#launch-btn {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-btn-display);
  letter-spacing: 0.04em;
  line-height: 1.5;
}

.btn--md {
  min-height: 54px;
  font-size: var(--fs-btn);
}

.btn--arcade::before {
  content: '▶';
  animation: soft-blink 1.2s steps(1, end) infinite;
}

/* Halo pulsé sur un pseudo-élément (opacité seule : composité, sans repeinture). */
.btn--arcade::after {
  content: '';
  position: absolute;
  inset: calc(-1 * var(--px));
  box-shadow: 0 0 30px 6px rgb(255 45 149 / 0.55);
  opacity: 0;
  pointer-events: none;
  animation: halo 2.4s ease-in-out infinite;
}

.btn--arcade:disabled::before,
.btn--arcade:disabled::after {
  animation: none;
}

@keyframes halo {
  50% {
    opacity: 1;
  }
}

.btn--arcade:not(:disabled):hover {
  --halo: 0 0 34px rgb(255 45 149 / 0.7);
}

.link-btn {
  background: none;
  border: 0;
  padding: 6px 4px;
  color: var(--c-muted);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  font: 0.85rem var(--font-pixel);
}

.link-btn:hover {
  color: var(--c-cyan);
}

/* ======================================================================== */
/* Panneau de commande                                                       */
/* ======================================================================== */
.panel {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.options {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  justify-content: center;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.14em;
  color: var(--c-cyan);
}

.field--inline {
  flex-direction: row;
  align-items: center;
  gap: 12px;
}

.field select {
  min-height: 44px;
  margin: 3px;
  padding: 0 38px 0 12px;
  border: 0;
  border-radius: 0;
  appearance: none;
  background: var(--c-ink)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 3' shape-rendering='crispEdges'%3E%3Cpath d='M0 0h5v1H0zM1 1h3v1H1zM2 2h1v1H2z' fill='%2300e5ff'/%3E%3C/svg%3E")
    no-repeat right 12px center / 12px 8px;
  box-shadow: 0 0 0 3px var(--c-cyan-shade);
  color: var(--c-text);
  font: 1.05rem var(--font-pixel);
  letter-spacing: 0.02em;
  cursor: pointer;
}

.field select:hover {
  box-shadow: 0 0 0 3px var(--c-cyan), var(--glow-cyan);
}

/* ======================================================================== */
/* Lecteur : panneau de contrôle                                             */
/* ======================================================================== */
.player {
  --bc: var(--c-violet);
  width: calc(100% - 2 * var(--px));
  margin: var(--px);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  background: var(--c-surface);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc);
}

.player .btn {
  margin-bottom: calc(var(--px) + var(--depth));
}

/* Bouton rond de borne */
.joy-btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 30%, #fff8c8 0%, var(--c-yellow) 42%, #d8bd2c 100%);
  box-shadow:
    0 0 0 3px var(--c-ink),
    0 5px 0 3px #6b5b0c,
    var(--glow-yellow);
  cursor: pointer;
  transition: transform var(--t-fast) steps(2, end), box-shadow var(--t-fast) steps(2, end);
  -webkit-tap-highlight-color: transparent;
}

.joy-btn:active {
  transform: translateY(4px);
  box-shadow:
    0 0 0 3px var(--c-ink),
    0 1px 0 3px #6b5b0c;
}

.joy-btn svg {
  width: 18px;
  height: 18px;
  fill: var(--c-ink);
}

#play-btn .i-play {
  display: none;
}

#play-btn.is-paused .i-play {
  display: block;
}

#play-btn.is-paused .i-pause {
  display: none;
}

/* Curseur de progression pixel */
#scrub {
  --v: 0;
  flex: 1;
  min-width: 0;
  height: 34px;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}

#scrub::-webkit-slider-runnable-track {
  height: 12px;
  background: linear-gradient(90deg, var(--c-pink) calc(var(--v) * 100%), var(--c-ink) 0);
  box-shadow: 0 0 0 2px var(--c-violet);
}

#scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 26px;
  margin-top: -7px;
  border: 0;
  border-radius: 0;
  background: var(--c-yellow);
  box-shadow:
    0 0 0 3px var(--c-ink),
    var(--glow-yellow);
}

#scrub::-moz-range-track {
  height: 12px;
  background: var(--c-ink);
  box-shadow: 0 0 0 2px var(--c-violet);
}

#scrub::-moz-range-progress {
  height: 12px;
  background: var(--c-pink);
}

#scrub::-moz-range-thumb {
  width: 14px;
  height: 26px;
  border: 0;
  border-radius: 0;
  background: var(--c-yellow);
  box-shadow: 0 0 0 3px var(--c-ink);
}

.player__time {
  min-width: 6.5ch;
  font-family: var(--font-display);
  font-size: 10px;
  color: var(--c-yellow);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ======================================================================== */
/* Écran de victoire + export                                                */
/* ======================================================================== */
.victory {
  --bc: var(--c-yellow);
  width: calc(100% - 2 * var(--px));
  margin: var(--px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 26px 18px 22px;
  text-align: center;
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgb(255 228 92 / 0.12), transparent 70%),
    var(--c-surface);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    0 0 40px -10px rgb(255 228 92 / 0.45);
}

.victory__head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 3vw, 22px);
}

.victory__title {
  font-family: var(--font-display);
  font-size: var(--fs-title);
  line-height: 1.6;
  font-weight: 400;
  background: linear-gradient(180deg, #fff7b8 0%, var(--c-yellow) 40%, var(--c-pink) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(3px 3px 0 #3b1670);
  /* « Stage clear » : 3 clignotements à 2,5 Hz, une seule fois. */
  animation: stage-clear 1.2s 0.2s steps(1, end) backwards;
}

@keyframes stage-clear {
  0%,
  33%,
  66% {
    opacity: 0;
  }
  16%,
  50%,
  83% {
    opacity: 1;
  }
}

.victory__star {
  flex: none;
  width: clamp(18px, 4vw, 30px);
  height: auto;
  filter: drop-shadow(0 0 6px rgb(255 228 92 / 0.6));
  animation: bob 1.4s steps(1, end) infinite;
}

.victory__star:last-child {
  animation-delay: 0.7s;
}

.victory__stats {
  font-family: var(--font-pixel);
  font-size: 1rem;
  color: var(--c-muted);
}

.victory__body,
.victory__progress {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.victory__actions {
  width: 100%;
  max-width: 720px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 14px;
}

.victory__actions .btn {
  width: calc(100% - 2 * var(--px));
}

.victory__progress .bar {
  max-width: 520px;
}

/* ======================================================================== */
/* Notices, toast                                                            */
/* ======================================================================== */
.notice {
  --bc: var(--c-danger);
  width: calc(100% - 2 * var(--px));
  max-width: 640px;
  margin: var(--px);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 12px 10px 14px;
  background: rgb(255 77 109 / 0.12);
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc);
  animation: shake 0.3s steps(3, end) 1;
}

.notice p {
  flex: 1;
}

.notice .btn {
  margin-bottom: calc(var(--px) + var(--depth));
}

.notice__tag {
  flex: none;
  padding: 5px 6px;
  font-family: var(--font-display);
  font-size: 9px;
  background: var(--c-danger);
  color: var(--c-ink);
}

@keyframes shake {
  33% {
    transform: translateX(-4px);
  }
  66% {
    transform: translateX(4px);
  }
}

.toast {
  --bc: var(--c-cyan);
  position: fixed;
  left: 50%;
  bottom: calc(22px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100% - 40px);
  padding: 12px 18px;
  background: var(--c-surface);
  font: 1rem/1.4 var(--font-pixel);
  text-align: center;
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    0 12px 30px rgb(0 0 0 / 0.6);
  animation: px-in 0.3s var(--steps) backwards;
  z-index: 30;
  pointer-events: none; /* message de statut : ne doit jamais bloquer un bouton en dessous */
}

/* ======================================================================== */
/* Modales                                                                   */
/* ======================================================================== */
.modal {
  --bc: var(--c-pink);
  width: min(460px, calc(100% - 28px));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  background: var(--c-surface);
  color: var(--c-text);
  overflow: auto;
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    var(--glow-pink),
    0 30px 80px rgb(0 0 0 / 0.8);
}

#privacy-dialog {
  --bc: var(--c-cyan);
}

.modal[open] {
  animation: px-in 0.35s var(--steps) backwards;
}

.modal::backdrop {
  background:
    repeating-linear-gradient(0deg, rgb(0 0 0 / 0.25) 0 2px, transparent 2px 4px),
    rgb(6 6 14 / 0.8);
}

.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 14px 12px 18px;
  background: linear-gradient(90deg, rgb(255 45 149 / 0.18), transparent);
  border-bottom: 2px solid var(--c-ink);
}

.modal__head h2 {
  font-family: var(--font-display);
  font-size: clamp(10px, 3vw, 13px);
  font-weight: 400;
  line-height: 1.5;
  color: var(--c-yellow);
  text-shadow: 2px 2px 0 var(--c-pink-shade);
}

/* Bouton de fermeture : toujours visible, libellé explicite, cible ≥ 44 px. */
.modal__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  background: var(--c-ink);
  color: var(--c-text);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.1em;
  cursor: pointer;
  box-shadow: inset 0 0 0 2px var(--c-text);
}

.modal__close:hover {
  color: var(--c-cyan);
  box-shadow: inset 0 0 0 2px var(--c-cyan), var(--glow-cyan);
}

.modal__close svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}

.modal__tag {
  margin: 16px 20px 0;
  text-align: center;
}

.modal__tag span {
  display: inline-block;
  padding: 2px 8px;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.16em;
  background: var(--c-muted);
  color: var(--c-ink);
}

.modal__ad {
  margin: 10px 20px 0;
  min-height: 250px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--c-ink);
  box-shadow: 0 0 0 2px #3a3658;
}

.modal__note {
  margin: 10px 20px 0;
  font-size: 0.8rem;
  color: var(--c-muted);
  text-align: center;
}

.modal__foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 14px 20px 14px;
}

.modal__foot .btn {
  width: calc(100% - 2 * var(--px));
}

.ad-placeholder {
  width: 300px;
  max-width: 100%;
  height: 250px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background:
    repeating-conic-gradient(#1d1b30 0 25%, #16142a 0 50%) 0 0 / 20px 20px;
  color: var(--c-muted);
  font-family: var(--font-pixel);
}

.ad-placeholder__label {
  font-family: var(--font-display);
  font-size: 10px;
  color: var(--c-yellow);
  text-transform: uppercase;
}

.ad-placeholder__size,
.ad-placeholder__note {
  font-size: 0.9rem;
}

.prose {
  padding: 16px 20px 20px;
  color: var(--c-muted);
  display: grid;
  gap: 12px;
}

.prose strong {
  color: var(--c-text);
}

/* Libellés posés par le JavaScript : affichés en capitales pixel. */
[data-ad-cta],
#launch-btn {
  text-transform: uppercase;
}

/* ======================================================================== */
/* Consentement, pied de page                                                */
/* ======================================================================== */
.consent {
  --bc: var(--c-cyan);
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  padding: 16px;
  background: var(--c-surface);
  font-size: 0.9rem;
  box-shadow:
    0 calc(-1 * var(--px)) 0 0 var(--bc),
    0 var(--px) 0 0 var(--bc),
    calc(-1 * var(--px)) 0 0 0 var(--bc),
    var(--px) 0 0 0 var(--bc),
    0 20px 50px rgb(0 0 0 / 0.7);
  z-index: 40;
}

.consent p {
  flex: 1 1 260px;
}

.consent__actions {
  display: flex;
  gap: 10px;
}

.footer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  justify-content: center;
  align-items: center;
  padding: 30px 16px calc(28px + env(safe-area-inset-bottom));
  text-align: center;
}

.footer__line {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 2;
  letter-spacing: 0.1em;
  color: var(--c-muted);
}

/* ======================================================================== */
/* Mobile                                                                    */
/* ======================================================================== */
@media (max-width: 560px) {
  .hud {
    padding: 10px 12px;
    gap: 8px;
  }

  .hud__brand span {
    font-size: 10px;
  }

  .hud__value {
    font-size: 11px;
  }

  .dropzone {
    min-height: 250px;
    padding: 30px 16px;
  }

  .card {
    padding: 20px 6px 8px;
  }

  .card img {
    max-height: 28vh;
  }

  .card__tag {
    font-size: 7px;
    padding: 5px 5px;
  }

  .card figcaption {
    font-size: 0.8rem;
  }

  .crt__screen {
    height: min(58vh, 520px);
    min-height: 240px;
  }

  .crt__brand {
    font-size: 7px;
  }

  .options {
    width: 100%;
    gap: 10px;
  }

  .options {
    flex-direction: column;
  }

  .options .field {
    width: 100%;
  }

  .field select {
    width: calc(100% - 6px);
  }

  .panel .btn--arcade {
    width: calc(100% - 2 * var(--px));
  }

  .player {
    flex-wrap: wrap;
  }

  .player #scrub {
    flex-basis: calc(100% - 140px);
  }

  .player #replay-btn {
    width: calc(100% - 2 * var(--px));
  }

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

  .field--inline {
    flex-direction: column;
  }
}

/* ======================================================================== */
/* Accessibilité : réduction des animations                                  */
/* ======================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }

  .backdrop__grid,
  .backdrop__stars::after,
  .crt__fx::after,
  .btn--arcade::after {
    animation: none !important;
  }
}
