/* ==========================================================================
   FOB WEBDESIGN – ANIMATIONEN
   --------------------------------------------------------------------------
   Diese Datei enthält ausschließlich Bewegung. Layout und Farben stehen in
   styles.css. Dadurch lässt sich die gesamte Animation an einer Stelle
   anpassen oder notfalls komplett abschalten.

   Aufbau:
     01  Grundlagen und Zeitkurven
     02  Seitenübergänge
     03  Scroll-Einblendungen (data-reveal)
     04  Wortweise Überschriften (data-split)
     05  Hero-Choreografie
     06  Kennzahlen
     07  Schaltflächen
     08  Karten
     09  Navigation
     10  Steigleitung im Ablauf
     11  Akkordeon
     12  Fortschrittsbalken und Sprung nach oben
     13  Bilder
     14  Dekorative Hintergrundbewegung
     15  Reduzierte Bewegung

   WICHTIG: Abschnitt 15 schaltet alles ab, sobald im Betriebssystem
   „Bewegung reduzieren" aktiviert ist. Bitte beim Erweitern beibehalten.
   ========================================================================== */


/* ==========================================================================
   01  GRUNDLAGEN UND ZEITKURVEN
   ========================================================================== */

:root {
  /* Weiche Kurve für Einblendungen – startet zügig, läuft sanft aus */
  --ease-out-soft:  cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Leichtes Überschwingen für spielerische Elemente */
  --ease-back:      cubic-bezier(0.34, 1.56, 0.64, 1);
  /* Gleichmäßig, für Dauerbewegungen */
  --ease-inout:     cubic-bezier(0.65, 0.05, 0.36, 1);

  --dur-fast:   180ms;
  --dur-base:   420ms;
  --dur-slow:   760ms;
  --dur-slower: 1100ms;
}

/* Elemente, die animiert werden, bekommen eine eigene Ebene.
   Das verhindert Flackern und entlastet den Hauptprozess. */
[data-reveal],
[data-split] .wort span,
.hero__zeile > span {
  will-change: transform, opacity;
}

/* Sobald die Animation gelaufen ist, wird die Ebene wieder freigegeben. */
[data-reveal].ist-sichtbar {
  will-change: auto;
}


/* ==========================================================================
   02  SEITENÜBERGÄNGE
   --------------------------------------------------------------------------
   Moderne Browser blenden den Wechsel zwischen zwei Seiten selbst weich über.
   Ältere Browser bekommen die Ersatzlösung darunter (Klasse .verlaesst).
   ========================================================================== */

@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: seiteRaus 220ms var(--ease-out-soft) both;
}

::view-transition-new(root) {
  animation: seiteRein 380ms var(--ease-out-soft) both;
}

/* Die Kopfleiste bleibt beim Wechsel stehen, statt mitzublenden */
.site-header {
  view-transition-name: kopfleiste;
}

@keyframes seiteRaus {
  to { opacity: 0; transform: translateY(-8px); }
}

@keyframes seiteRein {
  from { opacity: 0; transform: translateY(12px); }
}

/* --- Ersatzlösung ohne View Transitions --------------------------------- */

body {
  animation: inhaltRein var(--dur-base) var(--ease-out-soft) both;
}

body.verlaesst {
  animation: inhaltRaus 200ms var(--ease-out-soft) both;
}

@keyframes inhaltRein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes inhaltRaus {
  to { opacity: 0; transform: translateY(-6px); }
}

/* Unterstützt der Browser View Transitions, ist die Ersatzlösung überflüssig */
@supports (view-transition-name: none) {
  body,
  body.verlaesst {
    animation: none;
  }
}


/* ==========================================================================
   03  SCROLL-EINBLENDUNGEN
   --------------------------------------------------------------------------
   Verwendung im HTML:
     <div data-reveal>                 einfaches Aufblenden von unten
     <div data-reveal="links">         kommt von links herein
     <div data-reveal="rechts">        kommt von rechts herein
     <div data-reveal="skalieren">     wächst leicht auf
     <div data-reveal="vorhang">       wird von unten aufgedeckt
     <div data-reveal="kippen">        kippt nach vorn
     <ul data-stagger>                 Kinder erscheinen nacheinander
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transition-property: opacity, transform, clip-path;
  transition-duration: var(--dur-slow);
  transition-timing-function: var(--ease-out-soft);
}

[data-reveal=""],
[data-reveal="hoch"] { transform: translateY(38px); }
[data-reveal="links"]      { transform: translateX(-46px); }
[data-reveal="rechts"]     { transform: translateX(46px); }
[data-reveal="skalieren"]  { transform: scale(0.92); }
[data-reveal="kippen"]     { transform: perspective(900px) rotateX(10deg) translateY(30px); }

[data-reveal="vorhang"] {
  clip-path: inset(100% 0 0 0);
  transform: translateY(24px);
}

/* Endzustand: alles zurück auf Normalstellung */
[data-reveal].ist-sichtbar {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

/* Nacheinander erscheinende Kinder. Die Verzögerung setzt script.js,
   damit sie sich nicht über beliebig viele Stufen aufsummiert. */
[data-stagger] > * {
  transition-delay: var(--verzug, 0ms);
}


/* ==========================================================================
   04  WORTWEISE ÜBERSCHRIFTEN
   --------------------------------------------------------------------------
   script.js zerlegt Überschriften mit data-split in einzelne Wörter.
   Jedes Wort steigt einzeln von unten ins Bild.
   ========================================================================== */

[data-split] .wort {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  /* Unterlängen wie bei g oder p dürfen nicht abgeschnitten werden */
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}

[data-split] .wort > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform var(--dur-slow) var(--ease-out-soft);
  transition-delay: var(--verzug, 0ms);
}

[data-split].ist-sichtbar .wort > span {
  transform: translateY(0);
}


/* ==========================================================================
   05  HERO-CHOREOGRAFIE
   --------------------------------------------------------------------------
   Beim ersten Aufbau der Startseite laufen die Bestandteile nacheinander ein.
   ========================================================================== */

.hero__eyebrow,
.hero__subtitle,
.hero__actions,
.factbar {
  opacity: 0;
  animation: heroTeil var(--dur-slow) var(--ease-out-soft) forwards;
}

.hero__eyebrow  { animation-delay: 120ms; }
.hero__subtitle { animation-delay: 620ms; }
.hero__actions  { animation-delay: 760ms; }
.factbar        { animation-delay: 900ms; }

@keyframes heroTeil {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* Goldener Strich unter der Überschrift wird gezeichnet */
.hero__strich {
  display: block;
  width: 0;
  height: 3px;
  margin-top: var(--space-5);
  background: linear-gradient(90deg, var(--gold), rgba(200, 168, 95, 0));
  animation: strichZiehen var(--dur-slower) var(--ease-out-soft) 900ms forwards;
}

@keyframes strichZiehen {
  to { width: min(280px, 60%); }
}

/* Sanft schwebender Lichtschein im Hero */
.hero::before {
  animation: schweben 14s var(--ease-inout) infinite alternate;
}

@keyframes schweben {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-4%, 5%, 0) scale(1.12); }
}


/* ==========================================================================
   06  KENNZAHLEN
   ========================================================================== */

.kennzahl__wert {
  font-variant-numeric: tabular-nums;   /* Zahlen springen beim Zählen nicht */
}

/* Kurzer goldener Puls, wenn der Zählvorgang endet */
.kennzahl.ist-fertig .kennzahl__wert {
  animation: zahlPuls 620ms var(--ease-back);
}

@keyframes zahlPuls {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.08); color: var(--gold); }
  100% { transform: scale(1); }
}


/* ==========================================================================
   07  SCHALTFLÄCHEN
   ========================================================================== */

.btn {
  position: relative;
  overflow: hidden;
  /* Wird von der magnetischen Steuerung in script.js gesetzt */
  transform: translate3d(var(--mx, 0), var(--my, 0), 0);
  transition: background-color var(--dur-fast) var(--ease-out-soft),
              border-color var(--dur-fast) var(--ease-out-soft),
              color var(--dur-fast) var(--ease-out-soft),
              transform 260ms var(--ease-out-soft),
              box-shadow var(--dur-fast) var(--ease-out-soft);
}

/* Lichtreflex, der beim Überfahren durchläuft */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg,
              transparent 35%,
              rgba(255, 255, 255, 0.32) 50%,
              transparent 65%);
  transform: translateX(-120%);
  transition: transform 620ms var(--ease-out-soft);
  pointer-events: none;
}

.btn:hover::after,
.btn:focus-visible::after {
  transform: translateX(120%);
}

.btn--accent:hover {
  box-shadow: 0 8px 24px rgba(200, 168, 95, 0.35);
}

/* Auf Berührungsgeräten stört der Reflex, dort bleibt er aus */
@media (hover: none) {
  .btn::after { display: none; }
}


/* ==========================================================================
   08  KARTEN
   --------------------------------------------------------------------------
   Die Neigung berechnet script.js und schreibt sie in --neigeX / --neigeY.
   ========================================================================== */

.card,
.price-card,
.care-card {
  transform: perspective(1000px)
             rotateX(var(--neigeX, 0deg))
             rotateY(var(--neigeY, 0deg))
             translateY(var(--hebung, 0));
  transform-style: preserve-3d;
  transition: transform 320ms var(--ease-out-soft),
              border-color var(--dur-fast) var(--ease-out-soft),
              box-shadow 320ms var(--ease-out-soft);
}

/* Goldener Lichtpunkt folgt dem Zeiger über die Karte */
.card::before,
.care-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(340px circle at var(--zx, 50%) var(--zy, 50%),
              rgba(200, 168, 95, 0.16), transparent 62%);
  opacity: 0;
  transition: opacity 320ms var(--ease-out-soft);
  pointer-events: none;
}

.card:hover::before,
.care-card:hover::before {
  opacity: 1;
}

.card,
.care-card {
  position: relative;
}

/* Das Symbol dreht sich beim Überfahren leicht mit */
.card__icon {
  transition: transform 420ms var(--ease-back),
              background-color var(--dur-fast) var(--ease-out-soft);
}

.card:hover .card__icon {
  transform: rotate(-8deg) scale(1.08);
}

@media (hover: none) {
  .card::before,
  .care-card::before { display: none; }
}


/* ==========================================================================
   09  NAVIGATION
   ========================================================================== */

/* Goldener Strich wächst unter dem Menüpunkt auf */
.nav__link::after {
  content: "";
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: 6px;
  height: 2px;
  background-color: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 320ms var(--ease-out-soft);
}

.nav__link:hover::after,
.nav__link[aria-current="page"]::after {
  transform: scaleX(1);
}

/* Im mobilen Menü erscheinen die Punkte nacheinander */
.nav.is-open .nav__list > li {
  animation: menueEintrag 420ms var(--ease-out-soft) both;
}

.nav.is-open .nav__list > li:nth-child(1) { animation-delay:  40ms; }
.nav.is-open .nav__list > li:nth-child(2) { animation-delay:  90ms; }
.nav.is-open .nav__list > li:nth-child(3) { animation-delay: 140ms; }
.nav.is-open .nav__list > li:nth-child(4) { animation-delay: 190ms; }
.nav.is-open .nav__list > li:nth-child(5) { animation-delay: 240ms; }
.nav.is-open .nav__list > li:nth-child(6) { animation-delay: 290ms; }
.nav.is-open .nav__list > li:nth-child(7) { animation-delay: 340ms; }

@keyframes menueEintrag {
  from { opacity: 0; transform: translateX(-22px); }
  to   { opacity: 1; transform: none; }
}

/* Die Kopfleiste rückt beim Scrollen enger zusammen */
.site-header {
  transition: box-shadow var(--dur-fast) var(--ease-out-soft),
              background-color var(--dur-fast) var(--ease-out-soft);
}

.site-header__inner {
  transition: min-height 320ms var(--ease-out-soft);
}

.site-header.is-scrolled .site-header__inner {
  min-height: 60px;
}

.logo__mark {
  transition: transform 420ms var(--ease-back);
}

.logo:hover .logo__mark {
  transform: rotate(-6deg) scale(1.06);
}


/* ==========================================================================
   10  STEIGLEITUNG IM ABLAUF
   --------------------------------------------------------------------------
   Die senkrechte Linie wird beim Scrollen von oben nach unten gezeichnet.
   ========================================================================== */

.step:not(:last-child)::before {
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur-slower) var(--ease-out-soft);
}

.step.ist-sichtbar:not(:last-child)::before {
  transform: scaleY(1);
}

/* Der Knotenpunkt springt kurz auf, wenn er erreicht wird */
.step__num {
  transform: scale(0.6);
  opacity: 0;
  transition: transform 560ms var(--ease-back),
              opacity 420ms var(--ease-out-soft),
              box-shadow 420ms var(--ease-out-soft);
}

.step.ist-sichtbar .step__num {
  transform: scale(1);
  opacity: 1;
}

.step:hover .step__num {
  box-shadow: 0 0 0 8px rgba(200, 168, 95, 0.16);
}


/* ==========================================================================
   11  AKKORDEON
   ========================================================================== */

.faq__item {
  transition: border-color var(--dur-fast) var(--ease-out-soft),
              box-shadow var(--dur-fast) var(--ease-out-soft);
}

.faq__item[open] {
  box-shadow: var(--shadow-sm);
}

/* Die Antwort fährt aus, statt zu springen.
   Das Raster von 0fr auf 1fr lässt sich weich animieren. */
.faq__huelle {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 380ms var(--ease-out-soft);
}

.faq__item[open] .faq__huelle {
  grid-template-rows: 1fr;
}

.faq__answer {
  overflow: hidden;
  opacity: 0;
  transition: opacity 300ms var(--ease-out-soft) 80ms;
}

.faq__item[open] .faq__answer {
  opacity: 1;
}

.faq__icon::before,
.faq__icon::after {
  transition: transform 320ms var(--ease-back);
}

.faq__item[open] .faq__icon::before {
  transform: translate(-50%, -50%) rotate(180deg);
}


/* ==========================================================================
   12  FORTSCHRITTSBALKEN UND SPRUNG NACH OBEN
   ========================================================================== */

.lesefortschritt {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 120;
  height: 3px;
  width: 100%;
  background: linear-gradient(90deg, var(--gold), var(--gold-bright));
  transform: scaleX(var(--fortschritt, 0));
  transform-origin: left;
  pointer-events: none;
}

.nach-oben {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 110;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  background-color: var(--navy-900);
  border: 1px solid var(--line-dark);
  border-radius: 50%;
  color: var(--gold);
  cursor: pointer;
  opacity: 0;
  transform: translateY(16px) scale(0.85);
  pointer-events: none;
  transition: opacity 320ms var(--ease-out-soft),
              transform 320ms var(--ease-back),
              background-color var(--dur-fast) var(--ease-out-soft);
}

.nach-oben.ist-sichtbar {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.nach-oben:hover {
  background-color: var(--navy-800);
}

.nach-oben svg {
  width: 20px;
  height: 20px;
  position: relative;
  z-index: 1;
}

/* Ring zeigt die gelesene Strecke an */
.nach-oben__ring {
  position: absolute;
  inset: -1px;
  width: 54px;
  height: 54px;
  transform: rotate(-90deg);
}

.nach-oben__ring circle {
  fill: none;
  stroke: var(--gold);
  stroke-width: 2;
  stroke-dasharray: 163;      /* Umfang bei Radius 26 */
  stroke-dashoffset: calc(163 - 163 * var(--fortschritt, 0));
  transition: stroke-dashoffset 120ms linear;
}


/* ==========================================================================
   13  BILDER
   ========================================================================== */

/* Das Porträt wird beim Erscheinen von unten aufgedeckt */
.photo-frame {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-slower) var(--ease-out-soft);
}

.photo-frame.ist-sichtbar {
  clip-path: inset(0 0 0 0);
}

/* Beim Überfahren zoomt das Bild ganz leicht */
.photo-frame__img {
  transition: transform 900ms var(--ease-out-soft);
}

.photo-frame:hover .photo-frame__img {
  transform: scale(1.04);
}


/* ==========================================================================
   14  DEKORATIVE HINTERGRUNDBEWEGUNG
   ========================================================================== */

/* Dunkle Abschnitte bekommen einen sehr langsam wandernden Schein */
.section--dark {
  position: relative;
  overflow: hidden;
}

.section--dark::before {
  content: "";
  position: absolute;
  top: -40%;
  left: -10%;
  width: 60%;
  aspect-ratio: 1;
  background: radial-gradient(circle,
              rgba(200, 168, 95, 0.10) 0%,
              rgba(200, 168, 95, 0) 60%);
  animation: wandern 22s var(--ease-inout) infinite alternate;
  pointer-events: none;
}

.section--dark > * {
  position: relative;
  z-index: 1;
}

@keyframes wandern {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(60%, 18%, 0); }
}

/* Element, das beim Scrollen langsamer mitläuft.
   Den Wert setzt script.js in --versatz. */
[data-parallax] {
  transform: translate3d(0, var(--versatz, 0), 0);
  will-change: transform;
}


/* ==========================================================================
   15  REDUZIERTE BEWEGUNG
   --------------------------------------------------------------------------
   Wer im Betriebssystem „Bewegung reduzieren" eingestellt hat, sieht die
   Seite vollständig, aber ohne Animation. Das ist keine Einschränkung des
   Inhalts, sondern nur der Darstellung.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    transition-delay: 0ms !important;
  }

  [data-reveal],
  [data-reveal].ist-sichtbar {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  [data-split] .wort > span { transform: none !important; }

  .hero__eyebrow,
  .hero__subtitle,
  .hero__actions,
  .factbar {
    opacity: 1 !important;
    animation: none !important;
  }

  .hero__strich { width: min(280px, 60%) !important; animation: none !important; }

  .step__num { opacity: 1 !important; transform: none !important; }
  .step:not(:last-child)::before { transform: scaleY(1) !important; }

  .photo-frame { clip-path: none !important; }

  .card, .price-card, .care-card { transform: none !important; }

  .hero::before,
  .section--dark::before { animation: none !important; }

  [data-parallax] { transform: none !important; }
}


/* ==========================================================================
   OHNE JAVASCRIPT
   Bleibt JavaScript aus, darf nichts unsichtbar sein.
   ========================================================================== */

html.no-js [data-reveal],
html.no-js [data-split] .wort > span,
html.no-js .hero__eyebrow,
html.no-js .hero__subtitle,
html.no-js .hero__actions,
html.no-js .factbar,
html.no-js .step__num {
  opacity: 1;
  transform: none;
  clip-path: none;
  animation: none;
}

html.no-js .photo-frame { clip-path: none; }
html.no-js .step:not(:last-child)::before { transform: scaleY(1); }
