/* ============================================================
   pleyer ai - Bewegung
   Gehoert zu assets/bewegung.js. Eingebunden nach den uebrigen Stylesheets.

   Grundregel: Ohne JS ist alles der Endzustand und lesbar. Ausgangszustaende
   (versteckt, verschoben) stehen NUR unter diesen Klassen auf <html>, die
   bewegung.js setzt:
     .bw-anim    Reveals (Hero-Woerter, Titelzeilen); nicht bei reduzierter Bewegung
     .bw-scroll  Scrollkopplung; nur Desktop (ab 768 px), keine reduzierte Bewegung
     .bw-tl      Linie mit Punkten (Zeitleiste, Vorteile); wie .bw-scroll
   Animiert werden transform, opacity, filter. Ausnahmen (paint-only, an der Stelle
   kommentiert): box-shadow beim Karten-Hover.
   Alles bleibt dunkel: keine Farbwechsel, keine hellen Flaechen.
   Markenwerte kommen aus den Tokens in premium.css (--accent, --bg, --fg, --hair ...).
   ============================================================ */

:root {
  --bw-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ============================================================
   Hero - Headline wortweise (Woerter erzeugt bewegung.js)
   ============================================================ */
.bw-wort {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* Unterlaengen und kursive Ueberhaenge nicht abschneiden, ohne Layout zu verschieben */
  padding: 0.04em 0.06em 0.14em;
  margin: -0.04em -0.06em -0.14em;
}
.bw-wort__in { display: inline-block; }

html.bw-anim .bw-wort__in {
  transform: translateY(105%);
  opacity: 0;
}
html.bw-anim .bw-hero-titel.bw-an .bw-wort__in {
  transform: none;
  opacity: 1;
  transition: transform 700ms var(--bw-ease), opacity 700ms var(--bw-ease);
  transition-delay: calc(var(--i, 0) * 80ms);
}
/* Die h1 trug .reveal (Blur + Verschiebung). Nach dem Zerlegen animieren die Woerter,
   die h1 selbst bleibt ruhig, sonst liefe die Einblendung doppelt. */
html.bw-anim .bw-hero-titel.reveal {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}
/* Subline, Knoepfe, Kennzeilen erst nach dem letzten Wort (Wert setzt bewegung.js) */
html.bw-anim .hero__sub.reveal,
html.bw-anim .hero__ctas.reveal,
html.bw-anim .hero__meta-row.reveal,
html.bw-anim .bw-hero-titel ~ .reveal {
  transition-delay: var(--bw-nach, 0ms);
}

/* Hero-Verlaeufe leicht verstaerken (bestehende Orbs, kein zweites Hintergrundsystem) */
.bg-mesh__orb--1 { opacity: 0.32; }
.bg-mesh__orb--4 { opacity: 0.2; }

/* ============================================================
   Reveals - Titel zeilenweise, Raster gestaffelt
   ============================================================ */
.bw-zeile {
  display: block;
  overflow: hidden;
  padding: 0.06em 0.08em 0.16em;
  margin: -0.06em -0.08em -0.16em;
}
.bw-zeile__in { display: block; }

html.bw-anim .bw-titel .bw-zeile__in {
  transform: translateY(105%);
  opacity: 0;
}
html.bw-anim .bw-titel.bw-an .bw-zeile__in {
  transform: none;
  opacity: 1;
  transition: transform 500ms var(--bw-ease), opacity 500ms var(--bw-ease);
  transition-delay: calc(var(--z, 0) * 90ms);
}
/* Alte Reveal-Einblendung der Titel ersetzt die Zeilenanimation */
html.bw-anim .bw-titel.reveal {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}

/* Gestaffelte Kinder: --i = Position in der Reihe (setzt bewegung.js).
   Die Verzoegerung wirkt auf das bestehende .reveal der Karten. */
html.bw-anim .bw-raster > .reveal {
  transition-delay: calc(var(--i, 0) * 80ms);
}
/* Karten: Staffel nur fuer die Einblendung (opacity, transform, filter), nicht fuer Hover
   (translate, box-shadow, border-color), sonst reagierte die dritte Karte erst spaeter. */
html.bw-anim .bw-raster > :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card).reveal {
  transition-delay:
    calc(var(--i, 0) * 80ms), calc(var(--i, 0) * 80ms), calc(var(--i, 0) * 80ms),
    0ms, 0ms, 0ms;
}

/* Notbremse: wer nach einigen Sekunden im Bild noch versteckt ist, wird sofort gezeigt */
.bw-sofort .bw-wort__in,
.bw-sofort .bw-zeile__in {
  transform: none !important;
  opacity: 1 !important;
  transition: none !important;
}

/* ============================================================
   Nav - Insel schrumpft beim Runterscrollen, aktiver Punkt
   ============================================================ */
.nav {
  position: relative;
  transform-origin: 50% 0;
}
/* Verstaerkter Schatten ueber Pseudoelement: nur opacity wird animiert */
.nav::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  box-shadow: 0 18px 40px -8px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(255, 255, 255, 0.04);
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .nav {
    transition: transform 300ms var(--bw-ease);
  }
  .nav::after {
    transition: opacity 300ms var(--bw-ease);
  }
  .nav.bw-nav-klein {
    transform: scale(0.96);
  }
  .nav.bw-nav-klein::after {
    opacity: 1;
  }
}

/* Aktiver Punkt: Lime-Flaeche, schwarze Schrift */
.nav__link.bw-aktiv,
.nav__link.bw-aktiv:hover,
.nav__mobile-link.bw-aktiv {
  background: var(--accent);
  color: #0a0a0a;
}
/* Sichtbarer Tastaturfokus in der Insel (auch auf dem aktiven Lime-Punkt) */
.nav__link:focus-visible,
.nav__cta:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
  border-radius: 999px;
  color: var(--fg);
}
.nav__link.bw-aktiv:focus-visible {
  color: #0a0a0a;
}

/* Ohne backdrop-filter: deckender dunkler Hintergrund statt Glas */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav {
    background: rgba(14, 14, 14, 0.97);
  }
}

/* ============================================================
   Karten - Hover-Anheben, Mausfolge-Licht, Randglow
   Kartentypen: Leistungen (.bento__card), Vorteile (.vorteile__card), Umsetzung (.impl-card),
   Infrastruktur (.infra-card, .principle-item), Preise (.price-card), Branchen und Blog
   (.branchen__card). Keine Formulare, Umschalter oder Akkordeons.
   --x / --y setzt bewegung.js (Pixel relativ zur Karte, per rAF gedrosselt).
   Nur mit Maus, ab 768 px, ohne reduzierte Bewegung.
   ============================================================ */
@media (hover: hover) and (pointer: fine) and (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card) {
    position: relative;
    isolation: isolate;
  }
  /* Das bestehende .reveal animiert opacity/transform/filter 800 ms; das Anheben
     laeuft ueber die eigene Eigenschaft "translate", damit beides nebeneinander geht. */
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card).reveal {
    transition:
      opacity 800ms var(--ease-out),
      transform 800ms var(--ease-out),
      filter 800ms var(--ease-out),
      translate 300ms var(--bw-ease),
      box-shadow 300ms var(--bw-ease),
      border-color 300ms var(--bw-ease);
  }
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card):not(.reveal) {
    transition:
      transform 300ms var(--bw-ease),
      translate 300ms var(--bw-ease),
      box-shadow 300ms var(--bw-ease),
      border-color 300ms var(--bw-ease),
      background-color 300ms var(--bw-ease);
  }
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card):hover {
    translate: 0 -6px;
    /* box-shadow statt filter, weil .reveal den filter belegt; paint-only, nur eine Karte gleichzeitig */
    box-shadow: 0 26px 48px -18px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(191, 255, 0, 0.08);
    border-color: rgba(191, 255, 0, 0.22);
  }
  /* Karten ohne .reveal hoben sich schon ueber transform: nicht doppelt anheben */
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card):not(.reveal):hover {
    transform: none;
  }

  /* Mausfolge-Licht (hinter dem Karteninhalt) */
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card)::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: radial-gradient(400px circle at var(--x, 50%) var(--y, 50%), rgba(191, 255, 0, 0.15), transparent 40%);
    opacity: 0;
    transition: opacity 300ms var(--bw-ease);
    pointer-events: none;
  }
  /* Randglow: nur der 1-px-Rand leuchtet (Maske mit mask-composite) */
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card)::after {
    content: "";
    position: absolute;
    inset: 0;
    padding: 1px;
    border-radius: inherit;
    background: radial-gradient(260px circle at var(--x, 50%) var(--y, 50%), rgba(191, 255, 0, 0.75), transparent 60%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    opacity: 0;
    transition: opacity 300ms var(--bw-ease);
    pointer-events: none;
  }
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card):hover::before,
  :is(.bento__card, .vorteile__card, .impl-card, .infra-card, .principle-item, .price-card, .branchen__card):hover::after {
    opacity: 1;
  }
}

/* ============================================================
   Leuchtende Linie mit Punkten
   - Zeitleiste: Schrittfolgen mit grosser Zahl (.bw-zeitleiste: #ablauf .steps, .timeline)
   - Vorteile: Linie links am Raster (#vorteile .vorteile, nur Startseite)
   Nur unter html.bw-tl (JS, ab 768 px, ohne reduzierte Bewegung); sonst bleibt das Original.
   Spur plus Lime-Linie, --bw-l = Fortschritt 0..1, --bw-x = Abstand von links.
   ============================================================ */
.bw-tl-nummer { display: none; }
.bw-punkt { display: none; }

@media (min-width: 768px) {
  html.bw-tl .bw-zeitleiste,
  html.bw-tl #vorteile .vorteile {
    position: relative;
  }
  html.bw-tl .bw-zeitleiste::before,
  html.bw-tl .bw-zeitleiste::after,
  html.bw-tl #vorteile .vorteile::before,
  html.bw-tl #vorteile .vorteile::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--bw-x, 0);
    width: 2px;
    border-radius: 2px;
    pointer-events: none;
  }
  html.bw-tl .bw-zeitleiste::before,
  html.bw-tl #vorteile .vorteile::before { background: rgba(255, 255, 255, 0.1); }
  html.bw-tl .bw-zeitleiste::after,
  html.bw-tl #vorteile .vorteile::after {
    background: var(--accent);
    transform-origin: 50% 0;
    transform: scaleY(var(--bw-l, 0));
    filter: drop-shadow(0 0 8px rgba(191, 255, 0, 0.75));
  }
  html.bw-tl .bw-punkt { display: block; }

  /* Vorteile: Linie links am Raster, Platz dafuer ueber Innenabstand */
  html.bw-tl #vorteile .vorteile {
    --bw-x: 12px;
    padding-left: 44px;
  }
  html.bw-tl #vorteile .vorteile .bw-punkt { left: 6px; }

  /* Zeitleiste: Zahlenspalte links, Schritte rechts */
  html.bw-tl .bw-zeitleiste {
    --bw-nr: clamp(110px, 20vw, 280px);
    --bw-gap: 56px;
    --bw-x: calc(var(--bw-nr) + var(--bw-gap) / 2 - 1px);
    display: grid;
    grid-template-columns: var(--bw-nr) minmax(0, 1fr);
    column-gap: var(--bw-gap);
    row-gap: 22px;
    max-width: 980px;
    margin: 0 auto;
  }
  /* Grosse Schrittnummer, wechselt mit der Linie */
  html.bw-tl .bw-tl-nummer {
    display: block;
    grid-column: 1;
    grid-row: 1 / span var(--bw-n, 3);
    align-self: start;
    position: sticky;
    top: 30vh;
    pointer-events: none;
    user-select: none;
  }
  .bw-tl-nummer__z {
    display: block;
    font-family: 'Geist', sans-serif;
    font-weight: 700;
    font-size: clamp(5rem, 11vw, 9rem);
    line-height: 1;
    letter-spacing: -0.06em;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
    text-shadow: 0 0 40px rgba(191, 255, 0, 0.25);
  }
  .bw-tl-nummer__z.bw-wechsel {
    animation: bw-zahl 420ms var(--bw-ease);
  }

  html.bw-tl .bw-zeitleiste > .step,
  html.bw-tl .bw-zeitleiste > .timeline-step {
    grid-column: 2;
  }
  /* Punkt an der Linie: Schritte (Pseudoelement) und Vorteile-Zeilen (.bw-punkt aus bewegung.js) */
  html.bw-tl .bw-zeitleiste > .step::before,
  html.bw-tl .bw-zeitleiste > .timeline-step::before,
  .bw-punkt {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--bg);
    border: 2px solid rgba(255, 255, 255, 0.25);
    box-sizing: border-box;
    pointer-events: none;
    transition: transform 400ms var(--bw-ease), background-color 300ms var(--bw-ease), border-color 300ms var(--bw-ease);
  }
  html.bw-tl .bw-zeitleiste > .step::before {
    top: 44px;
    left: calc(var(--bw-gap) / -2 - 7px);
  }
  /* Ablauf-Seite: Punkt auf Hoehe der Schrittzahl im Kasten */
  html.bw-tl .bw-zeitleiste > .timeline-step::before {
    top: 47px;
    left: calc(var(--bw-gap) / -2 - 7px);
  }
  html.bw-tl .bw-zeitleiste > .step.bw-an::before,
  html.bw-tl .bw-zeitleiste > .timeline-step.bw-an::before,
  html.bw-tl .bw-punkt.bw-an {
    background: var(--accent);
    border-color: var(--accent);
    transform: scale(1.35);
    box-shadow: 0 0 0 5px rgba(191, 255, 0, 0.18), 0 0 14px rgba(191, 255, 0, 0.7);
  }

  /* Texte kommen seitlich (translateX), ersetzt das senkrechte Reveal der Schritte */
  html.bw-anim.bw-tl .bw-zeitleiste > .reveal {
    transform: translateX(30px);
  }
  html.bw-anim.bw-tl .bw-zeitleiste > .reveal.is-in {
    transform: none;
  }
}

@keyframes bw-zahl {
  from { transform: translateY(40%); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* ============================================================
   Reduzierte Bewegung: nichts verschoben, nichts versteckt, keine Uebergaenge
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .bw-wort__in,
  .bw-zeile__in {
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
  }
  .nav,
  .nav::after {
    transition: none !important;
  }
  .nav.bw-nav-klein { transform: none; }
  .bw-tl-nummer__z.bw-wechsel { animation: none; }
}

/* ============================================================
   Zahlen hochzaehlen: feste Ziffernbreite, Wert fuer Screenreader
   ============================================================ */
.bw-zahl {
  display: inline-block;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.bw-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   Blog: Quellen einklappbar (<details class="blog-quellen-klappe" id="quellen">)
   Ohne JS bedienbar (natives details). bewegung.js oeffnet den Block bei Verweisen
   auf #quellen und #quelle-N.
   ============================================================ */
.blog-quellen-klappe {
  margin: 56px 0 18px;
  border-top: 1px solid var(--hair);
  scroll-margin-top: 110px;
}
.blog-quellen-klappe > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 24px 0;
  cursor: pointer;
  list-style: none;
  border-radius: 8px;
}
.blog-quellen-klappe > summary::-webkit-details-marker { display: none; }
.blog-quellen-klappe > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
/* Titel der summary: Maße der Textueberschriften, aber ohne eigenen Abstand und Strich */
.blog-text .blog-quellen-klappe__titel {
  margin: 0;
  padding: 0;
  border: 0;
}
.blog-quellen-klappe__zahl {
  font-family: 'Geist Mono', monospace;
  font-size: 0.9375rem;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
/* Plus in Lime, dreht sich beim Oeffnen zum Kreuz */
.blog-quellen-klappe > summary::after {
  content: "+";
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  margin-left: auto;
  border: 1px solid var(--hair-strong);
  border-radius: 50%;
  color: var(--accent);
  font-size: 1.25rem;
  line-height: 1;
  transition: transform 300ms var(--bw-ease), border-color 300ms var(--bw-ease);
}
.blog-quellen-klappe > summary:hover::after { border-color: var(--accent); }
.blog-quellen-klappe[open] > summary::after { transform: rotate(45deg); }
.blog-quellen-klappe > .blog-quellen { margin-top: 0; }
@media (max-width: 720px) {
  .blog-quellen-klappe { margin-top: 44px; }
}
@media (prefers-reduced-motion: reduce) {
  .blog-quellen-klappe > summary::after { transition: none; }
}
