/* ============================================================================
   Hobba — die Bewegungsschicht (gemeinsam für alle Seiten)

   Bewegung ist hier eine Schicht, kein Bestandteil. Jede Seite steht ohne
   diese Datei vollständig da: Der Text ist sichtbar, die Reihenfolge stimmt,
   nichts wartet auf JavaScript. Erst wenn das Dokument die Klasse `js` trägt,
   blendet diese Datei etwas aus, um es danach hereinzuholen.

   Und die Klasse setzt das Skript im Seitenkopf nur, wenn das System **keine**
   reduzierte Bewegung verlangt. Deshalb steht in fast jeder Regel unten `.js`
   vorneweg. Wer das streicht, nimmt bewegungsempfindlichen Nutzern nicht die
   Animation, sondern den Inhalt.

   Ein Grundsatz für alles hier: bewegt werden nur `opacity`, `transform` und
   `translate`. Alles andere zwingt den Browser zum Neuberechnen des Layouts,
   und genau daran erkennt man eine Seite, die auf dem Telefon ruckelt.
   ========================================================================= */

:root {
  /* Eine Kurve für die ganze Seite: schnell los, weich aus. Verschiedene
     Kurven nebeneinander sind der häufigste Grund, warum sich eine Seite
     „zusammengesetzt“ anfühlt. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --rise: 14px;
  --lift-shadow: 0 16px 34px -20px rgba(20, 40, 30, 0.55);
  --head-shadow: 0 8px 26px -14px rgba(20, 40, 30, 0.4);
}
@media (prefers-color-scheme: dark) {
  :root {
    --lift-shadow: 0 16px 34px -18px rgba(0, 0, 0, 0.7);
    --head-shadow: 0 8px 26px -12px rgba(0, 0, 0, 0.6);
  }
}

/* --- Der Fortschrittsbalken -------------------------------------------------
   Zwei Pixel über allem. Er liegt bewusst über der klebenden Kopfzeile: Der
   Balken beantwortet „wie viel kommt noch“, und diese Frage soll nicht unter
   dem Menü verschwinden. Der Wert kommt als Custom Property aus dem Skript,
   damit pro Bild nur eine Eigenschaft gesetzt wird und kein Layout entsteht. */
.progress {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 30;
  pointer-events: none; transform-origin: 0 50%;
  transform: scaleX(var(--p, 0));
  background: linear-gradient(90deg,
              color-mix(in srgb, var(--accent) 55%, transparent),
              var(--accent));
}

/* --- Die Kopfzeile ---------------------------------------------------------
   Sie sitzt schon von Haus aus fest oben. Neu ist nur, dass sie merkt, wann
   sie über Inhalt liegt — vorher schwebte sie ohne Anlass. */
header.top { transition: box-shadow 0.3s var(--ease-soft); }
header.top.scrolled { box-shadow: var(--head-shadow); }

/* --- Einblenden beim Scrollen ----------------------------------------------
   Ein Element mit `.reveal` startet knapp unter seinem Platz und kommt hoch,
   sobald es ins Bild fährt. `--i` staffelt Geschwister, damit eine Reihe
   nacheinander eintrifft statt als Block. Beobachtet wird jedes Element nur
   einmal; danach meldet sich der Observer ab (siehe motion.js). */
.js .reveal {
  opacity: 0; transform: translateY(var(--rise));
  transition: opacity 0.62s var(--ease), transform 0.62s var(--ease);
  transition-delay: calc(var(--i, 0) * 85ms);
}
.js .reveal.in { opacity: 1; transform: none; }

/* --- Karten, die auf den Zeiger reagieren ----------------------------------
   Nur dort, wo es einen Zeiger gibt: Auf dem Telefon bliebe ein :hover nach
   der Berührung hängen und sähe aus wie ein Fehler. */
@media (hover: hover) {
  .js .pillar, .js .tier, .js .entry, .js .td-row, .js section.card {
    transition: transform 0.35s var(--ease), border-color 0.3s ease,
                box-shadow 0.35s var(--ease);
  }
  .js .pillar:hover, .js .tier:hover, .js .entry:hover, .js section.card:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
    box-shadow: var(--lift-shadow);
  }
}

/* --- Der Knopf -------------------------------------------------------------
   Ein Schimmer, der einmal durchläuft, und ein Pfeil, der einen Hauch
   vorrückt. Beides nur bei Zeigergeräten und nur einmal je Überfahrt. */
.cta { position: relative; overflow: hidden; isolation: isolate; }
.cta .arrow { display: inline-block; }
@media (hover: hover) {
  .js .cta .arrow { transition: transform 0.3s var(--ease); }
  .js .cta:hover .arrow { transform: translateX(3px); }
  .js .cta::after {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(105deg, transparent 38%,
                rgba(255, 255, 255, 0.4) 50%, transparent 62%);
    transform: translateX(-130%);
  }
  .js .cta:hover::after { animation: hobba-sheen 0.8s var(--ease-soft); }
}
@keyframes hobba-sheen { to { transform: translateX(130%); } }

/* --- Tastatur --------------------------------------------------------------
   Wer mit der Tabulatortaste durchgeht, soll sehen, wo er ist. Kostet nichts
   und fehlt auf den meisten Seiten. */
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 8px;
}

/* --- Seitenwechsel ---------------------------------------------------------
   Zwei Zeilen, und der Sprung von der Startseite ins Devlog wird eine
   Überblendung statt eines Weißblitzes. Browser ohne View Transitions
   ignorieren die Regel vollständig — deshalb steht hier nichts, was ohne sie
   fehlen würde. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: hobba-vt-out 160ms ease both; }
  ::view-transition-new(root) { animation: hobba-vt-in 260ms var(--ease) both; }
}
@keyframes hobba-vt-out { to { opacity: 0; } }
@keyframes hobba-vt-in { from { opacity: 0; transform: translateY(8px); } }

/* --- Reduzierte Bewegung ---------------------------------------------------
   Das Kopf-Skript setzt `js` gar nicht erst, also greift oben fast nichts
   mehr. Dieser Block fängt den Rest ab — auch das, was schon vor dieser
   Datei auf den Seiten stand. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
