/* Interactive pilot character that follows the pointer.
   Paired with app/ui/pilotGaze.js.

   Markup:
     <div class="pilot-gaze" data-pilot-gaze>
       <div class="pilot-gaze-sprite" data-pilot-gaze-sprite></div>
     </div>

   Size it by setting --pilot-gaze-height on .pilot-gaze (or an ancestor).
   The width follows from the source frame ratio, so the original framing and
   centring are preserved at any size. */

.pilot-gaze {
  --pilot-gaze-height: min(70vh, 560px);
  /* source frames are 300x534 */
  --pilot-gaze-width: calc(var(--pilot-gaze-height) * 300 / 534);

  position: relative;
  width: var(--pilot-gaze-width);
  height: var(--pilot-gaze-height);
  margin-inline: auto;
  -webkit-user-select: none;
  user-select: none;
  animation: pilot-gaze-breathe 5s ease-in-out infinite;
  filter: drop-shadow(0 22px 30px rgba(20, 45, 80, 0.2));
}

.pilot-gaze-sprite {
  position: absolute;
  inset: 0;
  /* WebP med alfakanal: himmelsbakgrunden bakom piloten är borttagen, så han
     står fritt mot sidan. Källbilden är en JPG och kan inte ha genomskinlighet
     — bakgrunden är urklippt med flödesfyllning från varje rams kant.

     Bara den här WebP:en får nämnas med sökväg i koden. Bygget samlar ihop
     assets genom att leta sökvägar i källfilerna, så en JPG-sökväg i en
     kommentar skickade tidigare med 1,3 MB källbild till användarna.
     Källan hanteras av tools/cutout-pilot-sprite.py. */
  background-image: url('../assets/pilot-gaze-sprite.webp');
  background-repeat: no-repeat;
  /* background-size and background-position are driven from pilotGaze.js */
}

@keyframes pilot-gaze-breathe {
  0%,
  100% {
    transform: translateY(0) scale(1);
  }

  50% {
    transform: translateY(-0.35%) scale(1.004);
  }
}

/* The pointer tracking itself is disabled in JS under this preference; this
   also stops the idle breathing so the character is fully still. */
@media (prefers-reduced-motion: reduce) {
  .pilot-gaze {
    animation: none;
  }
}

/* ===== HÖRNPLACERING =====
   Fast i nedre vänstra hörnet, följer med i scrollen. Används på säljsidan och
   på appens skärmar fram till att ett scenario startar.

   pointer-events:none är inte kosmetik. Elementet ligger över sidan i nedre
   hörnet, och utan detta skulle det äta klick på det som råkar ligga under.
   Spårningen lyssnar på fönstret, inte på elementet, så den påverkas inte. */
.pilot-gaze--corner {
  position: fixed;
  left: 18px;
  bottom: 0;
  z-index: 40;
  margin-inline: 0;
  pointer-events: none;
  --pilot-gaze-height: min(34vh, 300px);
}

/* Figuren når ramens underkant i alla 49 ramar, så bottom:0 sätter honom kant i
   kant mot sidans nederkant utan glipa.
   Andningen lyfter honom ett par tiondels procent, och skuggan under följer med
   — båda skulle synas som en spalt mot kanten. */
.pilot-gaze--corner {
  animation: none;
  filter: none;
}

/* Små skärmar: figuren skulle täcka en betydande del av innehållet, och det
   finns ingen mus att följa. */
@media (max-width: 760px), (max-height: 560px) {
  .pilot-gaze--corner { display: none; }
}

/* I appen försvinner han när ett pass startat. setActiveScreen sätter
   data-active-screen på <body>, så regeln följer varje sätt att byta skärm —
   knappen "Starta träning", ett återupptaget pass eller en drill — utan att
   någon JS behöver komma ihåg att gömma honom.
   s-results tas med: den skärmen nås bara genom ett avslutat pass. */
body[data-active-screen="s-train"] .pilot-gaze--corner,
body[data-active-screen="s-drill"] .pilot-gaze--corner,
body[data-active-screen="s-results"] .pilot-gaze--corner {
  display: none;
}
