/* ============================================================================
 * leap.css — #leap · In-Place Scroll-Zoom-Subpage
 *
 * Ein gerahmtes Fenster sitzt MITTIG auf der #spark-Figur (im leeren Center des
 * Service-Sliders — genau dort, wo der rote Kasten war). Es zeigt das Bild der
 * aktuell gewaehlten Folie. Scrollt man weiter, zoomt das Fenster AN ORT UND
 * STELLE auf Vollbild und wird zur Unterseite, durch die man weiterscrollt.
 *
 * WICHTIG (Stacking): .leap ist ein BODY-Kind (Geschwister von <main> + der
 * .spark-stream-Figur-Canvas z6), darum greift hier ein echtes z-index 8 —
 * ueber der Figur (z6), unter der Nav (#hdr z9). Laege es in <main> (eigener
 * z-Kontext), wuerde die Figur-Canvas drueberzeichnen (alter Bug).
 *
 * Geometrie (Position / Groesse / Zoom / Subpage-Scroll) setzt leap.js LIVE per
 * Inline-Style aus EINER Quelle (window.scrollY). Hier nur Aussehen + Defaults.
 * Vanilla, kein GSAP.
 * ==========================================================================*/

.leap {
  position: fixed; inset: 0;
  z-index: 5;                         /* STABLE: HINTER der Figur-Canvas (z6) — der Punkt-Mann
                                         steht VOR dem Fenster. Beim Zoom -> z8 (siehe .is-zooming). */
  pointer-events: none;
  opacity: 0; visibility: hidden;
  --sb: #2ea2ff;
  --leap-tint: #2ea2ff;
  --leap-frameglow: 1;
  font-family: "Outfit", system-ui, -apple-system, sans-serif;
}
.leap.is-visible { visibility: visible; }        /* opacity steuert leap.js */
/* sobald gezoomt wird, hebt sich das Fenster UEBER die Figur (z6), unter die Nav (#hdr z9),
   damit die Vollbild-Unterseite die Punkt-Figur + Slider sauber verdeckt. */
.leap.is-zooming { z-index: 8; }

/* dunkler Vorhang, der die Szene (Figur + Slider) beim Hineinzoomen schluckt */
.leap__backdrop {
  position: fixed; inset: 0;
  background: #02030a;
  opacity: 0;                          /* leap.js: 0 -> 1 mit dem Zoom */
}

/* ---- das Fenster — Position/Groesse/Radius interpoliert leap.js (Box->Voll) */
.leap__frame {
  position: fixed; left: 0; top: 0; width: 540px; height: 360px;
  overflow: hidden; border-radius: 18px;
  background: #04060d;
  box-shadow: 0 40px 90px -34px rgba(0, 0, 0, .82);
  will-change: left, top, width, height;
}
.leap__frame::after {                  /* feiner Leuchtrahmen (Box-Phase), faded beim Zoom */
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  border: 1px solid var(--leap-tint);
  box-shadow: 0 0 46px -8px var(--leap-tint), 0 0 0 1px rgba(124, 198, 255, .12) inset;
  opacity: calc(var(--leap-frameglow) * .85);
  pointer-events: none;
}
.leap.is-full .leap__frame { pointer-events: auto; }   /* Vollbild: Links/Buttons klickbar */

/* ---- Entrance: das Fenster ERSCHEINT mit einer ruhigen Anim, sobald man VOLL in
   #showcase ist (leap.js setzt .is-entered). Nur opacity/transform -> stoert die
   left/top/width/height-Zoom-Interpolation NICHT (im Zoom ist transform = none). */
.leap__frame {
  opacity: 0;
  transform: translateY(42px) scale(.94);
  filter: blur(7px);
  transition: opacity .6s ease, transform 1s cubic-bezier(.16, 1, .3, 1), filter .7s ease;
}
.leap.is-entered .leap__frame { opacity: 1; transform: none; filter: none; }

/* gestaffeltes Hereinkommen der Hero-Texte (Tag/Kicker/Titel/Subzeile) */
.leap__tag, .leap__kicker, .leap__title, .leap__sub {
  opacity: 0; transform: translateY(18px);
  transition: opacity .5s ease, transform .7s cubic-bezier(.22, .61, .36, 1);
}
.leap.is-entered .leap__tag    { opacity: 1; transform: none; transition-delay: .14s; }
.leap.is-entered .leap__kicker { opacity: 1; transform: none; transition-delay: .22s; }
.leap.is-entered .leap__title  { opacity: 1; transform: none; transition-delay: .30s; }
.leap.is-entered .leap__sub    { opacity: 1; transform: none; transition-delay: .40s; }

/* ---- die ganze Unterseite — wird per translateY hochgescrollt (leap.js) ---- */
.leap__doc { position: absolute; top: 0; left: 0; width: 100%; will-change: transform; }

/* HERO = was in der Box sichtbar ist; Hoehe = aktuelle Fensterhoehe (leap.js) */
.leap__hero {
  position: relative; width: 100%; min-height: 360px;
  display: flex; align-items: flex-end; overflow: hidden;
}
.leap__bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  transform: scale(1.06);
}
.leap__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(2, 3, 10, .30) 0%, rgba(2, 3, 10, .18) 38%, rgba(2, 3, 10, .88) 100%);
}
.leap__tag {
  position: absolute; top: 16px; left: 18px; z-index: 2;
  font: 600 11px/1 "Outfit", sans-serif; letter-spacing: .18em; text-transform: uppercase;
  color: #cfe4ff; padding: 6px 11px; border-radius: 999px;
  background: rgba(4, 8, 18, .5); border: 1px solid rgba(124, 198, 255, .25);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.leap__hero-inner { position: relative; z-index: 2; padding: clamp(20px, 3.4vw, 56px); max-width: 900px; }
.leap__kicker {
  display: block; font: 600 12px/1 "Outfit", sans-serif; letter-spacing: .24em;
  text-transform: uppercase; color: var(--leap-tint); margin-bottom: 12px;
}
.leap__title {
  margin: 0; font-family: "Bebas Neue", "Outfit", sans-serif; font-weight: 400;
  font-size: clamp(36px, 7.2vw, 104px); line-height: .9; letter-spacing: .012em;
  color: #fff; text-transform: uppercase;
}
.leap__sub {
  margin: 16px 0 0; max-width: 56ch;
  font-size: clamp(14px, 1.2vw, 19px); line-height: 1.5; color: #b9c6dd;
}
.leap__hint {
  position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 3;
  display: inline-flex; align-items: center; gap: 9px;
  font: 600 11px/1 "Outfit", sans-serif; letter-spacing: .16em; text-transform: uppercase;
  color: #dce8ff; white-space: nowrap;
  padding: 9px 15px; border-radius: 999px;
  background: rgba(4, 8, 18, .55); border: 1px solid rgba(124, 198, 255, .25);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.leap__hint i {
  width: 12px; height: 12px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); animation: leap-bob 1.5s ease-in-out infinite;
}
@keyframes leap-bob { 0%, 100% { transform: rotate(45deg) translate(0, 0); } 50% { transform: rotate(45deg) translate(3px, 3px); } }

/* ---- BODY = die eigentliche Unterseite unter dem Hero ---------------------- */
.leap__body {
  position: relative; background: #04060d; color: #d6e2f3;
  padding: clamp(44px, 8vh, 104px) clamp(20px, 6vw, 92px) clamp(80px, 12vh, 168px);
}
.leap__wrap { max-width: 1040px; margin: 0 auto; display: grid; gap: clamp(36px, 5.4vh, 72px); }
.leap__label {
  display: inline-flex; align-items: center; gap: 9px; margin-bottom: 14px;
  font: 600 12px/1 "Outfit", sans-serif; letter-spacing: .18em; text-transform: uppercase;
  color: var(--leap-tint);
}
.leap__label i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.leap__h {
  margin: 0 0 14px; font-family: "Bebas Neue", "Outfit", sans-serif; font-weight: 400;
  font-size: clamp(26px, 3.6vw, 50px); line-height: 1; color: #fff;
  text-transform: uppercase; letter-spacing: .012em;
}
.leap__p { margin: 0; font-size: clamp(15px, 1.25vw, 19px); line-height: 1.65; color: #b9c6dd; max-width: 70ch; }

.leap__steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 1.6vw, 22px); }
.leap__step {
  background: rgba(124, 198, 255, .04); border: 1px solid rgba(124, 198, 255, .12);
  border-radius: 14px; padding: clamp(18px, 1.7vw, 28px);
}
.leap__step-n { font: 600 11px/1 "Outfit", sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--leap-tint); }
.leap__step h4 { margin: 12px 0 8px; font-size: clamp(16px, 1.3vw, 21px); color: #fff; }
.leap__step p { margin: 0; font-size: 14px; line-height: 1.55; color: #9fb0c8; }

/* ---- Demo-Rahmen (16:9): aeusserer Container fuer alle folien-spezifischen
   Mockups. FESTE Hoehe via aspect-ratio -> measure() bleibt deterministisch.
   overflow:hidden, damit kein Inhalt die gemessene Hoehe sprengt. ------------ */
.leap__demo {
  position: relative; overflow: hidden;
  border: 1px solid rgba(124, 198, 255, .14); border-radius: 16px; aspect-ratio: 16 / 9;
  background: radial-gradient(120% 120% at 50% 0%, rgba(46, 162, 255, .08), rgba(4, 8, 18, .4));
  color: #d6e2f3;
}

/* =========================================================================
   DEMO Folie 0 — KI-Assistenz: Chat-Mockup
   Bubbles starten unsichtbar; .is-playing (Body, von leap.js bei is-full)
   blendet sie gestaffelt ein, --k liefert den Versatz. Tipp-Indikator
   pulsiert. reduced-motion -> alles statisch sichtbar.
   ========================================================================= */
.leap-chat {
  position: absolute; inset: 0; overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px;
  padding: clamp(16px, 2.4vw, 30px);
  background: linear-gradient(180deg, rgba(4, 8, 18, .2), rgba(2, 3, 10, .55));
}
.leap-chat__row { display: flex; max-width: 78%; }
.leap-chat__row--user { align-self: flex-end; justify-content: flex-end; }
.leap-chat__row--bot  { align-self: flex-start; }
.leap-chat__bubble {
  padding: 10px 14px; border-radius: 16px; font-size: clamp(13px, 1.05vw, 15px); line-height: 1.45;
}
.leap-chat__row--user .leap-chat__bubble {
  background: var(--leap-tint); color: #02030a; border-bottom-right-radius: 5px; font-weight: 500;
}
.leap-chat__row--bot .leap-chat__bubble {
  background: rgba(124, 198, 255, .08); border: 1px solid rgba(124, 198, 255, .14);
  color: #e2ecfb; border-bottom-left-radius: 5px;
}
/* Tipp-Indikator (drei Punkte) */
.leap-chat__typing .leap-chat__bubble { display: inline-flex; gap: 5px; padding: 13px 15px; }
.leap-chat__typing i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--leap-tint); opacity: .55;
}
/* Standardzustand: sichtbar (reduced-motion + no-JS sind so lesbar) */
.leap-chat__row { opacity: 1; transform: none; }
/* Spielzustand: erst unsichtbar, dann gestaffelt einblenden */
.is-playing .leap-chat__row {
  opacity: 0; transform: translateY(10px);
  animation: leap-chat-in .45s cubic-bezier(.22, .61, .36, 1) forwards;
  animation-delay: calc(var(--k) * .8s + .25s);
}
.is-playing .leap-chat__typing {
  /* Tipp-Indikator erscheint kurz und verschwindet wieder (letzte Bubble uebernimmt) */
  animation: leap-chat-in .4s ease forwards, leap-chat-out .4s ease forwards;
  animation-delay: calc((var(--k) - 1) * .8s + .25s), calc(var(--k) * .8s);
}
.is-playing .leap-chat__typing i { animation: leap-typing 1s ease-in-out infinite; }
.is-playing .leap-chat__typing i:nth-child(2) { animation-delay: .15s; }
.is-playing .leap-chat__typing i:nth-child(3) { animation-delay: .3s; }
@keyframes leap-chat-in  { to { opacity: 1; transform: none; } }
@keyframes leap-chat-out { to { opacity: 0; height: 0; margin: 0; padding: 0; } }
@keyframes leap-typing   { 0%, 100% { opacity: .35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }

/* =========================================================================
   DEMO Folie 1 — Telefonie: Anruf-Mockup (Timer, Play/Pause, Wellenform)
   Wellenform animiert nur im .is-playing-Zustand UND wenn der Button aktiv
   ist (.is-on, von leap.js gesetzt). Hoehe fix -> Layout stabil.
   ========================================================================= */
.leap-call {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center; gap: clamp(18px, 3vh, 34px);
  padding: clamp(20px, 3vw, 40px);
  background: radial-gradient(120% 100% at 50% 0%, rgba(46, 162, 255, .1), rgba(2, 3, 10, .5));
}
.leap-call__top { display: flex; align-items: center; gap: 14px; }
.leap-call__avatar {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font: 700 15px/1 "Outfit", sans-serif; color: #02030a;
  background: var(--leap-tint);
}
.leap-call__who { display: flex; flex-direction: column; gap: 3px; }
.leap-call__who strong { color: #fff; font-size: clamp(15px, 1.3vw, 18px); }
.leap-call__who span  { color: #9fb0c8; font-size: 13px; }
.leap-call__time {
  margin-left: auto; font: 600 16px/1 "Outfit", sans-serif; color: var(--leap-tint);
  font-variant-numeric: tabular-nums; letter-spacing: .04em;
}
.leap-call__wave {
  display: flex; align-items: center; justify-content: center; gap: 4px; height: clamp(54px, 9vh, 92px);
}
.leap-call__wave i {
  width: 4px; height: 24%; border-radius: 999px; background: var(--leap-tint); opacity: .5;
  transform-origin: center;
}
/* nur waehrend aktiver Wiedergabe pulsiert die Welle */
.leap-call.is-on .leap-call__wave i {
  animation: leap-wave 1.1s ease-in-out infinite;
  animation-delay: calc(var(--k) * -.07s);
}
@keyframes leap-wave { 0%, 100% { transform: scaleY(.3); opacity: .45; } 50% { transform: scaleY(1); opacity: 1; } }
.leap-call__controls { display: flex; align-items: center; justify-content: center; gap: 14px; }
.leap-call__btn {
  width: 56px; height: 56px; border-radius: 50%; border: none; cursor: pointer; flex: none;
  display: grid; place-items: center; color: #02030a; background: var(--leap-tint);
  transition: filter .2s ease, transform .2s ease;
}
.leap-call__btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.leap-call__btn .ic-pause { display: none; }
.leap-call.is-on .leap-call__btn .ic-play  { display: none; }
.leap-call.is-on .leap-call__btn .ic-pause { display: block; }
.leap-call__hint { color: #9fb0c8; font-size: 13px; }

/* =========================================================================
   DEMO Folie 2 — Workflow: animiertes Flow-Diagramm
   Knoten + Verbindungslinien leuchten sequenziell und loopen sanft, solange
   .is-playing aktiv ist. --k staffelt die Reihenfolge.
   ========================================================================= */
.leap-flow {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0;
  padding: clamp(18px, 3vw, 40px);
}
.leap-flow__node {
  position: relative; flex: none; width: clamp(86px, 11vw, 130px);
  display: flex; flex-direction: column; align-items: center; gap: 5px; text-align: center;
  padding: clamp(12px, 1.4vw, 18px) 8px; border-radius: 14px;
  background: rgba(124, 198, 255, .04); border: 1px solid rgba(124, 198, 255, .14);
  opacity: .5; transition: opacity .3s ease;
}
.leap-flow__node strong { color: #fff; font-size: clamp(12px, 1.05vw, 15px); }
.leap-flow__node span   { color: #9fb0c8; font-size: clamp(10px, .9vw, 12px); }
.leap-flow__dot {
  width: 12px; height: 12px; border-radius: 50%; background: var(--leap-tint); opacity: .55;
  transition: opacity .3s ease, box-shadow .3s ease;
}
.leap-flow__link { flex: none; width: clamp(24px, 4vw, 56px); height: 2px; position: relative; background: rgba(124, 198, 255, .14); }
.leap-flow__link i {
  position: absolute; inset: 0; width: 0; background: var(--leap-tint);
  box-shadow: 0 0 10px var(--leap-tint);
}
/* sequenzielles Aufleuchten im Loop (Gesamtzyklus ~4.8s = 4 Knoten * 1.2s) */
.is-playing .leap-flow__node {
  animation: leap-node 4.8s ease-in-out infinite;
  animation-delay: calc(var(--k) * 1.2s);
}
.is-playing .leap-flow__dot {
  animation: leap-dot 4.8s ease-in-out infinite;
  animation-delay: calc(var(--k) * 1.2s);
}
.is-playing .leap-flow__link i {
  animation: leap-fill 4.8s ease-in-out infinite;
  animation-delay: calc(var(--k) * 1.2s + .6s);
}
@keyframes leap-node { 0%, 8% { opacity: .5; } 12%, 22% { opacity: 1; } 30%, 100% { opacity: .5; } }
@keyframes leap-dot  { 0%, 8% { opacity: .55; box-shadow: 0 0 0 0 var(--leap-tint); }
                        12%, 22% { opacity: 1; box-shadow: 0 0 14px 2px var(--leap-tint); }
                        30%, 100% { opacity: .55; box-shadow: 0 0 0 0 var(--leap-tint); } }
@keyframes leap-fill { 0%, 8% { width: 0; } 18% { width: 100%; } 100% { width: 100%; } }

/* reduced-motion: alle Demos im finalen, statischen, lesbaren Zustand. */
@media (prefers-reduced-motion: reduce) {
  .is-playing .leap-chat__row { opacity: 1; transform: none; animation: none; }
  .leap-chat__typing { display: none; }
  .leap-call.is-on .leap-call__wave i { animation: none; transform: scaleY(.6); opacity: .8; }
  .is-playing .leap-flow__node { opacity: 1; animation: none; }
  .is-playing .leap-flow__dot { opacity: 1; box-shadow: 0 0 10px var(--leap-tint); animation: none; }
  .is-playing .leap-flow__link i { width: 100%; animation: none; }
}

/* ---- Calendly-Buchung — die neue Primaer-Aktion. Dunkle Card im Markenlook,
   der Widget-Container reserviert FESTE Hoehe (auch vor dem Init), damit
   measure() / das Layout stabil bleiben. ----------------------------------- */
.leap__book {
  padding: clamp(24px, 3.2vw, 44px);
  border: 1px solid rgba(124, 198, 255, .16); border-radius: 18px;
  background: radial-gradient(130% 130% at 50% 0%, rgba(46, 162, 255, .1), rgba(4, 8, 18, .3));
}
.leap__book .leap__p { margin-bottom: 22px; }
.leap__book .calendly-inline-widget {
  min-height: 630px;                 /* Hoehe reserviert -> kein Sprung beim Lazy-Init */
  border-radius: 14px; overflow: hidden;
  background: #04060d; border: 1px solid rgba(124, 198, 255, .12);
}
/* Vor dem Init: nur der Fallback-Link liegt drin -> zentriert anzeigen.
   Nach dem Init ersetzt Calendly den Inhalt durch ein <iframe> (kein .leap__btn
   mehr) -> diese Regel greift nicht mehr, das iframe fuellt den Container. */
.leap__book .calendly-inline-widget:has(.leap__btn) {
  display: flex; align-items: center; justify-content: center;
}

.leap__cta {
  text-align: center; padding: clamp(32px, 4.4vw, 64px);
  border: 1px solid rgba(124, 198, 255, .16); border-radius: 18px;
  background: radial-gradient(130% 130% at 50% 0%, rgba(46, 162, 255, .12), rgba(4, 8, 18, .3));
}
.leap__cta h3 {
  margin: 0 0 20px; font-family: "Bebas Neue", "Outfit", sans-serif; font-weight: 400;
  font-size: clamp(28px, 4.2vw, 60px); color: #fff; text-transform: uppercase;
}
.leap__btn {
  display: inline-flex; align-items: center; gap: 10px; padding: 14px 28px; border-radius: 999px;
  background: var(--leap-tint); color: #02030a; font: 700 15px/1 "Outfit", sans-serif; text-decoration: none;
  transition: filter .2s ease, transform .2s ease;
}
.leap__btn:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* ---- Zurueck-Knopf — nur sichtbar wenn (fast) Vollbild --------------------- */
.leap__close {
  position: fixed; top: clamp(74px, 9vh, 96px); left: clamp(16px, 2vw, 26px); z-index: 5;
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 999px;
  background: rgba(4, 8, 18, .6); border: 1px solid rgba(124, 198, 255, .25); color: #dce8ff;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font: 600 13px/1 "Outfit", sans-serif; cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .25s ease, background .2s ease;
}
.leap.is-full .leap__close { opacity: 1; pointer-events: auto; }
.leap__close:hover { background: rgba(46, 162, 255, .18); }

/* ---- Unterseiten-Fortschrittsbalken (oben) — sichtbar ab Vollbild ----------
   Liegt fix am oberen Viewport-Rand (z9, unter der Nav-Schrift, ueber dem
   Subpage-Frame z8). scaleX = subRaw (leap.js, mit Mindest-Sliver) -> klar
   sichtbar von Beginn der Unterseite an, fuellt sich bis zum Ende. */
.leap__progress {
  position: fixed; left: 0; right: 0; top: 0; height: 3px; z-index: 9;
  background: rgba(255, 255, 255, .08);
  opacity: 0; pointer-events: none;
  transition: opacity .35s ease;
}
.leap.is-full .leap__progress { opacity: 1; }
.leap__progress i {
  display: block; height: 100%; width: 100%; transform-origin: left;
  transform: scaleX(var(--leap-prog, 0));
  background: linear-gradient(90deg, var(--leap-tint), #7cc6ff);
  box-shadow: 0 0 12px var(--leap-tint);
  transition: transform .12s linear;
}

/* ---- die unsichtbare Scroll-Schiene (liefert den Scrollweg fuer Zoom+Sub) -- */
.leap-rail { position: relative; width: 100%; pointer-events: none; }

/* reduced-motion / mobile / statisches #spark: Portal aus
   (dort gilt die native Swipe-Galerie + die echten Subpages) */
@media (max-width: 860px) { .leap, .leap-rail { display: none; } }
@media (prefers-reduced-motion: reduce) { .leap, .leap-rail { display: none; } }
