/* ============================================================
   BUZZCUT — FX LAYER
   Scroll-Animationen für alle Seiten. Alles hängt an html.fx,
   das nur gesetzt wird, wenn JS läuft und kein "reduced motion"
   gewünscht ist. Ohne JS bleibt die Seite wie vorher.
============================================================ */

:root {
  --fx-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --fx-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Scroll-Fortschritt ---------- */
.fx-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  z-index: 100000;
  background: #0073bc;
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
  will-change: transform;
}

/* ---------- Nav schrumpft beim Scrollen (nur Desktop) ---------- */
@media (min-width: 901px) {
  html.fx .buzz-nav {
    transition: height 0.45s var(--fx-ease), background 0.45s ease, box-shadow 0.45s ease;
  }
  html.fx .buzz-nav.fx-scrolled {
    height: 68px;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.06);
  }
}

/* ---------- Bestehendes .reveal neutralisieren, wenn Kinder animieren ---------- */
html.fx .reveal.fx-neutral {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* ============================================================
   AUSGANGSZUSTÄNDE (vor dem Einblenden)
============================================================ */
html.fx .fx-up:not(.fx-in)     { opacity: 0; transform: translate3d(0, 46px, 0); }
html.fx .fx-left:not(.fx-in)   { opacity: 0; transform: translate3d(-9vw, 0, 0); }
html.fx .fx-right:not(.fx-in)  { opacity: 0; transform: translate3d(9vw, 0, 0); }
html.fx .fx-zoom:not(.fx-in)   { opacity: 0; transform: scale(0.92); }
/* Wichtig: im Ausgangszustand KEIN clip-path, sonst meldet der IntersectionObserver
   "nicht sichtbar" und die Animation startet nie. Der Clip steckt nur in den Keyframes. */
html.fx .fx-sweep:not(.fx-in)  { opacity: 0; transform: translate3d(-28px, 0, 0); }
html.fx .fx-wipe:not(.fx-in)   { opacity: 0; }
html.fx .fx-curtain:not(.fx-in){ opacity: 0; }
html.fx .fx-wipe:not(.fx-in) > img:not([data-fx-par]),
html.fx .fx-curtain:not(.fx-in) > img:not([data-fx-par]) { transform: scale(1.3); }

/* ============================================================
   EINBLENDEN
   animation-fill-mode: backwards → danach gelten wieder die
   normalen Styles der Seite (Hover etc. bleiben unberührt).
============================================================ */
html.fx .fx-in {
  animation-duration: 1.1s;
  animation-timing-function: var(--fx-ease);
  animation-delay: var(--fx-d, 0s);
  animation-fill-mode: backwards;
}
html.fx .fx-up.fx-in      { animation-name: fxUp; }
html.fx .fx-left.fx-in    { animation-name: fxLeft;  animation-duration: 1.3s; }
html.fx .fx-right.fx-in   { animation-name: fxRight; animation-duration: 1.3s; }
html.fx .fx-zoom.fx-in    { animation-name: fxZoom;  animation-duration: 1.4s; }
html.fx .fx-sweep.fx-in   { animation-name: fxSweep; animation-duration: 1.15s; }
html.fx .fx-wipe.fx-in    { animation-name: fxWipe;  animation-duration: 1.5s; animation-timing-function: var(--fx-ease-out); }
html.fx .fx-curtain.fx-in { animation-name: fxCurtain; animation-duration: 1.4s; animation-timing-function: var(--fx-ease-out); }
html.fx .fx-wipe.fx-in > img:not([data-fx-par]),
html.fx .fx-curtain.fx-in > img:not([data-fx-par]) {
  animation: fxImgSettle 1.8s var(--fx-ease-out) var(--fx-d, 0s) backwards;
}

@keyframes fxUp      { from { opacity: 0; transform: translate3d(0, 46px, 0); } to { opacity: 1; transform: none; } }
@keyframes fxLeft    { from { opacity: 0; transform: translate3d(-9vw, 0, 0); } to { opacity: 1; transform: none; } }
@keyframes fxRight   { from { opacity: 0; transform: translate3d(9vw, 0, 0); }  to { opacity: 1; transform: none; } }
@keyframes fxZoom    { from { opacity: 0; transform: scale(0.92); }             to { opacity: 1; transform: none; } }
@keyframes fxSweep   {
  from { opacity: 0; clip-path: inset(-0.1em 100% -0.1em 0); transform: translate3d(-28px, 0, 0); }
  to   { opacity: 1; clip-path: inset(-0.1em -2% -0.1em 0);  transform: none; }
}
@keyframes fxWipe    { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes fxCurtain { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes fxImgSettle { from { transform: scale(1.3); } to { transform: scale(1); } }

/* ---------- Hero-Buchstaben ---------- */
.fx-char {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.06em;
  margin-bottom: -0.06em;
}
.fx-char > data {
  display: inline-block;
  will-change: transform;
}
html.fx .fx-letters:not(.fx-in) .fx-char > data { transform: translate3d(0, 112%, 0) rotate(7deg); }
html.fx .fx-letters.fx-in .fx-char > data {
  animation: fxChar 1.15s var(--fx-ease) backwards;
  animation-delay: calc(var(--fx-d, 0s) + var(--i) * 0.055s);
}
@keyframes fxChar {
  from { transform: translate3d(0, 112%, 0) rotate(7deg); }
  to   { transform: none; }
}

/* ============================================================
   HERO-PARALLAX (Variablen werden per JS gesetzt: --hp 0…1)
============================================================ */
html.fx .fx-hero { --hp: 0; }
html.fx .fx-hero > video {
  transform: translate3d(0, calc(var(--hp) * 14%), 0) scale(calc(1.08 + var(--hp) * 0.05));
  will-change: transform;
}
html.fx .fx-hero-content {
  opacity: calc(1 - var(--hp) * 1.5);
  transform: translate3d(0, calc(var(--hp) * -60px), 0);
  will-change: transform, opacity;
}

/* Parallax für Bilder: Wrapper schneidet ab, Bild skaliert */
html.fx [data-fx-par] {
  transform: translate3d(0, var(--py, 0px), 0) scale(1.18);
  will-change: transform;
}
html.fx .bz-sideword[data-fx-par],
html.fx .cs-sideword[data-fx-par] {
  transform: translate3d(var(--px, 0px), 0, 0);
}

/* Buttons: magnetisch (Transform kommt per JS) */
html.fx .fx-magnet { transition: transform 0.35s var(--fx-ease), background 0.4s ease, border-color 0.4s ease; }

/* ---------- Mobile: Bewegungen kleiner, damit nichts über den Rand läuft ---------- */
@media (max-width: 900px) {
  html.fx .fx-left:not(.fx-in),
  html.fx .fx-right:not(.fx-in) { transform: translate3d(0, 46px, 0); }
  @keyframes fxLeft  { from { opacity: 0; transform: translate3d(0, 46px, 0); } to { opacity: 1; transform: none; } }
  @keyframes fxRight { from { opacity: 0; transform: translate3d(0, 46px, 0); } to { opacity: 1; transform: none; } }
}

/* ============================================================
   STICKY-STACK: Leistungen fahren beim Scrollen übereinander
   Nur Desktop. overflow:clip statt hidden, sonst greift sticky nicht.
============================================================ */
@media (min-width: 901px) {
  html.fx body { overflow-x: clip !important; }
  html.fx .bz-gal { overflow: clip; }

  html.fx .bz-service-row {
    position: sticky;
    top: calc(104px + var(--si, 0) * 28px);
    margin-bottom: 6vh;
    padding: 52px clamp(28px, 3.6vw, 60px);
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.08) !important;
    border-radius: 18px;
    box-shadow: 0 -16px 50px rgba(0, 0, 0, 0.05), 0 30px 80px rgba(0, 0, 0, 0.08);
    transition: box-shadow 0.5s var(--fx-ease), transform 0.5s var(--fx-ease);
  }
  html.fx .bz-service-row:hover {
    box-shadow: 0 -16px 50px rgba(0, 0, 0, 0.05), 0 40px 100px rgba(0, 115, 188, 0.16);
  }
}
