/* =========================================================================
   MW-Education — Animationen für die WordPress-Seite
   Teil 1 von 2: CSS.  Gehört nach Design → Customizer → Zusätzliches CSS.
   Ohne die zugehörige animationen.js passiert nichts (bewusst, siehe unten).
   =========================================================================

   SICHERHEITSNETZ — bitte nicht wegoptimieren:
   Alle Ausblend-Zustände hängen an `html.fx-ready`. Diese Klasse setzt das
   JavaScript als Allererstes. Lädt das Skript nicht, ist es blockiert oder
   wirft es einen Fehler, greift keine einzige Regel hier — die Seite sieht
   dann aus wie ohne Animationen, statt unsichtbar zu sein.

   Ein Effekt, der Inhalte auf `opacity: 0` setzt, ohne diese Absicherung,
   macht bei jedem JS-Aussetzer die ganze Seite leer. Das ist der häufigste
   und teuerste Fehler bei Scroll-Animationen.
   ========================================================================= */

:root {
  /* Zentrale Stellschrauben — hier drehen, nicht in den Regeln unten. */
  --fx-dauer: 700ms;
  --fx-weg: 28px;                                  /* Strecke der Einblendung */
  --fx-kurve: cubic-bezier(0.22, 0.61, 0.36, 1);   /* weich auslaufend */
  --fx-stufe: 90ms;                                /* Versatz je Element */
}

/* ── 1. Einblenden beim Scrollen ────────────────────────────────────────
   Klasse `fx-reveal` an ein Element hängen. Varianten siehe unten. */

html.fx-ready .fx-reveal {
  opacity: 0;
  transform: translate3d(0, var(--fx-weg), 0);
  transition:
    opacity   var(--fx-dauer) var(--fx-kurve),
    transform var(--fx-dauer) var(--fx-kurve);
  transition-delay: var(--fx-delay, 0ms);
  /* will-change nur währenddessen — dauerhaft gesetzt kostet es Speicher
     und kann auf schwachen Geräten das Gegenteil bewirken. */
}

html.fx-ready .fx-reveal.fx-in {
  opacity: 1;
  transform: none;
}

/* Richtungsvarianten */
html.fx-ready .fx-reveal.fx-von-links  { transform: translate3d(calc(var(--fx-weg) * -1.5), 0, 0); }
html.fx-ready .fx-reveal.fx-von-rechts { transform: translate3d(calc(var(--fx-weg) *  1.5), 0, 0); }
html.fx-ready .fx-reveal.fx-zoom       { transform: scale(0.94); }
html.fx-ready .fx-reveal.fx-von-links.fx-in,
html.fx-ready .fx-reveal.fx-von-rechts.fx-in,
html.fx-ready .fx-reveal.fx-zoom.fx-in { transform: none; }

/* ── 2. Kacheln anheben beim Überfahren ─────────────────────────────────
   Für Projekt-/Leistungskacheln. Nur auf Geräten mit echtem Zeiger — auf
   dem Handy gibt es kein Hover, dort bliebe der Effekt sonst nach dem
   Antippen „kleben". */

@media (hover: hover) and (pointer: fine) {
  .fx-lift {
    transition:
      transform 350ms var(--fx-kurve),
      box-shadow 350ms var(--fx-kurve);
  }
  .fx-lift:hover {
    transform: translateY(-6px);
    box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.28);
  }
  /* Bild innerhalb der Kachel leicht heranfahren */
  .fx-lift img { transition: transform 600ms var(--fx-kurve); }
  .fx-lift:hover img { transform: scale(1.045); }
  .fx-lift { overflow: hidden; }   /* damit das Bild nicht heraussteht */
}

/* ── 3. Logo-Band (Marquee) ─────────────────────────────────────────────
   Struktur baut das JavaScript. Hier nur die Bewegung.
   `--fx-marquee-dauer` setzt das Skript passend zur Breite, damit das
   Tempo unabhängig von der Anzahl der Logos gleich bleibt. */

.fx-marquee {
  overflow: hidden;
  position: relative;
  /* Weiche Kanten links und rechts statt harter Schnitt */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.fx-marquee__spur {
  display: flex;
  width: max-content;
  align-items: center;
  gap: var(--fx-marquee-abstand, 3rem);
  animation: fx-marquee var(--fx-marquee-dauer, 30s) linear infinite;
}

.fx-marquee:hover .fx-marquee__spur { animation-play-state: paused; }

@keyframes fx-marquee {
  from { transform: translate3d(0, 0, 0); }
  /* -50%, weil das Skript die Logos genau einmal dupliziert: an dieser
     Stelle sieht das Bild identisch aus und der Sprung ist unsichtbar. */
  to   { transform: translate3d(-50%, 0, 0); }
}

/* ── 4. Sanftes Scrollen bei Ankerlinks ─────────────────────────────────
   Native Lösung. Bewusst KEIN Smooth-Scroll-Skript (Lenis/Locomotive):
   das übernimmt das Scrollen der ganzen Seite und fühlt sich auf dem
   Handy zäh an, bricht Browser-Suche und Barrierefreiheit. */

html { scroll-behavior: smooth; }

/* ── 5. Zeilenweises Text-Reveal ────────────────────────────────────────
   Klasse `fx-zeilen` an eine Überschrift. Das Skript zerlegt den Text in
   echte Zeilen (so wie er umbricht) und lässt sie nacheinander hinter
   einer Maske hervorfahren.

   Das ist der Effekt, der bei Agenturseiten am meisten zum „teuren"
   Eindruck beiträgt — und der einzige hier, der etwas Rechenarbeit im
   Layout braucht. Deshalb passiert er nur einmal beim Laden und einmal
   nach einer Größenänderung, nicht beim Scrollen. */

html.fx-ready .fx-zeilen {
  /* Ohne das wäre die Überschrift nach dem Zerlegen ein paar Pixel höher
     als vorher: der negative Ausgleichsrand der letzten Zeile (siehe unten)
     kollabiert sonst durch das Elternelement hindurch, während dessen
     Innenabstand bleibt. `flow-root` schließt das ab — gemessen: mit
     dieser Zeile exakt dieselbe Höhe wie ungeteilter Text, ohne sie 5 px mehr. */
  display: flow-root;
}

html.fx-ready .fx-zeilen .fx-zeile {
  display: block;
  overflow: hidden;
  /* Unterlängen (g, j, p, y) würden von overflow:hidden abgeschnitten.
     Der Puffer unten wird per negativem Rand wieder ausgeglichen, damit
     sich der Zeilenabstand nicht verändert. */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

html.fx-ready .fx-zeilen .fx-zeile__i {
  display: block;
  /* 105 statt 100 Prozent: bei genau 100 blitzt die Unterlänge der Zeile
     am unteren Rand hervor, bevor die Maske greift. */
  transform: translate3d(0, 105%, 0);
  transition: transform var(--fx-zeilen-dauer, 900ms) var(--fx-kurve);
  transition-delay: var(--fx-zeile-delay, 0ms);
}

html.fx-ready .fx-zeilen.fx-in .fx-zeile__i { transform: none; }

/* ── 6. Sticky-Abschnitt ────────────────────────────────────────────────
   Klasse `fx-sticky` an das Element, das stehen bleiben soll, während
   der Inhalt daneben weiterläuft. Reines CSS, kein JavaScript.

   ACHTUNG, häufigste Fehlerquelle: sticky funktioniert NICHT, wenn ein
   Elternelement `overflow: hidden` oder `overflow: auto` hat. Viele
   Themes und Seitenbaukästen setzen das auf Sections. Wenn nichts
   passiert, ist fast immer das die Ursache — nicht dieser Code. */

.fx-sticky {
  position: sticky;
  top: var(--fx-sticky-oben, 6rem);
}

/* ── 7. Magnetische Schaltflächen ───────────────────────────────────────
   Klasse `fx-magnet` an einen Button oder Link. Das Element folgt dem
   Zeiger ein paar Pixel, solange er darüber ist.

   Nur mit echtem Zeiger — auf dem Handy gibt es kein Hover, dort bliebe
   die Verschiebung nach dem Antippen stehen.

   NICHT mit `fx-reveal` am selben Element kombinieren: beide arbeiten
   über `transform` und würden sich gegenseitig überschreiben. Das
   Reveal gehört dann an ein umschließendes Element. */

@media (hover: hover) and (pointer: fine) {
  .fx-magnet {
    /* Kurz genug, dass es dem Zeiger folgt, lang genug, dass es weich
       wirkt statt zu zappeln. */
    transition: transform 200ms var(--fx-kurve);
  }
  /* Beim Verlassen darf es gemütlicher zurückgleiten. */
  .fx-magnet.fx-magnet--zurueck {
    transition: transform 500ms var(--fx-kurve);
  }
}

/* ── 8. Bewegung reduzieren ─────────────────────────────────────────────
   Pflicht, nicht Kür: Wer im Betriebssystem „Bewegung reduzieren" gesetzt
   hat, tut das meist aus gutem Grund (Migräne, Schwindel). Alles wird
   sofort sichtbar dargestellt. */

/* ── 7. Kacheln beleben ─────────────────────────────────────────────────
   Klasse `fx-karte` an Inhaltskacheln hängen.

   BEWUSST ZURÜCKHALTEND: nur Randfarbe und ein weicher Schatten. Kein
   Anheben, keine Vergrößerung, kein Zeigerwechsel.

   Der Grund ist kein Geschmack, sondern Ehrlichkeit: diese Kacheln sind
   KEINE Links. Ein Effekt, der sich anfühlt wie eine Schaltfläche,
   verspricht einen Klick, den es nicht gibt — der Besucher klickt, nichts
   passiert, und die Seite wirkt kaputt statt lebendig. Deshalb hebt
   `fx-lift` (weiter oben) die Kachel an, `fx-karte` nur ihren Rand.

   @AI-NOTE: Diese Regeln hängen absichtlich NICHT an `html.fx-ready`.
   Der Schalter existiert nur, um Inhalte zu schützen, die auf
   `opacity: 0` starten. Hier startet nichts unsichtbar — fällt das
   Skript aus, fehlt lediglich ein Hover-Effekt. Es gibt keinen Grund,
   ihn dann auch noch abzuschalten.

   Nur für Kacheln mit neutralem Rand (`border-line`). Die hervorgehobene
   Kachel mit durchgehend teal Rand bekommt sie NICHT: der Hover-Rand ist
   halbtransparent und würde ihren kräftigen Rand beim Überfahren
   ABSCHWÄCHEN statt betonen. */

@media (hover: hover) and (pointer: fine) {
  .fx-karte {
    /* 220 ms statt der 700 ms von --fx-dauer: Hover muss dem Zeiger
       folgen. Alles über ~250 ms fühlt sich träge an. */
    transition:
      border-color 220ms var(--fx-kurve),
      box-shadow   220ms var(--fx-kurve);
  }

  .fx-karte:hover {
    /* teal-deep (0 124 113) auf knapp der Hälfte — sichtbar wärmer als
       der neutrale Rand (216 224 235), aber weit entfernt von der
       Signalwirkung der teal hervorgehobenen Kachel. */
    border-color: rgba(0, 124, 113, 0.45);
    /* Navy statt Schwarz: ein grauer Schatten wirkt auf dem leicht
       blauen Offwhite schmutzig. */
    box-shadow: 0 10px 28px -16px rgba(1, 34, 101, 0.38);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Der Hover-Zustand bleibt — er ist eine Zustandsanzeige, keine
     Bewegung. Nur das weiche Überblenden entfällt. */
  .fx-karte { transition: none; }

  html.fx-ready .fx-reveal,
  html.fx-ready .fx-reveal.fx-von-links,
  html.fx-ready .fx-reveal.fx-von-rechts,
  html.fx-ready .fx-reveal.fx-zoom {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .fx-marquee__spur { animation: none; }
  .fx-lift, .fx-lift img { transition: none; }
  .fx-lift:hover { transform: none; box-shadow: none; }
  .fx-lift:hover img { transform: none; }

  /* Zeilen bleiben ungeteilt stehen (das Skript zerlegt sie gar nicht
     erst), die Regeln hier sind das Netz für den Fall, dass doch. */
  html.fx-ready .fx-zeilen .fx-zeile__i {
    transform: none !important;
    transition: none !important;
  }
  .fx-magnet { transition: none !important; transform: none !important; }
}
