/* ==========================================================================
   DP-Dynamic · Bewegung beim Scrollen

   Aufbau in drei Schichten:

   1. Einblenden beim Eintritt (JS: dp-animation.js setzt .ist-da)
      Mehrere Spielarten, damit nicht jeder Abschnitt gleich hereinkommt.
   2. Gestaffelte Kinder (--stufe wird vom Skript gesetzt)
   3. Scroll-gebundene Effekte ohne JavaScript, über animation-timeline.
      Wo der Browser das nicht kann, passiert schlicht nichts — die Seite
      bleibt vollständig bedienbar.

   Grundregel: Bewegung hat eine Aufgabe. Sie ordnet die Reihenfolge, zeigt
   Fortschritt oder gibt Rückmeldung. Nichts läuft in Endlosschleife.
   ========================================================================== */

:root {
  --dp-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dp-ease-weich: cubic-bezier(0.33, 1, 0.68, 1);
  /* Kraeftiger Auslauf: die Karte kommt schnell herein und legt sich
     am Ende ruhig ab. Bewusst ohne Ueberschwingen -- das wirkt nach
     Spielerei, nicht nach Produkt. */
  --dp-ease-setzen: cubic-bezier(0.16, 1, 0.3, 1);
  --dp-dauer: 780ms;
  --dp-dauer-kurz: 460ms;
}

/* --------------------------------------------------------------------------
   1 · Eintritt
   -------------------------------------------------------------------------- */
[data-anim] {
  opacity: 0;
  will-change: opacity, transform;
  transition:
    opacity var(--dp-dauer) var(--dp-ease) var(--dp-verzug, 0ms),
    transform var(--dp-dauer) var(--dp-ease) var(--dp-verzug, 0ms),
    clip-path var(--dp-dauer) var(--dp-ease) var(--dp-verzug, 0ms),
    filter var(--dp-dauer) var(--dp-ease) var(--dp-verzug, 0ms);
}

/* Von unten herein. Der Standard für Fließtext und Karten. */
[data-anim="auf"]    { transform: translate3d(0, 30px, 0); }

/* Karte: steigt auf und kommt dabei ein Stueck heran. Fuer freistehende
   Kacheln, die nicht in einem gestaffelten Raster liegen. */
[data-anim="karte"]  { transform: translate3d(0, 30px, 0) scale(0.975); }

/* Von der Seite. Für Inhalte, die neben einem Bild stehen. */
[data-anim="links"]  { transform: translate3d(-34px, 0, 0); }
[data-anim="rechts"] { transform: translate3d(34px, 0, 0); }

/* Leichtes Heranfahren. Für Bilder und Medienflächen. */
[data-anim="zoom"]   { transform: scale(1.045); }

/* Vorhang: der Inhalt wird von unten freigegeben. Für Überschriften. */
[data-anim="maske"] {
  clip-path: inset(0 0 100% 0);
  transform: translate3d(0, 14px, 0);
}

/* Weichzeichner, der scharf stellt. Sparsam, nur für Schlüsselbilder. */
[data-anim="scharf"] {
  filter: blur(9px);
  transform: scale(1.02);
}

[data-anim="karte"] {
  transition:
    opacity 480ms var(--dp-ease) var(--dp-verzug, 0ms),
    transform 660ms var(--dp-ease-setzen) var(--dp-verzug, 0ms);
}

[data-anim].ist-da {
  opacity: 1;
  transform: none;
  filter: none;
}
/* Nur der Vorhang braucht einen Endwert fürs Aufziehen. Alle anderen
   Spielarten bleiben unbeschnitten, sonst fallen Fokusrahmen, Schatten und
   Bedienelemente am Rand weg (z. B. die Reiter-Pfeile). */
[data-anim="maske"].ist-da { clip-path: inset(0 0 0 0); }

/* Nach dem Eintritt wird will-change zurückgenommen, sonst hält der Browser
   für jede Kachel dauerhaft eine eigene Ebene vor. */
[data-anim].ist-fertig { will-change: auto; }

/* --------------------------------------------------------------------------
   2 · Gestaffelte Kinder
   Das Skript vergibt --stufe je Kind. Die Reihenfolge wird dadurch lesbar,
   statt dass zehn Kacheln gleichzeitig aufblitzen.
   -------------------------------------------------------------------------- */
/* Bewusst `animation` statt `transition`.
   Viele Kacheln tragen `.card-hover`, und diese Klasse setzt eine eigene
   `transition: transform, border-color, background-color`. Eine
   Kurzschreibweise ersetzt die ganze Liste -- `opacity` fiel heraus
   (die Kachel blitzte auf, statt zu blenden) und der gestaffelte Verzug
   ebenfalls (alle Kacheln liefen gleichzeitig). `animation` laeuft
   unabhaengig davon, der Hover bleibt unberuehrt. */
[data-stufen] > * { opacity: 0; }
[data-stufen].ist-da > * {
  opacity: 1;
  will-change: opacity, transform;
  animation: dp-kachel-rein 660ms var(--dp-ease-setzen)
             calc(var(--stufe, 0) * 65ms) backwards;
}
/* `backwards` haelt den Anfangszustand nur waehrend der Verzoegerung.
   Danach bleibt nichts liegen, was den Hover ueberschreiben koennte. */
@keyframes dp-kachel-rein {
  from { opacity: 0; transform: translate3d(0, 26px, 0) scale(0.975); }
  to   { opacity: 1; transform: none; }
}
[data-stufen].ist-fertig > * { will-change: auto; }

/* --------------------------------------------------------------------------
   3 · Zahlen, die hochlaufen
   -------------------------------------------------------------------------- */
[data-zahl] { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   4 · Fortschrittsbalken am oberen Rand
   Zeigt, wie weit die Seite gelesen ist. Ohne JavaScript, rein über die
   Scroll-Zeitleiste des Browsers.
   -------------------------------------------------------------------------- */
.dp-fortschritt {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 60;
  background: transparent;
  pointer-events: none;
}
.dp-fortschritt span {
  display: block;
  height: 100%;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, #FF9600, #FFB454);
}

/* Der Füllstand steckt in --dp-gelesen (0 bis 1) und wird von dp-nav.js
   gesetzt. Eine reine CSS-Scroll-Zeitleiste wäre eleganter, ließ sich hier
   aber nicht zuverlässig prüfen, und ein Balken, dessen Funktion man nicht
   nachweisen kann, ist keiner. */
.dp-fortschritt span {
  transform: scaleX(var(--dp-gelesen, 0));
}

/* --------------------------------------------------------------------------
   5 · Ruhiger Parallaxversatz für Schlüsselbilder
   Ebenfalls scroll-gebunden und ohne JavaScript. Der Versatz ist klein
   gehalten: er soll Tiefe andeuten, nicht auffallen.
   -------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
  [data-parallax] {
    animation: dp-parallax linear both;
    animation-timeline: view(block);
    animation-range: entry 0% exit 100%;
  }
  @keyframes dp-parallax {
    from { transform: translate3d(0, 22px, 0); }
    to   { transform: translate3d(0, -22px, 0); }
  }
}

/* --------------------------------------------------------------------------
   6 · Rückmeldung beim Bedienen
   -------------------------------------------------------------------------- */
.btn-primary, .btn-ghost, .dp-menue-liste a, .fuss-liste a {
  transition: background-color 0.28s var(--dp-ease),
              border-color 0.28s var(--dp-ease),
              color 0.28s var(--dp-ease),
              transform 0.18s var(--dp-ease),
              box-shadow 0.28s var(--dp-ease);
}
.btn-primary:active, .btn-ghost:active { transform: translateY(1px) scale(0.99); }

/* Karten heben sich beim Überfahren etwas deutlicher, aber ruhig. */
.card-hover { transition: transform 0.5s var(--dp-ease-weich), border-color 0.4s, background-color 0.4s; }

/* --------------------------------------------------------------------------
   7 · Reduzierte Bewegung
   Alles wird sofort sichtbar, nichts bewegt sich. Kein Inhalt darf von der
   Einstellung abhängen.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-anim],
  [data-stufen] > *,
  [data-stufen].ist-da > * {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    filter: none !important;
    transition: none !important;
    animation: none !important;
    will-change: auto !important;
  }
  .dp-fortschritt { display: none; }
  [data-parallax] { animation: none !important; transform: none !important; }
  .btn-primary:active, .btn-ghost:active { transform: none; }
}

/* --------------------------------------------------------------------------
   8 · Ablauf: die Ziffernscheibe ist ein Knoten auf der Linie
   Sie muss decken. Vorher trug sie `glass-strong` (halbtransparent), und der
   Hover ersetzte die Fläche durch zehn Prozent Deckkraft -- dadurch schien
   die Verbindungslinie mitten durch die Scheibe.
   -------------------------------------------------------------------------- */
.ablauf-marke {
  background: var(--bg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow);
  transition: background-color 0.3s var(--dp-ease),
              border-color 0.3s var(--dp-ease);
}
.group:hover .ablauf-marke {
  /* Deckender Farbauftrag statt Alphawert, damit nichts durchscheint. */
  background: color-mix(in srgb, #FF9600 12%, var(--bg));
  border-color: rgba(255, 150, 0, 0.45);
}
@supports not (background: color-mix(in srgb, red 10%, blue)) {
  .group:hover .ablauf-marke { background: var(--surface-strong, var(--bg)); }
}

/* --------------------------------------------------------------------------
   9 · Markenclaim im Hero
   Vorher eine Glas-Pille mit 0.25em Sperrung -- also genau das Chip-Muster,
   das die Seite sonst losgeworden ist. Jetzt trägt der Claim sich selbst:
   schwerer Schnitt, enge Sperrung, kein Rahmen.
   -------------------------------------------------------------------------- */
.hero-claim {
  margin: 0;
  font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t75);
  line-height: 1.2;
}
.hero-claim .plus-orange {
  margin-inline: 0.28em;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   10 · Feinschliff: Überschriften Zeichen für Zeichen
   Nur auf Seiten mit <html data-bewegung="fein">. Das Skript zerlegt die
   Überschrift und setzt [data-zeichen]; ohne Skript greift hier nichts.
   Reine Deckkraft, kein Versatz: so bleibt die Laufweite der Schrift
   unberührt und nichts springt.
   -------------------------------------------------------------------------- */
.dp-wort { white-space: nowrap; }
[data-zeichen] .dp-zeichen {
  transition: opacity 180ms cubic-bezier(0.215, 0.61, 0.355, 1) var(--zv, 0ms);
}
[data-zeichen]:not(.zeichen-da) .dp-zeichen { opacity: 0; }

/* --------------------------------------------------------------------------
   11 · Feinschliff: Block-Reveal für Fotos
   Der Block liegt über dem Bild und wird per clip-path gezeichnet (siehe
   medienAbspielen in dp-animation.js). Farbe: Tinte der Seite, im dunklen
   Modus also hell -- der Block soll sich vom Grund abheben.
   -------------------------------------------------------------------------- */
[data-medien],
[data-medien-kachel] { position: relative; }

/* Kachel vor dem Aufdecken: keine Fläche, kein Rand, kein Schatten. Nur
   die Hülle, die beim Entfernen der Klasse wieder sichtbar wird. */
.medien-leer {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
/* .card-hover bringt eigene Übergänge mit (inkl. transform für den
   Hover) und darf nicht überschrieben werden. */
[data-medien-kachel]:not(.card-hover) {
  transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.dp-block {
  --dp-block-akzent: #FF9600;
  --dp-block-farbe: var(--t95, #0c1621);
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: var(--dp-block-farbe);
  clip-path: inset(0 0 100% 100%);
}
.medien-warten img { opacity: 0; }
.medien-laeuft img { will-change: opacity, filter, transform; }

@media (prefers-reduced-motion: reduce) {
  [data-zeichen] .dp-zeichen { opacity: 1 !important; transition: none !important; }
  .medien-warten img { opacity: 1 !important; }
  .dp-block { display: none; }
}

/* --------------------------------------------------------------------------
   12 · Feinschliff: Ablauf-Leiste Schritt für Schritt
   --schritt setzt das Skript je Schritt (380 ms Takt). Kreis springt auf,
   Text folgt, dann zieht die Linie nach rechts zum nächsten Kreis.
   Die Übergänge hängen nur am Aufbau (.ablauf-da). Hingen sie immer, liefe
   das Verstecken beim Einrichten mit denselben Verzügen ab: die hinteren
   Schritte stünden noch sekundenlang da und blendeten dann erst aus.
   -------------------------------------------------------------------------- */
[data-ablauf].ablauf-da > * > :first-child {
  transition: opacity 320ms var(--dp-ease) var(--schritt, 0ms),
              transform 420ms var(--dp-ease-setzen) var(--schritt, 0ms);
}
[data-ablauf].ablauf-da > * > :nth-child(n+2) {
  transition: opacity 420ms var(--dp-ease) calc(var(--schritt, 0ms) + 110ms),
              transform 420ms var(--dp-ease) calc(var(--schritt, 0ms) + 110ms);
}
[data-ablauf] > *::after { transform-origin: 0 50%; }
[data-ablauf].ablauf-da > *::after {
  transition: transform 250ms var(--dp-ease-weich) calc(var(--schritt, 0ms) + 130ms);
}
[data-ablauf]:not(.ablauf-da) > * > :first-child { opacity: 0; transform: scale(0.4); }
[data-ablauf]:not(.ablauf-da) > * > :nth-child(n+2) { opacity: 0; transform: translate3d(0, 8px, 0); }
[data-ablauf]:not(.ablauf-da) > *::after { transform: scaleX(0); }

@media (prefers-reduced-motion: reduce) {
  [data-ablauf] > * > *,
  [data-ablauf] > *::after { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* Mauslicht (dp-animation.js): weiches oranges Leuchten hinter dem Inhalt */
.dp-mauslicht { position: fixed; left: 0; top: 0; width: 640px; height: 640px; margin: -320px 0 0 -320px;
  border-radius: 50%; pointer-events: none; z-index: 0; opacity: 0; will-change: transform;
  background: radial-gradient(circle at center, rgba(255,150,0,0.10) 0%, rgba(255,150,0,0.045) 35%, rgba(255,150,0,0) 68%);
  transition: opacity .6s ease; }
.dp-mauslicht.ist-an { opacity: 1; }
:root:not([data-theme="dark"]) .dp-mauslicht {
  background: radial-gradient(circle at center, rgba(255,150,0,0.12) 0%, rgba(255,150,0,0.05) 35%, rgba(255,150,0,0) 68%); }
/* Mauszeiger: schwarzer Pfeil mit oranger statt weißer Kontur. Über
   Klickbarem wird daraus ein Kreis in derselben Machart, keine Hand.
   Nur bei Maus; Textfelder behalten den Textcursor. */
@media (hover: hover) and (pointer: fine) {
  html { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M5 2.5v17.2l4.3-4.1 2.9 6.5 2.9-1.3-2.8-6.3h6z' fill='%23000' stroke='%23FF9600' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E") 5 2, auto; }
  html body a[href], html body button:not(:disabled), html body [role="button"], html body [role="tab"],
  html body summary, html body label, html body select, html body .cursor-pointer, html body video {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='7.5' fill='none' stroke='%23FF9600' stroke-width='4.2'/%3E%3Ccircle cx='12' cy='12' r='7.5' fill='none' stroke='%23000' stroke-width='1.8'/%3E%3C/svg%3E") 12 12, pointer; }
  html body input:not([type="button"]):not([type="submit"]):not([type="checkbox"]):not([type="radio"]),
  html body textarea { cursor: text; }
}
@media (prefers-reduced-motion: reduce) { .dp-mauslicht { display: none; } }
