/* route.css — die Flugroute und die Birdys Buehne.
 *
 * ZWEI EBENEN, GETRENNT (siehe Konzept, Abschnitt 03):
 *   ORT      — Position/Groesse/Drehung des Vogels: hier, per CSS-transform.
 *   AUSDRUCK — Fluegelschlag, Blick, Reaktion: in der Rive State Machine.
 *
 * Der Vogel liegt FIXED im Viewport und folgt einem Ziel mit Traegheit.
 * Ob er "fliegt" oder "sitzt", ist nur die Frage, welches Ziel gerade gilt —
 * einen Punkt auf der Route oder einen Sitzplatz [data-perch]. Daraus ergibt
 * sich das Anfliegen und Landen von selbst, ohne eigene Zustandsanimation.
 */

/* ---------- Die gestrichelte Route im Hintergrund ---------- */

.route {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.route svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Der noch nicht geflogene Teil */
.route-line {
  fill: none;
  stroke: var(--route);
  stroke-width: 1.5;
  stroke-dasharray: 7 7;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* Der zurueckgelegte Teil — wird per stroke-dashoffset aufgedeckt */
.route-line-done {
  fill: none;
  stroke: var(--route-done);
  stroke-width: 1.5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  transition: stroke-dashoffset .1s linear;
}

/* Stopp-Punkte auf der Route, einer je Abschnitt */
.route-stop {
  fill: var(--ground);
  stroke: var(--route);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  transition: stroke var(--dur) var(--ease-soft), fill var(--dur) var(--ease-soft);
}
.route-stop.is-reached { stroke: var(--route-done); fill: var(--accent); }

/* ---------- Birdy ---------- */

.companion {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 40;
  width: var(--bird-size, 74px);
  height: var(--bird-size, 74px);
  pointer-events: none;          /* faengt keine Klicks ab ... */
  will-change: transform;
  transform: translate3d(-100px, -100px, 0);
  transition: width var(--dur-slow) var(--ease-out),
              height var(--dur-slow) var(--ease-out),
              opacity var(--dur) var(--ease-soft);
}

/* ... ausser im Begleiter-Abschnitt, wo man ihn anfassen darf */
.companion.is-touchable { pointer-events: auto; cursor: grab; }
.companion.is-touchable:active { cursor: grabbing; }

.companion.is-hidden { opacity: 0; }

/* AUSRICHTUNG DES FLUGZEUGS
 *
 * Die Nase zeigt im Bild nach LINKS. Fliegt Birdy nach rechts, wird gespiegelt
 * (--bird-flip: -1); die Neigung kommt aus der Flugrichtung (--bird-rot).
 * Reihenfolge beachten: CSS wendet von rechts nach links an — erst spiegeln,
 * dann drehen. Andersherum kaeme die Drehung spiegelverkehrt heraus.
 *
 * Die Uebergangszeit ist kurz gehalten: bei laengerer Dauer "schwimmt" das
 * Flugzeug der Bahn hinterher, statt ihr zu folgen. */
.companion-inner {
  width: 100%;
  height: 100%;
  transform: rotate(var(--bird-rot, 0deg)) scaleX(var(--bird-flip, 1));
  transition: transform .18s var(--ease-soft);
}

.companion canvas,
.companion svg { width: 100%; height: 100%; display: block; }

/* Weicher Schein darunter — verankert ihn optisch, ersetzt einen Schatten */
.companion::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -6%;
  width: 66%; height: 14%;
  transform: translateX(-50%) scale(var(--bird-shadow, 1));
  background: radial-gradient(ellipse at center, var(--bird-shade), transparent 72%);
  opacity: var(--bird-shadow-alpha, 0);
  transition: opacity var(--dur) var(--ease-soft);
  pointer-events: none;
}

/* Der Vogel bleibt beim Landen kurz stehen — Groesse wechselt je Abschnitt */
.companion[data-scale="close"] { --bird-size: clamp(150px, 26vw, 240px); }
.companion[data-scale="far"]   { --bird-size: clamp(48px, 7vw, 64px); }

/* ---------- Sitzplaetze ---------- */

/* Unsichtbarer Anker. Ein Element bekommt data-perch und wird damit zum Ziel.
   Kein eigenes Aussehen — es markiert nur eine Stelle im Layout. */
[data-perch] { position: relative; }

/* ---------- Ruecksicht ---------- */

/* Ohne Bewegung: der Vogel sitzt fest an seinem Abschnitt, die Route steht
   vollstaendig da. Der Inhalt bleibt unveraendert. */
@media (prefers-reduced-motion: reduce) {
  .companion { transition: none; }
  .companion-inner { transition: none; }
  .route-line-done { transition: none; }
}

/* Auf schmalen Geraeten kleiner und dezenter — dort zaehlt Ladezeit mehr als
   Choreografie (Konzept, Abschnitt 07). */
@media (max-width: 720px) {
  .companion { --bird-size: 54px; }
  .companion[data-scale="close"] { --bird-size: clamp(120px, 38vw, 170px); }
  .companion[data-scale="far"]   { --bird-size: 42px; }
}

/* Ganz schmal: die Route waere nur noch Strich am Rand — weg damit. */
@media (max-width: 480px) {
  .route { display: none; }
}

/* ---------- Fluegelschlag des SVG-Vogels ----------
 * Nur fuer den Fall OHNE Rive. Uebernimmt die Rive-Runtime, wird das SVG
 * ausgeblendet und der Fluegelschlag kommt aus der State Machine (flapSpeed).
 * Die Geschwindigkeit setzt journey.js ueber --wing-dur — schneller im Flug,
 * langsam im Sitzen.
 */
@keyframes wingbeat {
  0%, 100% { transform: rotate(0deg)   scaleY(1);    }
  50%      { transform: rotate(-14deg) scaleY(.82);  }
}

[data-bird-fallback] .wing {
  transform-origin: 52px 50px;
  transform-box: view-box;
  animation: wingbeat var(--wing-dur, 1.1s) var(--ease-soft) infinite;
}

/* Sanftes Auf und Ab, damit er auch im Sitzen atmet */
@keyframes hover-bob {
  0%, 100% { transform: translateY(0);      }
  50%      { transform: translateY(-3.5%);  }
}
[data-bird-fallback] { animation: hover-bob 3.4s var(--ease-soft) infinite; }

@media (prefers-reduced-motion: reduce) {
  [data-bird-fallback],
  [data-bird-fallback] .wing { animation: none; }
}

/* ---------- Birdy im Doppeldecker ----------
 * Das ist die Fassung OHNE Rive: auf dem Telefon (wo die 390-KB-Runtime nicht
 * geladen wird) und ueberall dort, wo Rive nicht zustande kommt.
 *
 * Warum ein Flugzeug statt eines sitzenden Vogels: Die Seite erzaehlt eine
 * Flugroute — da passt der Doppeldecker aus dem Mini-Spiel besser als ein
 * gezeichneter Vogel, und die beiden Bilder sind bereits eine fertige
 * Zwei-Bild-Animation (nur der Propeller unterscheidet sich).
 *
 * Beide Bilder liegen uebereinander; blinkend gewechselt wird per Animation,
 * ohne JavaScript. 24 KB fuer beide zusammen.
 */

.plane { position: relative; width: 100%; height: 100%; }
.plane img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}
.plane .frame-b { opacity: 0; }

@keyframes propeller {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.plane .frame-a { animation: propeller var(--prop-dur, .16s) steps(1, end) infinite; }
.plane .frame-b { animation: propeller var(--prop-dur, .16s) steps(1, end) infinite reverse; }

/* Sanftes Auf und Ab, damit er auch im Stand lebt */
.plane { animation: hover-bob 3.4s var(--ease-soft) infinite; }

@media (prefers-reduced-motion: reduce) {
  .plane, .plane img { animation: none; }
  .plane .frame-b { opacity: 0; }
}


/* ---------- Unterwegs im Flugzeug, im Atelier als Birdy ----------
 * Zwei Darstellungen desselben Begleiters: Auf der Route fliegt er im
 * Doppeldecker (das passt zur Flugbahn und ist gutmuetiger als ein Vogel, der
 * quer durchs Bild rudert). Im Atelier steigt er aus — dort steht der Vogel
 * selbst auf dem Stuhl und laesst sich antippen.
 *
 * Laeuft keine Rive-Runtime (Telefon), bleibt es ueberall beim Flugzeug.
 */
.companion.is-perched .plane { opacity: 0; }
.companion:not(.is-perched) canvas { opacity: 0; }
.companion .plane,
.companion canvas { transition: opacity .35s var(--ease-soft); }

/* Im Atelier sitzt er aufrecht — keine Neigung aus der Flugbahn. */
.companion.is-perched .companion-inner { transform: none; }
