:root {
  /* % plutôt que dvh/svh : plus fiable en iframe (le jeu est aussi intégré ainsi
     sur nilsou.fr), où dvh/svh peuvent se calculer contre le mauvais viewport
     tant que l'iframe elle-même n'a pas une hauteur définie côté page hôte. */
  --webcam-pip-size: 30%; /* largeur du médaillon caméra, hauteur déduite via aspect-ratio */
  /* Accent retuné (Phase 3, dépend de la Phase 1) pour s'accorder avec le nouveau décor :
     orange chaud proche du bec de l'oiseau (0xf5a028 dans createBird), en complémentaire du
     dégradé de ciel bleu (SKY_TOP/BOTTOM_COLOR dans game.js) plutôt que le rouge d'origine. */
  --accent: #f5a028;
  --sky-accent: #4a90d9; /* = SKY_TOP_COLOR, pour les touches qui doivent rester "ciel" */
}

* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: #0a0e14;
  font-family: "Segoe UI", system-ui, sans-serif;
}

#app {
  position: relative;
  width: 100%;
  height: 100%; /* cascade html/body height:100% — fonctionne quelle que soit la hauteur donnée à l'iframe */
}

/* ---------- jeu (plein écran) ---------- */

#game-pane {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #7fb3d5;
}

#game-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

#hud {
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  pointer-events: none;
  font-weight: 700;
  font-size: 1.1rem;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

#timer::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
  animation: blink 1s steps(1) infinite;
}

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

#timer.stopped::before {
  animation: none;
}

/* ---------- coupure du son ---------- */

#mute-toggle {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.95rem;
  background: rgba(255, 255, 255, 0.12);
  border: none;
  color: #fff;
  cursor: pointer;
  pointer-events: auto; /* seul élément interactif de #hud, qui est sinon pointer-events: none */
}

#mute-toggle.muted {
  opacity: 0.5;
}

/* ---------- pause ---------- */

#pause-toggle {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.95rem;
  background: rgba(255, 255, 255, 0.12);
  border: none;
  color: #fff;
  cursor: pointer;
  pointer-events: auto; /* cf. #mute-toggle : seuls éléments interactifs de #hud */
}

/* Au-dessus de #status-overlay (20), sous #start-screen (30)/#loading-screen (40) — les deux
   ne peuvent de toute façon pas être visibles en même temps qu'une pause (pause seulement
   pendant un run actif, cf. app.js#togglePause). Même pattern fade que #start-screen.hidden. */
#pause-overlay {
  position: absolute;
  inset: 0;
  z-index: 22;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 14, 20, 0.72);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

#pause-overlay.visible {
  opacity: 1;
  pointer-events: auto;
}

#pause-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  color: #fff;
  text-align: center;
}

#pause-panel h2 {
  margin: 0;
  font-size: 1.6rem;
}

#pause-resume-button {
  padding: 14px 40px;
  font-size: 1.2rem;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 999px;
  cursor: pointer;
}

/* ---------- toast bonus (pomme dorée / défi) ---------- */

#bonus-toast {
  position: absolute;
  top: 22%;
  left: 50%;
  transform: translate(-50%, -6px);
  padding: 8px 18px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: #ffd54a;
  font-weight: 700;
  font-size: 1.05rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

#bonus-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ---------- jauge d'altitude ---------- */

#altitude-gauge {
  position: absolute;
  left: max(14px, env(safe-area-inset-left));
  top: 50%;
  transform: translateY(-50%);
  width: 12px;
  height: 150px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  overflow: hidden;
  pointer-events: none;
  /* 3 bandes = les 3 bandes d'altitude utilisées par le spawn des pommes (basse/moyenne/
     haute, cf. Chunk#regenerate) ; approximatives (tiers égaux de ALTITUDE_MIN..MAX), pas
     un rendu exact des seuils réels (HEIGHT_MAX/BIRD_BASE_Y ne sont pas exportés). */
  background: linear-gradient(to top,
    rgba(63, 174, 92, 0.55) 0%, rgba(63, 174, 92, 0.55) 33%,
    rgba(143, 197, 232, 0.55) 33%, rgba(143, 197, 232, 0.55) 66%,
    rgba(255, 210, 100, 0.55) 66%, rgba(255, 210, 100, 0.55) 100%);
}

#altitude-marker {
  position: absolute;
  left: -3px;
  width: 18px;
  height: 4px;
  border-radius: 2px;
  background: #fff;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
  bottom: 0;
}

/* ---------- contrôle tactile : joystick virtuel (mobile/tablette uniquement) ---------- */
/* Masqué par défaut ; réaffiché seulement sur les appareils dont le pointeur principal est
   tactile (pas de hover, pointeur "coarse") — un desktop avec écran tactile + souris reste sur
   clavier/souris, un vrai mobile/tablette sans clavier récupère ce joystick. Même z-index que
   #webcam-pane (10) : les deux coexistent (joystick en bas-droite, webcam en bas-gauche — inversé
   par rapport au placement desktop du médaillon caméra, cf. plus bas, pour laisser le pouce droit
   sur le joystick), sous #status-overlay/#start-screen/#pause-overlay/#loading-screen qui doivent
   rester cliquables par-dessus. */
#touch-controls {
  display: none;
}

@media (hover: none) and (pointer: coarse) {
  #touch-controls {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 10;
    pointer-events: none;
  }

}

#touch-joystick {
  position: absolute;
  left: max(14px, env(safe-area-inset-left));
  bottom: max(14px, env(safe-area-inset-bottom));
  pointer-events: auto;
}

/* Le pouce fait glisser #joystick-knob depuis le centre de #joystick-base ; app.js#bindJoystick
   pilote le transform directement (suivi 1:1, pas de lag) et retire .active au relâchement,
   ce qui réactive la transition ci-dessous pour un retour au centre amorti plutôt qu'un saut. */
#joystick-base {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.45);
  background: rgba(0, 0, 0, 0.3);
  position: relative;
  touch-action: none; /* empêche le scroll/zoom au toucher, le joystick pilote le jeu, pas la page */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

#joystick-base.active {
  border-color: rgba(255, 255, 255, 0.75);
}

#joystick-knob {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
  border: 2px solid rgba(255, 255, 255, 0.75);
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none; /* le drag est géré par #joystick-base (setPointerCapture) */
  transition: transform 0.15s ease-out;
}

#joystick-base.active #joystick-knob {
  background: rgba(255, 255, 255, 0.65);
  transition: none; /* suivi 1:1 du doigt pendant le drag, sans lissage ni lag perceptible */
}

/* ---------- médaillon webcam (flottant, coin bas-droit) ---------- */

#webcam-pane {
  position: absolute;
  right: max(12px, env(safe-area-inset-right));
  bottom: max(12px, env(safe-area-inset-bottom));
  width: var(--webcam-pip-size);
  max-width: 160px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 14px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45);
  background: #000;
  z-index: 10; /* au-dessus du jeu (défaut 0), sous le statut (20) et l'écran de démarrage (30) */
}

#webcam-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
}

#skeleton-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Caméra/pose indisponibles : le jeu reste jouable au clavier, le médaillon disparaît */
#app.no-camera #webcam-pane {
  display: none;
}

/* Sur device tactile, joystick à droite (pouce droit) et médaillon caméra renvoyé à gauche —
   doit être déclaré APRÈS les règles #touch-joystick/#webcam-pane non conditionnelles ci-dessus
   pour gagner la cascade à spécificité égale (sinon leur `left`/`right` explicite regagne). Le
   placement desktop des deux (joystick alors invisible de toute façon, webcam bas-droit) est
   inchangé. */
@media (hover: none) and (pointer: coarse) {
  #touch-joystick {
    left: auto;
    right: max(14px, env(safe-area-inset-right));
  }

  #webcam-pane {
    right: auto;
    left: max(12px, env(safe-area-inset-left));
  }
}

/* ---------- statut / chargement ---------- */

#status-overlay {
  position: absolute;
  bottom: max(16px, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  padding: 8px 16px;
  border-radius: 20px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.85rem;
  z-index: 20;
  transition: opacity 0.5s;
}

/* #status-overlay (statut caméra/pose, cf. app.js#setStatus) est habituellement collé en
   bas de l'écran — sur un device tactile, ce coin est maintenant occupé par #touch-joystick, et
   un message comme "Caméra indisponible" s'y superposait au joystick. Remonté juste sous le
   HUD (dont l'icône la plus haute fait 26px + le top offset) à la place.
   Doit être déclaré APRÈS la règle #status-overlay non conditionnelle ci-dessus pour gagner
   la cascade à spécificité égale (même piège que #touch-joystick/#webcam-pane plus haut : sinon
   le `bottom` de la règle de base, plus tardive dans le fichier, regagne malgré le `bottom: auto`
   ici, et l'élément se retrouve avec `top` ET `bottom` fixés à la fois, donc étiré sur toute la
   hauteur entre les deux au lieu de s'ajuster à son contenu). */
@media (hover: none) and (pointer: coarse) {
  #status-overlay {
    bottom: auto;
    top: calc(max(12px, env(safe-area-inset-top)) + 46px);
  }
}

/* ---------- écran de chargement (modèle 3D) ---------- */
/* Au-dessus de #start-screen (z-index 30) : reprend le dégradé de ciel du jeu (SKY_TOP/
   BOTTOM_COLOR dans game.js) plutôt que le fond sombre du start-screen, pour que la première
   chose vue ressemble déjà au jeu plutôt qu'à un splash générique. Masqué par opacité/scale
   (même pattern que #start-screen.hidden) une fois game.init() résolu, cf. app.js. */

#loading-screen {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  overflow: hidden;
  background: linear-gradient(to bottom, #4a90d9 0%, #6fa8dd 45%, #8fc5e8 100%);
  color: #fff;
  text-align: center;
  padding: 24px;
  opacity: 1;
  transition: opacity 0.5s ease;
}

#loading-screen.hidden {
  opacity: 0;
  pointer-events: none;
}

.loading-cloud {
  position: absolute;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.55);
  filter: blur(1px);
  animation: loading-drift linear infinite;
}

.loading-cloud--a { width: 120px; height: 40px; top: 18%; left: -20%; animation-duration: 22s; }
.loading-cloud--b { width: 90px; height: 32px; top: 62%; left: -30%; animation-duration: 28s; animation-delay: -8s; opacity: 0.8; }
.loading-cloud--c { width: 70px; height: 26px; top: 40%; left: -15%; animation-duration: 18s; animation-delay: -4s; opacity: 0.7; }

@keyframes loading-drift {
  from { transform: translateX(0); }
  to { transform: translateX(140vw); }
}

#loading-bird {
  font-size: 3.4rem;
  line-height: 1;
  filter: drop-shadow(0 6px 10px rgba(10, 20, 30, 0.35));
  animation: loading-flap 0.9s ease-in-out infinite;
}

@keyframes loading-flap {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50% { transform: translateY(-14px) rotate(4deg); }
}

#loading-title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 700;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}

#loading-bar-track {
  width: min(240px, 70vw);
  height: 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.5);
  overflow: hidden;
}

#loading-bar-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.25s ease;
}

#loading-percent {
  margin-top: -8px;
  font-size: 0.85rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}

/* ---------- écran de démarrage ---------- */

#start-screen {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  background: rgba(10, 14, 20, 0.72);
  color: #fff;
  text-align: center;
  padding: 24px;
  opacity: 1;
  transform: scale(1);
  transition: opacity 0.35s ease, transform 0.35s ease;
}

/* Fade + léger scale plutôt qu'un display:none brut ; pointer-events coupe les clics une
   fois masqué (l'élément reste en position absolute, donc toujours dans le flux). */
#start-screen.hidden {
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
}

#start-title {
  margin: 0;
  font-size: 1.6rem;
}

#start-goal {
  margin: -10px 0 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: #e4e9f0;
}

#start-record {
  margin: -10px 0 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: #ffd54a;
}

#start-record:empty {
  display: none;
}

/* ---------- stats de fin de run (masquées tant qu'aucun run n'est terminé) ---------- */

#start-stats {
  display: none;
  gap: 22px;
  margin: -4px 0 0;
}

#start-stats.visible {
  display: flex;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.stat-icon {
  font-size: 1.1rem;
  line-height: 1;
}

.stat-value {
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.stat-label {
  font-size: 0.68rem;
  opacity: 0.75;
}

#start-button {
  padding: 14px 40px;
  font-size: 1.3rem;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 999px;
  cursor: pointer;
}

/* ---------- onboarding progressif (3 pictos, écran de démarrage) ---------- */

#onboarding-hints {
  display: flex;
  gap: 16px;
  max-width: 320px;
}

/* Masqués une fois qu'un run est terminé : la place est prise par #start-stats (Rejouer) */
#onboarding-hints.hidden {
  display: none;
}

.hint-picto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: 1;
  animation: hint-pulse 2.2s ease-in-out infinite;
}

.hint-picto:nth-child(2) { animation-delay: 0.25s; }
.hint-picto:nth-child(3) { animation-delay: 0.5s; }

.hint-icon {
  font-size: 1.6rem;
  line-height: 1;
}

.hint-label {
  font-size: 0.72rem;
  opacity: 0.85;
  line-height: 1.25;
}

@keyframes hint-pulse {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50% { transform: scale(1.12); opacity: 1; }
}
