/**
 * Anirova District — Kamerafahrt und Seitenuebergaenge.
 *
 * 04-INTERACTION-MOTION.md: Zustandsautomat
 * idle → preview → departing → traveling → arriving → district.
 *
 * Animiert werden AUSSCHLIESSLICH transform und opacity. Beide laufen im
 * Compositor und loesen weder Layout noch Paint aus. Ein animiertes width
 * oder top wuerde jeden Frame das Layout neu rechnen — genau die Ruckler,
 * die 09-QUALITY-GATES ausschliesst ("Long Tasks >50 ms waehrend Reise: 0").
 */

/* ── Kamera ──────────────────────────────────────────────────────────────
   Die Szene skaliert um den angeklickten Node. transform-origin wird von
   district-map.js je Ziel gesetzt, damit die Fahrt wirklich DORTHIN geht
   und nicht in die Bildmitte. */
.district-atlas__kamera {
  position: absolute;
  inset: 0;
  transform-origin: var(--kamera-x, 50%) var(--kamera-y, 50%);
  transition: transform var(--dur-travel) var(--ease-district-out);
  will-change: transform;
}

/* Abfahrt: minimales Zurueckweichen, damit der Sprung nach vorn Kontrast
   bekommt. 180 ms laut 04-INTERACTION-MOTION (Zoom-out zur Mini-Map). */
[data-reise="departing"] .district-atlas__kamera {
  transform: scale(.97);
  transition-duration: 180ms;
}

/* Anfahrt: 1.0 → 1.32 wie im Handoff spezifiziert. */
[data-reise="traveling"] .district-atlas__kamera,
[data-reise="arriving"] .district-atlas__kamera {
  transform: scale(1.32);
}

/* Waehrend der Fahrt treten die uebrigen Nodes zurueck, das Ziel bleibt. */
[data-reise="traveling"] .district-node:not([data-ziel="true"]),
[data-reise="arriving"] .district-node:not([data-ziel="true"]) {
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-district-out);
}

[data-reise="traveling"] .district-node[data-ziel="true"] {
  /* Das Ziel waechst leicht mit — es ist der Ort, auf den man zufaehrt. */
  transform: translate(-50%, -50%) scale(1.15);
  transition: transform var(--dur-travel) var(--ease-district-out);
}

/* ── Route zeichnen ──────────────────────────────────────────────────────
   Einmalig in 180-260 ms, nicht endlos (DESIGN.md 4). */
[data-reise] .district-route[data-strecke="true"] {
  stroke: var(--color-primary-bright);
  opacity: 1;
  stroke-dasharray: var(--strecke-laenge, 200);
  stroke-dashoffset: var(--strecke-laenge, 200);
  animation: district-strecke 260ms var(--ease-district-out) forwards;
}

@keyframes district-strecke {
  to { stroke-dashoffset: 0; }
}

/* ── Ausblenden beim Verlassen ──────────────────────────────────────────
   Die Karte verschwindet nach vorn, nicht einfach weg — das verkauft die
   Bewegung als Eintritt statt als Seitenwechsel. */
[data-reise="arriving"] [data-component="district-atlas"] {
  opacity: 0;
  transition: opacity var(--dur-reveal) var(--ease-district-out);
}

/* ── Establishing Shot ───────────────────────────────────────────────────
   Beim Ankommen faehrt der District-Header aus dem Zoom heraus auf. Das
   ist die Gegenbewegung zur Kamerafahrt und schliesst sie ab. */
@keyframes district-ankunft {
  from { opacity: 0; transform: scale(1.06) translateY(8px); }
  to   { opacity: 1; transform: none; }
}

[data-district-ankunft] [data-component="district-buehne"] {
  animation: district-ankunft var(--dur-reveal) var(--ease-district-out) both;
}

/* Der Seiteninhalt folgt leicht versetzt — dadurch wirkt die Ankunft
   gestaffelt statt als ein harter Schnitt. */
[data-district-ankunft] main > :not([data-component="district-buehne"]):not([data-component="board-kopf"]) {
  animation: district-ankunft var(--dur-reveal) var(--ease-district-out) 80ms both;
}

/* Einmalige Inhaltsankunft. Inhalte sind ohne JS normal sichtbar; erst der
   Controller setzt pending und damit den kurzen Ausgangszustand. */
[data-district-reveal="pending"] {
  opacity: .01;
  transform: translate3d(0, 18px, 0);
}

[data-district-reveal="done"] {
  animation: district-panel-ein 520ms var(--ease-district-out) both;
  animation-delay: calc(var(--reveal-order, 0) * 55ms);
}

@keyframes district-panel-ein {
  from { opacity: .01; transform: translate3d(0, 18px, 0); filter: blur(3px); }
  to { opacity: 1; transform: none; filter: none; }
}

/* Die Cyan-Route im Ortsbild reist genau einmal beim Laden durch das Bild. */
.bhe::after {
  content: "";
  position: absolute;
  left: -35%;
  bottom: 0;
  width: 34%;
  height: 2px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--color-primary-bright), transparent);
  filter: drop-shadow(0 0 7px var(--color-primary));
  animation: district-hero-route 1100ms var(--ease-district-out) 180ms both;
}

@keyframes district-hero-route {
  from { transform: translate3d(0, 0, 0); opacity: 0; }
  20% { opacity: 1; }
  to { transform: translate3d(410%, 0, 0); opacity: 0; }
}

/* ── View Transitions ────────────────────────────────────────────────────
   Nur benennen, nicht erzwingen: fehlt die API, greift der Crossfade aus
   dem Router (05-TECHNICAL-ARCHITECTURE, Fallback). */
@supports (view-transition-name: none) {
  [data-component="board-kopf"] { view-transition-name: district-dock; }
  [data-component="district-header"] { view-transition-name: district-title; }
}

/* ── Reduce Motion ───────────────────────────────────────────────────────
   Kein Zoom, kein Pan — nur ein kurzer Crossfade
   (04-INTERACTION-MOTION: "Reduce Motion ersetzt Zoom und Translation
   durch einen 120-ms-Crossfade"). */
@media (prefers-reduced-motion: reduce) {
  .district-atlas__kamera,
  [data-reise="departing"] .district-atlas__kamera,
  [data-reise="traveling"] .district-atlas__kamera,
  [data-reise="arriving"] .district-atlas__kamera {
    transform: none !important;
    transition: none !important;
  }

  [data-reise] .district-route[data-strecke="true"] {
    animation: none !important;
    stroke-dashoffset: 0 !important;
  }

  [data-reise="traveling"] .district-node[data-ziel="true"] {
    transform: translate(-50%, -50%) !important;
  }

  [data-district-ankunft] [data-component="district-buehne"],
  [data-district-ankunft] main > * {
    animation: district-einblenden 120ms linear both !important;
  }

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

  [data-district-reveal],
  [data-district-reveal="pending"],
  [data-district-reveal="done"] {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
  }

  .bhe::after { animation: none !important; display: none; }
  .bhe__marke { transform: none !important; transition: none !important; }
}
