/* ===================================================================
   Jakob & Cedric AIRLINES — Stylesheet
   -------------------------------------------------------------------
   Kurz-Einführung für Web-Anfänger:

   - Ein CSS-"Block" beginnt mit einem Selektor (z. B. #buehne oder
     .hotspot) und legt in { } fest, wie diese Elemente aussehen.
   - "#name"  spricht das Element mit id="name" an (nur einmal pro Seite).
   - ".name"  spricht alle Elemente mit class="name" an (beliebig oft).
   - position: absolute  =  das Element wird frei über seinem Elternteil
     platziert, mit Abstand von oben/links. Genau das brauchen wir für
     die unsichtbaren Klickflächen über dem Bild.
   - Werte in %  =  Prozent der Elterngröße. Dadurch sitzen die Hotspots
     immer richtig, egal wie groß das Fenster ist.
   =================================================================== */


/* --- 1. Farben und Grundwerte an einer Stelle -------------------- */
/* :root ist die ganze Seite. Variablen (--name) kann man unten mit
   var(--name) wiederverwenden — so muss man Farben nur hier ändern. */
:root {
  --farbe-hintergrund: #12233a;
  --farbe-text:        #ffffff;
  --farbe-akzent:      #ffd166;
  --farbe-gut:         #4ade80;
  --schrift:           system-ui, "Segoe UI", "Trebuchet MS", sans-serif;
  --radius:            14px;
}


/* --- 2. Grundgerüst --------------------------------------------- */

* {
  /* padding/border zählen zur Breite dazu — macht Layout viel einfacher */
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--farbe-hintergrund);
  font-family: var(--schrift);
  color: var(--farbe-text);

  /* Flexbox zentriert die Bühne waagerecht UND senkrecht im Fenster */
  display: flex;
  align-items: center;
  justify-content: center;

  /* Kinder tippen gern schnell doppelt — das verhindert das Rein-Zoomen */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}


/* Die "Bühne": der 16:9-Rahmen, in dem der ganze Rundgang stattfindet.
   aspect-ratio hält das Seitenverhältnis konstant, egal wie breit das
   Fenster ist. So passen die Prozent-Hotspots immer aufs Bild. */
#buehne {
  position: relative;          /* Bezugspunkt für alles mit position:absolute */
  width: 100vw;
  max-width: calc(100vh * 16 / 9);   /* nie höher als das Fenster */
  aspect-ratio: 16 / 9;
  overflow: hidden;            /* nichts ragt aus dem Rahmen heraus */
  background: #000;
  box-shadow: 0 0 60px rgba(0, 0, 0, 0.6);
}


/* --- 3. Szenen-Bild und Platzhalter ------------------------------ */

#szenen-bild {
  width: 100%;
  height: 100%;
  object-fit: cover;   /* füllt den Rahmen, schneidet notfalls Ränder ab */
  display: block;
  transition: opacity 0.22s ease;
}

/* Kurz ausblenden, während innerhalb einer Szene das Bild getauscht
   wird (Cockpit: Schalter umgelegt, Schub gegeben). Die Austauschbilder
   sind nie pixelgenau identisch — die Blende verdeckt das Zucken. */
#szenen-bild.bild-wechsel {
  opacity: 0;
}

/* Farbfläche mit Szenennamen, solange das PNG noch fehlt */
#platzhalter {
  position: absolute;
  inset: 0;                    /* Kurzform für top/right/bottom/left: 0 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  padding: 24px;

  font-size: clamp(22px, 4vw, 52px);   /* wächst mit der Fenstergröße mit */
  font-weight: 700;
  letter-spacing: 0.5px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

#platzhalter small {
  font-size: clamp(11px, 1.4vw, 16px);
  font-weight: 400;
  opacity: 0.85;
}

#platzhalter code {
  background: rgba(0, 0, 0, 0.25);
  padding: 1px 6px;
  border-radius: 6px;
}

/* Zusatz-Grafik im Platzhalter (z. B. die Passagiere in der Kabine) */
/* width: 100% ist wichtig! Ohne das bekommt dieser Container in der
   zentrierten Flexbox nur die Breite seines Inhalts — und der Inhalt
   ist auf 60 % des Containers gesetzt. Das ist ein Ringschluss und
   endet bei null, die Grafik wäre unsichtbar. */
#platzhalter-extra {
  width: 100%;
  display: flex;
  justify-content: center;
}

#platzhalter-extra:empty {
  display: none;
}

.platzhalter-svg {
  width: min(60%, 460px);
  height: auto;
  aspect-ratio: 180 / 100;   /* passt zur viewBox in passagiereSVG() */
  opacity: 0.9;
}

/* [hidden] blendet Elemente aus. Manche Browser brauchen das explizit. */
[hidden] {
  display: none !important;
}


/* --- 3b. Die Flugsequenz ----------------------------------------- */
/* Der Flug kommt ganz ohne Bilddatei aus: Himmel als Farbverlauf,
   Wolken und Landschaft als SVG, alles per CSS in Bewegung.          */

#flug-ebene {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* Der obere Farbwert ist am Himmel in flug-landschaft.png abgemessen
   (#10a8fc). Beim Steigflug sinkt das Panorama nach unten weg und gibt
   diesen Himmel frei — passten die Farben nicht zusammen, liefe eine
   sichtbare Kante durchs Bild. */
.himmel {
  position: absolute;
  inset: 0;
  background: linear-gradient(#10a8fc 0%, #74c4ec 55%, #c5e8f7 100%);
}

/* Wolken ziehen von rechts nach links vorbei — aber erst in
   Reiseflughöhe. Beim Start und beim Landeanflug ist man zu tief,
   dort gäbe es keine Wolken vor dem Fenster. Gilt genauso für die
   Cockpitsicht, siehe .vorn-wolken weiter unten. */
.wolken {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.6s ease;
}

#flug-ebene.phase-reise .wolken {
  opacity: 1;
}

.wolke {
  position: absolute;
  left: 100%;                  /* startet rechts außerhalb des Bildes */
  height: auto;
  opacity: 0.92;
  animation-name: wolke-zieht;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  /* animation-duration und -delay setzt main.js je Wolke einzeln */
}

/* Die Landschaft unter dem Flugzeug */
.boden {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42%;
  overflow: hidden;
}

/* Die Bildfassung bringt ihren eigenen Himmel und Horizont mit und
   braucht deshalb die volle Höhe — sonst säße der Horizont des Bildes
   im unteren Drittel und darüber käme ein zweiter Himmel.
   Beim Steigflug sinkt so das ganze Panorama weg und lässt den
   Himmel-Verlauf zurück, genau wie es sein soll. */
.boden-voll {
  height: 100%;
}

.boden-inhalt {
  /* doppelt so breit wie der Rahmen: eine Kopie schiebt sich nach,
     dadurch wirkt die Landschaft endlos */
  width: 200%;
  height: 100%;
  animation: boden-zieht 6s linear infinite;
}

/* Gezeichnete Landschaft aus images/flug-landschaft.png.
   Mehrere Kopien nebeneinander; wie viele, rechnet main.js aus dem
   Seitenverhältnis des Bildes aus und schreibt es in --kopien.
   Geschoben wird um 100 % / Kopienzahl — also um exakt eine
   Bildbreite. Dadurch ist der Übergang unsichtbar, egal welches
   Format das Bild hat. */
.boden-bild {
  width: max-content;
  display: flex;
  animation-name: boden-zieht-bild;
}

.boden-bild img {
  height: 100%;
  width: auto;               /* Seitenverhältnis bleibt erhalten */
  flex: none;
  display: block;
}

/* Phase 1 — Start: die Landschaft sinkt nach unten weg.
   Die Dauer kommt aus main.js (START_DAUER) über die Variable
   --start-dauer, damit Ton, Timer und Animation nicht auseinander
   laufen. Der Wert dahinter ist nur der Notfall-Rückfall. */
#flug-ebene.phase-start .boden {
  animation: boden-sinkt var(--start-dauer, 15s) ease-in forwards;
}

/* Phase 2 — Reiseflug: Boden ist verschwunden, nur noch Wolken */
#flug-ebene.phase-reise .boden {
  transform: translateY(115%);
}

/* Phase 3 — Landung: die Landschaft kommt wieder herauf.
   Dauer aus main.js (LANDE_DAUER) über --lande-dauer. */
#flug-ebene.phase-landung .boden {
  animation: boden-steigt var(--lande-dauer, 15s) ease-out forwards;
}

/* Im Reiseflug ziehen die Wolken schneller — wirkt wie mehr Tempo */
#flug-ebene.phase-reise .wolke {
  animation-duration: 6s;
}

/* --- 3d. Blick nach vorn aus dem Cockpit ------------------------- */
/*
   Beim Blick zur Seite (Kabine) zieht die Welt vorbei. Beim Blick nach
   VORN kommt sie einem entgegen — das ist keine seitliche Bewegung,
   sondern eine perspektivische. Deshalb wird hier eine echte Ebene in
   den Raum gekippt (rotateX) statt ein Bild zu scrollen.

   --horizont steuert, wie hoch der Horizont steht. Beim Steigflug
   wandert er nach unten (die Erde fällt weg), bei der Landung zurück.
*/

.vorn {
  position: absolute;
  inset: 0;
  overflow: hidden;
  --horizont: 33%;
}

/* Die gekippte Bodenebene. perspective + rotateX erzeugen die Flucht
   zum Horizont: unten breit und schnell, hinten schmal und langsam. */
.vorn-ebene {
  position: absolute;
  top: var(--horizont);
  left: 50%;
  width: 460%;
  height: 150%;
  transform: translateX(-50%) perspective(150px) rotateX(64deg);
  transform-origin: center top;
  transform-style: preserve-3d;
}

/* Gras, und mittig die Landebahn. Weil die ganze Ebene gekippt ist,
   wird aus dem geraden Streifen automatisch das Trapez der Bahn. */
.vorn-grund {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right,
      transparent 0 46.4%,
      #a8b2bb 46.4% 47%,
      #b9c3cc 47% 53%,
      #a8b2bb 53% 53.6%,
      transparent 53.6% 100%),
    linear-gradient(to bottom, #7cbf63, #8fce76 40%, #9dd67f);
}

/* Die Mittelstriche der Bahn. Sie laufen nach unten — das ist die
   eigentliche Bewegung nach vorn. Weil die Ebene gekippt ist, werden
   sie dabei von selbst größer und schneller, genau wie im Anflug. */
.vorn-striche {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(to bottom,
    #ffffff 0 45%, transparent 45% 100%);
  background-size: 1.5% 7%;
  background-position: center 0;
  background-repeat: repeat-y;
  animation: vorn-striche-laufen 0.75s linear infinite;
}

@keyframes vorn-striche-laufen {
  from { background-position: center 0; }
  to   { background-position: center 7%; }
}

/* Wolken kommen aus der Bildmitte auf einen zu: klein und blass in der
   Ferne, dann wachsend und nach außen ziehend. */
.vorn-wolken {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.vorn-wolke {
  position: absolute;
  left: 50%;
  top: 42%;
  width: 26%;
  animation-name: vorn-wolke-kommt;
  animation-timing-function: cubic-bezier(0.45, 0, 0.9, 0.55);
  animation-iteration-count: infinite;
}

.vorn-wolke svg {
  width: 100%;
  height: auto;
  display: block;
}

@keyframes vorn-wolke-kommt {
  0%   { transform: translate(-50%, -50%) scale(0.06); opacity: 0; }
  18%  { opacity: 0.95; }
  100% { transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y)))
                    scale(2.6);
         opacity: 0; }
}

/* Phase 1 — Start: der Horizont wandert nach unten, die Erde fällt
   weg. Gleichzeitig laufen die Bahnstriche schneller (Beschleunigung)
   und hören auf, sobald wir oben sind. */
#flug-ebene.phase-start.sicht-vorn .vorn {
  animation: vorn-steigt var(--start-dauer, 15s) ease-in forwards;
}

#flug-ebene.phase-start.sicht-vorn .vorn-striche {
  animation: vorn-striche-laufen 0.75s linear infinite,
             vorn-striche-bremsen var(--start-dauer, 15s) ease-in forwards;
}

/* Wolken gibt es nur in Reiseflughöhe.
   Beim Start und beim Landeanflug ist man tief, sieht den Boden und
   fliegt an keiner Wolke vorbei — dort wären sie schlicht falsch.
   Der Wechsel läuft über eine Transition, damit sie beim Erreichen
   der Reiseflughöhe sanft auftauchen statt aufzupoppen. */
.vorn-wolken {
  opacity: 0;
  transition: opacity 1.6s ease;
}

#flug-ebene.phase-reise.sicht-vorn .vorn-wolken {
  opacity: 1;
}

@keyframes vorn-steigt {
  0%   { --horizont: 33%; }
  100% { --horizont: 78%; }
}

/* Je höher wir kommen, desto ruhiger wirkt der Boden — deshalb wird
   die Strichanimation langsam ausgeblendet. */
@keyframes vorn-striche-bremsen {
  0%   { opacity: 1; }
  70%  { opacity: 0.5; }
  100% { opacity: 0; }
}

/* Phase 2 — Reiseflug: kein Boden mehr, nur noch Wolken. */
#flug-ebene.phase-reise.sicht-vorn .vorn-ebene {
  opacity: 0;
}

/* Phase 3 — Landung: der Horizont kommt zurück nach oben. */
#flug-ebene.phase-landung.sicht-vorn .vorn {
  animation: vorn-sinkt var(--lande-dauer, 15s) ease-out forwards;
}

#flug-ebene.phase-landung.sicht-vorn .vorn-ebene {
  animation: vorn-ebene-auf var(--lande-dauer, 15s) ease-out forwards;
}

@keyframes vorn-sinkt {
  0%   { --horizont: 78%; }
  100% { --horizont: 33%; }
}

@keyframes vorn-ebene-auf {
  0%   { opacity: 0; }
  35%  { opacity: 1; }
  100% { opacity: 1; }
}

/* Damit --horizont überhaupt animierbar ist, muss die Variable typisiert
   werden. Ohne @property springt sie nur zwischen Anfang und Ende. */
@property --horizont {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 33%;
}


/* Der Fensterrahmen (Cockpit oder Kabine) liegt über allem */
.rahmen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Die Instrumentenzeiger im Cockpit wackeln leicht.
   transform-box: fill-box ist hier entscheidend: ohne diese Zeile
   bezieht sich transform-origin bei SVG auf die ganze viewBox, und
   der Zeiger dreht dann um einen Punkt weit außerhalb seines
   Instruments statt um seinen eigenen Fußpunkt. */
.zeiger {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: zeiger-wackelt 3.5s ease-in-out infinite;
}

/* Kurzes Aufblitzen, wenn im Cockpit die Landelichter angehen */
.lichtblitz {
  position: absolute;
  inset: 0;
  background: #fffbe9;
  opacity: 0;
  animation: blitzen 0.85s ease-out;
}


/* --- 3c. Die Taxifahrt ------------------------------------------- */
/* Drei Schichten ziehen unterschiedlich schnell vorbei: ferne Hügel
   langsam, Häuser mittel, Straße schnell. Dieser Tiefeneindruck heißt
   Parallaxe. Alle drei benutzen dieselbe Animation, nur mit anderer
   Dauer.                                                             */

.fahrt-himmel {
  position: absolute;
  inset: 0;
  background: linear-gradient(#5bb8e8 0%, #a8dcf2 55%, #dcf0f7 100%);
}

.fahrt-schicht {
  position: absolute;
  left: 0;
  width: 200%;                 /* zwei gleiche Kopien nebeneinander */
  animation: schicht-zieht linear infinite;
}

.fahrt-schicht svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Tempo der Schichten. Seit die Fahrt 20 Sekunden dauert, sind die
   Werte gemächlicher: Vorher zog das Panorama viermal durch, jetzt
   knapp zweimal. Das Verhältnis zwischen den Schichten bleibt gleich —
   die Straße im Vordergrund läuft weiter rund doppelt so schnell wie
   der Hintergrund, sonst ginge der Tiefeneindruck verloren. */
.fahrt-huegel  { bottom: 30%; height: 26%; animation-duration: 30s; }
.fahrt-haeuser { bottom: 18%; height: 34%; animation-duration: 12s; }
.fahrt-strasse { bottom:  0;  height: 20%; animation-duration: 4.5s; }

/* Gezeichnetes Panorama statt Hügel + Häuser, sobald die Datei
   images/fahrt-panorama.png vorhanden ist.

   WICHTIG — warum hier zwei <img> statt eines gekachelten
   Hintergrundbildes: Die Animation schiebt IMMER um 50 % der
   Elementbreite. Nahtlos ist das nur, wenn diese 50 % exakt einer
   Bildbreite entsprechen. Mit `background-repeat` wäre die Kachel
   1,35 Bühnenbreiten breit, geschoben würde aber um genau eine —
   das ergäbe alle fünf Sekunden einen sichtbaren Sprung.

   Mit `width: max-content` ist das Element exakt so breit wie seine
   zwei Bilder. Damit sind 50 % genau ein Bild, und der Übergang
   stimmt bei jeder Fenstergröße. Dieselbe Technik benutzen auch die
   gezeichneten Schichten oben.                                      */
.fahrt-panorama {
  top: 0;
  height: 80%;
  width: max-content;        /* überschreibt die 200 % von oben */
  display: flex;
  animation-duration: 12s;   /* gemächlich, passend zur langen Fahrt */
}

.fahrt-panorama img {
  height: 100%;
  width: auto;               /* Seitenverhältnis 3:1 bleibt erhalten */
  flex: none;                /* nicht stauchen lassen */
  display: block;
}

/* Angekommen: das Taxi hält, alle Schichten bleiben stehen.
   animation-play-state: paused friert die Animation an Ort und Stelle
   ein — passend dazu läuft das Bremsgeräusch. */
#flug-ebene.fahrt.angekommen .fahrt-schicht {
  animation-play-state: paused;
}


/* --- 4. Hotspots (die unsichtbaren Klickflächen) ------------------ */

#hotspot-ebene,
#effekt-ebene {
  position: absolute;
  inset: 0;
}

/* Die Effekt-Ebene soll Klicks NICHT abfangen, sonst blockieren
   herumfliegende Koffer die Hotspots darunter. */
#effekt-ebene {
  pointer-events: none;
}

.hotspot {
  position: absolute;          /* Position kommt per style="" aus main.js */
  cursor: pointer;
  border: 3px dashed rgba(255, 255, 255, 0.55);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.06);
  padding: 0;

  /* Sanftes "Atmen", damit Kinder sehen: hier kann man klicken.
     Definition der Animation steht ganz unten bei @keyframes. */
  animation: atmen 2.6s ease-in-out infinite;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.hotspot:hover,
.hotspot:focus-visible {
  background: rgba(255, 255, 255, 0.22);
  border-color: var(--farbe-akzent);
  transform: scale(1.03);
  outline: none;
  animation: none;             /* beim Draufzeigen hört das Pulsieren auf */
}

/* Beschriftung, die beim Draufzeigen erscheint. Sie sitzt unterhalb
   des Hotspots und ist normalerweise unsichtbar (opacity: 0). */
.hotspot-label {
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translate(-50%, 8px);
  white-space: nowrap;
  background: rgba(0, 0, 0, 0.78);
  color: #fff;
  font-size: clamp(12px, 1.5vw, 18px);
  padding: 5px 12px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;        /* das Schild selbst ist nicht klickbar */
  transition: opacity 0.15s ease;
}

.hotspot:hover .hotspot-label,
.hotspot:focus-visible .hotspot-label {
  opacity: 1;
}

/* Ein Hotspot, der gerade neu freigeschaltet wurde (z. B. der Durchgang
   nach der Sicherheitskontrolle) leuchtet kurz grün auf. */
.hotspot.neu {
  border-color: var(--farbe-gut);
  animation: aufleuchten 1.2s ease-in-out 3;
}

/* --- Checklisten-Szene (Cockpit) --------------------------------- */
/* Dort sind die Instrumente dauerhaft beschriftet — man soll lesen
   können, was welcher Schalter ist, ohne mit der Maus zu suchen.
   Das Schild sitzt hier ÜBER dem Hotspot, weil die Instrumente im
   unteren Bildbereich liegen und ein Schild darunter aus dem Bild
   fallen würde. */
.hotspot.beschriftet .hotspot-label {
  opacity: 1;
  top: auto;
  bottom: 100%;
  transform: translate(-50%, -8px);
  font-weight: 700;
}

/* Der Schritt, der gerade dran ist: kräftig gelb und deutlich
   pulsierend. Alle übrigen Schritte sind in dieser Szene ohnehin
   noch gesperrt und damit gar nicht sichtbar. */
.hotspot.dran {
  border-color: var(--farbe-akzent);
  border-width: 4px;
  background: rgba(240, 180, 41, 0.16);
  animation: schritt-pulsiert 1.4s ease-in-out infinite;
}

.hotspot.dran .hotspot-label {
  background: var(--farbe-akzent);
  color: #12233a;
}

@keyframes schritt-pulsiert {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 180, 41, 0.55); }
  50%      { box-shadow: 0 0 0 12px rgba(240, 180, 41, 0); }
}


/* --- 5. Kopfzeile und Hinweis ------------------------------------ */

.kopfzeile {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;

  /* Weicher dunkler Verlauf, damit Text auf hellen Bildern lesbar bleibt */
  background: linear-gradient(rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
  pointer-events: none;        /* der Verlauf selbst schluckt keine Klicks */
}

.kopfzeile > * {
  pointer-events: auto;        /* Button und Titel aber schon */
}

#szenen-titel {
  margin: 0;
  font-size: clamp(16px, 2.4vw, 30px);
  font-weight: 700;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
}

#zurueck-button {
  font: inherit;
  font-size: clamp(13px, 1.6vw, 19px);
  font-weight: 600;
  color: #12233a;
  background: var(--farbe-akzent);
  border: none;
  border-radius: 999px;
  padding: 9px 18px;
  cursor: pointer;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.3);
}

#zurueck-button:hover {
  filter: brightness(1.08);
}

#zurueck-button:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
}

/* Ton-Button: margin-left: auto schiebt ihn ans rechte Ende der Kopfzeile */
#ton-button {
  margin-left: auto;
  font-size: clamp(18px, 2.4vw, 28px);
  line-height: 1;
  background: rgba(0, 0, 0, 0.45);
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-radius: 50%;
  width: clamp(38px, 5vw, 56px);
  height: clamp(38px, 5vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

#ton-button:hover {
  border-color: var(--farbe-akzent);
  background: rgba(0, 0, 0, 0.65);
}

/* --- 5b. Toast — kurze Meldung, verschwindet von selbst ---------- */

#toast {
  position: absolute;
  left: 50%;
  bottom: clamp(64px, 12vh, 110px);
  transform: translateX(-50%);
  z-index: 6;

  background: rgba(18, 35, 58, 0.92);
  border: 2px solid var(--farbe-akzent);
  border-radius: 999px;
  padding: 10px 22px;
  font-size: clamp(13px, 1.7vw, 20px);
  font-weight: 600;
  max-width: 80%;
  text-align: center;
  pointer-events: none;

  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
}

#toast.sichtbar {
  opacity: 1;
  transform: translateX(-50%) translateY(-6px);
}


.hinweis {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  margin: 0;
  max-width: 80%;
  text-align: center;

  background: rgba(0, 0, 0, 0.62);
  padding: 9px 20px;
  border-radius: 999px;
  font-size: clamp(13px, 1.7vw, 21px);
  pointer-events: none;
}


/* --- 6. Overlay (Bordkarte, Willkommen an Bord, Fehler) ---------- */

#overlay {
  position: absolute;
  inset: 0;
  z-index: 10;                 /* liegt über allem anderen */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  padding: 24px;
  text-align: center;

  background: rgba(10, 20, 35, 0.88);
  animation: einblenden 0.28s ease-out;

  /* Sicherheitsnetz: Ist der Inhalt einmal höher als die Bühne (die
     Geschichte am Anfang war es), läuft er sonst oben und unten aus
     dem Bild — samt Überschrift und Knopf. Lieber scrollen. */
  overflow-y: auto;
}

#overlay-inhalt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  font-size: clamp(15px, 2.1vw, 26px);
  line-height: 1.45;
}

#overlay-inhalt h2 {
  margin: 0;
  font-size: clamp(22px, 3.6vw, 46px);
  color: var(--farbe-akzent);
}

#overlay-inhalt p {
  margin: 0;
  max-width: 46ch;             /* ca. 46 Zeichen pro Zeile — gut lesbar */
}

/* Titelbild vor dem Vorspann: nur das Logo und ein Knopf. Der Klick
   darauf ist zugleich die Nutzeraktion, mit der Browser den Ton
   freigeben — ohne ihn bliebe die Titelmusik stumm. */
.titel-logo {
  width: min(62%, 560px);
  max-height: 52vh;
  height: auto;
  object-fit: contain;
  background: #ffffff;
  border-radius: 20px;
  padding: 14px 20px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55);
}


/* --- Vorspann: durchlaufender Text nach Star-Wars-Art ------------ */
/*
   Der Aufbau in drei Teilen:

   .crawl      – das Fenster, in dem alles läuft. Es gibt die
                 Perspektive vor und blendet oben weich aus, damit der
                 Text in der Ferne verschwindet statt abgeschnitten zu
                 werden.
   .crawl-lauf – der Inhalt. Er ist nach hinten gekippt (rotateX) und
                 wandert von unten nach oben.

   Wichtig ist die Reihenfolge: Die Perspektive sitzt am ELTERN-Element,
   die Drehung am Kind. Beides am selben Element hätte keine Tiefe,
   der Text wäre nur flach gestaucht.
*/

/* Der Overlay-Inhalt ist eine zentrierte Flexbox und damit nur so breit
   wie sein Inhalt. Der Crawl-Text ist aber absolut positioniert und
   trägt gar nichts zur Breite bei — das ergibt einen Ringschluss, der
   bei null endet, und der ganze Vorspann bliebe unsichtbar. Deshalb
   hier ausdrücklich die volle Breite anfordern. (Derselbe Stolperstein
   wie oben bei #platzhalter-extra.) */
#overlay-inhalt:has(.crawl) {
  width: 100%;
}

.crawl {
  position: relative;
  width: 100%;
  height: 70vh;      /* darunter braucht der Knopf noch Platz */
  overflow: hidden;

  /* Perspektive bewusst schwach (großer Wert = flacherer Blick).
     Bei kleinen Werten staucht sich der Text zu einem unleserlichen
     Streifen zusammen — für Kinder muss er lesbar bleiben, der
     Tiefeneffekt ist nur Beiwerk.

     Der Fluchtpunkt sitzt in der Mitte, nicht oben: Bei
     `perspective-origin: 50% 0%` laufen die Zeilen nach unten hin
     auseinander und schießen seitlich aus dem Bild. */
  perspective: 1700px;
  perspective-origin: 50% 45%;

  /* Oben ausblenden — der Text soll in der Ferne verschwinden. */
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%, rgba(0, 0, 0, 0.35) 14%, #000 34%, #000 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0%, rgba(0, 0, 0, 0.35) 14%, #000 34%, #000 100%);
}

.crawl-lauf {
  position: absolute;
  top: 100%;
  left: 50%;
  /* Schmal ansetzen: Die Perspektive zieht den Text nach unten hin
     auseinander, erst dadurch füllt er die Bühne. Wäre er hier schon
     breit, ragte er unten weit aus dem Bild. */
  width: min(58%, 620px);
  transform-origin: 50% 0%;
  transform: translateX(-50%) rotateX(20deg);

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1em;

  color: var(--farbe-akzent);
  text-align: center;
  font-size: clamp(16px, 2.3vw, 30px);
  font-weight: 600;
  line-height: 1.4;

  animation: crawl-laeuft var(--crawl-dauer, 34s) linear forwards;
}

.crawl-lauf p {
  margin: 0;
}

.crawl-lauf strong {
  color: #fff3d0;
}

.crawl-lauf em {
  font-style: normal;
  color: #ffffff;
}

/* Die Einleitungszeile etwas ruhiger, der Schlusssatz größer */
.crawl-vor {
  font-size: 0.82em;
  opacity: 0.85;
}

.crawl-schluss {
  font-size: 1.3em;
  font-weight: 800;
  color: #fff3d0;
}

/* Logo und Foto laufen im Text mit. Das Logo hat weißen Grund und
   bekommt deshalb eine eigene helle Fläche, sonst stünde ein harter
   Block im Dunkeln. */
.crawl-logo {
  width: 58%;
  height: auto;
  background: #ffffff;
  border-radius: 16px;
  padding: 8px 14px;
}

.crawl-foto {
  width: 34%;
  height: auto;
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
}

@keyframes crawl-laeuft {
  from { top: 100%; }
  to   { top: -260%; }
}

/* Wer Bewegung nicht mag oder braucht: dann steht der Text einfach da
   und man liest ihn in Ruhe. */
@media (prefers-reduced-motion: reduce) {
  .crawl-lauf {
    position: static;
    transform: none;
    animation: none;
    max-height: 68vh;
    overflow-y: auto;
  }

  .crawl {
    perspective: none;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* Der Vorspann bringt Bild, Überschrift und drei Absätze mit — das ist
   für ein Overlay viel. Nur dort wird alles etwas enger gesetzt, damit
   es auch auf flachen Fenstern ohne Scrollen auf die Bühne passt.
   `:has()` trifft gezielt das Geschichts-Overlay; die übrigen (Bordkarte,
   Abschluss) bleiben unverändert. */
#overlay-inhalt:has(.overlay-text) {
  gap: 9px;
}

#overlay-inhalt:has(.overlay-text) h2 {
  font-size: clamp(18px, 2.5vw, 32px);
}

/* Mehrere Absätze am Stück (die Geschichte zu Beginn). Hier ist
   linksbündig deutlich besser lesbar als zentriert — bei zentrierten
   Blocktexten muss das Auge jede Zeile neu suchen. Etwas kleiner
   gesetzt, damit die Geschichte auch auf kleinen Fenstern ganz
   sichtbar bleibt. */
.overlay-text {
  max-width: 52ch;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  font-size: 0.88em;
}

.overlay-text p {
  margin: 0;
}

.overlay-text em {
  color: var(--farbe-akzent);
  font-style: normal;
  font-weight: 700;
}

#overlay-inhalt code {
  background: rgba(255, 255, 255, 0.12);
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 0.9em;
}

#overlay-schliessen {
  font: inherit;
  font-size: clamp(15px, 2vw, 24px);
  font-weight: 700;
  color: #12233a;
  background: var(--farbe-akzent);
  border: none;
  border-radius: 999px;
  padding: 12px 34px;
  cursor: pointer;
  box-shadow: 0 4px 0 rgba(0, 0, 0, 0.35);
}

#overlay-schliessen:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
}

/* Solange kein Name eingetippt ist, ist der Start-Button ausgegraut. */
#overlay-schliessen:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  box-shadow: none;
}


/* Eingabefeld für den Spielernamen */
#name-eingabe {
  font: inherit;
  font-size: clamp(18px, 2.6vw, 30px);
  font-weight: 700;
  text-align: center;
  color: #12233a;
  background: #fffbe9;
  border: 3px solid var(--farbe-akzent);
  border-radius: var(--radius);
  padding: 10px 18px;
  width: min(340px, 70vw);
}

#name-eingabe:focus {
  outline: 3px solid var(--farbe-gut);
  outline-offset: 2px;
}

#name-eingabe::placeholder {
  color: #9ca3af;
  font-weight: 400;
}


/* --- 7. Die Bordkarte (reines SVG + CSS, kein Bild nötig) -------- */

.bordkarte {
  width: clamp(260px, 45vw, 520px);
  height: auto;
  filter: drop-shadow(0 12px 24px rgba(0, 0, 0, 0.5));
  animation: karte-rein 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.3);
}

/* Beim Vorspann steht das Bild zusammen mit mehreren Absätzen im
   Overlay. In voller Größe passt beides auf kleineren Fenstern nicht
   mehr auf die Bühne — deshalb hier deutlich kleiner. Die Höhe wird
   zusätzlich am Fenster gedeckelt, damit auf flachen Bildschirmen
   der Text sichtbar bleibt und nicht das Bild alles auffrisst. */
.bordkarte.logo {
  width: clamp(180px, 22vw, 300px);
  max-height: 21vh;
  object-fit: contain;
}

/* Der grüne Haken wird "gezeichnet": stroke-dasharray legt eine
   gestrichelte Linie an, stroke-dashoffset schiebt sie aus dem Bild
   heraus — die Animation zieht sie dann wieder hinein. */
.haken-pfad {
  stroke-dasharray: 60;
  stroke-dashoffset: 60;
  animation: haken-malen 0.5s ease-out 0.35s forwards;
}


/* --- 8. Sicherheitskontrolle: Koffer und Röntgen ----------------- */

/* Der Koffer fährt von links ins Bild und verschwindet im Scanner. */
.koffer {
  position: absolute;
  left: 6%;
  bottom: 16%;
  width: 16%;
  animation: koffer-faehrt 2.6s ease-in-out forwards;
}

/* Kurzer heller Blitz über die ganze Szene = Röntgenaufnahme */
.roentgen-blitz {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 42% 55%, #9fe8ff 0%, rgba(159, 232, 255, 0) 65%);
  opacity: 0;
  animation: blitzen 0.9s ease-out 1.5s;
}

/* Wassertropfen am Waschbecken */
.tropfen {
  position: absolute;
  width: 1.4%;
  aspect-ratio: 1 / 1.5;
  background: #7fd4ff;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  animation: tropfen-faellt 1.1s ease-in forwards;
}


/* --- 9. Alle Animationen (@keyframes) ---------------------------- */
/* @keyframes beschreibt einen Ablauf: was passiert bei 0 %, was bei
   100 %. Oben verweisen die Elemente per "animation:" darauf. */

@keyframes atmen {
  0%, 100% { border-color: rgba(255, 255, 255, 0.35); }
  50%      { border-color: rgba(255, 255, 255, 0.85); }
}

@keyframes aufleuchten {
  0%, 100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.7); }
  50%      { box-shadow: 0 0 0 14px rgba(74, 222, 128, 0); }
}

@keyframes einblenden {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes karte-rein {
  from { transform: translateY(40px) rotate(-6deg); opacity: 0; }
  to   { transform: translateY(0) rotate(0); opacity: 1; }
}

@keyframes haken-malen {
  to { stroke-dashoffset: 0; }
}

@keyframes koffer-faehrt {
  0%   { transform: translateX(0) rotate(-3deg); opacity: 1; }
  55%  { transform: translateX(150%) rotate(2deg); opacity: 1; }
  75%  { transform: translateX(210%) rotate(0deg); opacity: 0.35; }
  100% { transform: translateX(240%) rotate(0deg); opacity: 0; }
}

@keyframes blitzen {
  0%   { opacity: 0; }
  25%  { opacity: 0.95; }
  100% { opacity: 0; }
}

@keyframes tropfen-faellt {
  from { transform: translateY(0);    opacity: 1; }
  to   { transform: translateY(320%); opacity: 0; }
}

/* Wolke zieht von rechts komplett nach links aus dem Bild */
@keyframes wolke-zieht {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100vw - 100%)); }
}

/* Eine Parallaxe-Schicht der Taxifahrt zieht nach links.
   -50 % = genau eine Kopie weiter, dadurch ist der Übergang unsichtbar */
@keyframes schicht-zieht {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Landschaft scrollt seitlich — eine Kopie schiebt sich nach */
@keyframes boden-zieht {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Dasselbe für die Bildfassung. Verschoben wird um ein "Kopien-tel"
   der Gesamtbreite — das ist genau eine Bildbreite, egal wie viele
   Kopien main.js eingesetzt hat. */
@keyframes boden-zieht-bild {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% / var(--kopien, 4))); }
}

/* Beim Start sinkt die Landschaft weg und wird kleiner (= weiter weg) */
@keyframes boden-sinkt {
  0%   { transform: translateY(0)      scale(1);    opacity: 1; }
  60%  { transform: translateY(35%)    scale(0.82); opacity: 0.9; }
  100% { transform: translateY(115%)   scale(0.6);  opacity: 0.7; }
}

/* Bei der Landung dasselbe rückwärts */
@keyframes boden-steigt {
  0%   { transform: translateY(115%) scale(0.6);  opacity: 0.7; }
  100% { transform: translateY(0)    scale(1);    opacity: 1; }
}

/* Die Zeiger der Cockpit-Instrumente zittern leicht */
@keyframes zeiger-wackelt {
  0%, 100% { transform: rotate(-12deg); }
  50%      { transform: rotate(16deg); }
}


/* --- 10. Rücksicht auf empfindliche Nutzer ----------------------- */
/* Wer im Betriebssystem "Bewegung reduzieren" eingestellt hat,
   bekommt keine dauerhaften Animationen. */
@media (prefers-reduced-motion: reduce) {
  .hotspot,
  .hotspot.neu {
    animation: none;
    border-color: rgba(255, 255, 255, 0.8);
  }
}
