/* ---------------------------------------------------------------------------
   Webux Effekte - Scroll-Einblendungen und Hover-Bewegung fuer jeden Block
   ---------------------------------------------------------------------------

   Die Datei laedt genau dann, wenn die Effekte in den Theme-Einstellungen
   (Einstellungen > WX Effekte) eingeschaltet sind - der Hauptschalter faellt,
   bevor die Seite gerendert wird, eine feinere Bedingung gaebe es zu diesem
   Zeitpunkt nicht. Auf einer Site mit ausgeschalteten Effekten existiert weder
   diese Datei im Head noch eine einzige `webux-fx*`-Klasse im Markup; auf einer
   eingeschalteten Seite ohne dekorierten Block liegt sie wirkungslos herum.

   Barrierefreiheits-Vertrag (identisch zu assets/css/webux-reveal.css, das
   Muster ist dort ausfuehrlich begruendet):

     1. Der Grundzustand versteckt NICHTS. `.webux-fx--up` allein setzt weder
        opacity noch transform. Erst die Klasse `is-fx-armed` - die
        ausschliesslich assets/js/webux-effects.js vergibt - blendet aus.
        Ohne JavaScript ist jeder Inhalt normal sichtbar.
     2. Der komplette Scroll-Teil haengt zusaetzlich in
        `prefers-reduced-motion: no-preference`. Wer Bewegung reduziert, sieht
        den Inhalt auch dann ohne Versatz, wenn das Skript bereits armiert hat.
     3. Animiert werden nur opacity, transform, filter und clip-path - alles
        Eigenschaften, die kein Layout verschieben. Der Block belegt durchgehend
        seinen endgueltigen Platz, es gibt keinen Layout-Shift (CLS).
     4. Im Druck wird nie gescrollt, der IntersectionObserver feuert also nie.
        Am Ende der Datei hebt ein @media print den Effekt vollstaendig auf.

   Stellschrauben: alle Werte haengen an Custom Properties, die
   inc/webux-effects.php als kleiner Inline-Style aus der Site-Einstellung
   (Intensitaet/Tempo) setzt. Dadurch braucht es kein zweites Stylesheet pro
   Site - dieselbe Datei laeuft auf jeder Installation mit eigenen Werten.
--------------------------------------------------------------------------- */

:root {
	/* Scroll-Einblendung */
	--wx-fx-dur: 620ms;
	--wx-fx-dist: 24px;
	--wx-fx-scale: 0.94;
	--wx-fx-blur: 10px;
	--wx-fx-tilt: 8deg;
	--wx-fx-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	/* Zeitversatz je Kind einer gestaffelten Gruppe */
	--wx-fx-step: 90ms;
	/* Zusaetzlicher Startversatz des ganzen Blocks (pro Block einstellbar) */
	--wx-fx-delay: 0ms;

	/* Hover */
	--wx-fx-hover-dur: 320ms;
	--wx-fx-hover-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--wx-fx-lift: 6px;
	--wx-fx-media-zoom: 1.06;
	/* Zwei Lagen statt einer, und ohne den starken negativen Spread von frueher:
	   ein Schatten, der um 18px eingezogen wird, klebt als dunkles Band direkt
	   unter der Karte, statt sie schweben zu lassen. Die weite, sehr weiche
	   Lage traegt die Tiefe, die enge dichtet die Kante ab - dieselbe Sprache,
	   die die Karten schon im Ruhezustand sprechen (0 8px 28px / 0 1px 2px). */
	--wx-fx-shadow: 0 20px 44px -8px rgba(0, 0, 0, 0.16), 0 6px 14px -6px rgba(0, 0, 0, 0.1);
	--wx-fx-shadow-soft: 0 8px 20px -10px rgba(0, 0, 0, 0.18);

	/* Markenfarbe fuer Schein/Rahmen/Lichtkegel. Faellt auf die Palette der
	   jeweiligen Site zurueck - derselbe Effekt wirkt dadurch bei jeder Marke in
	   deren Primaerfarbe. Als letzter Rueckfall currentColor und nicht ein
	   Hex-Wert: eine Site ohne `primary` bekaeme sonst die Farbe einer fremden
	   Marke ins Layout. */
	--wx-fx-tint: var(--wp--preset--color--primary, currentColor);
}

/* ===========================================================================
   1. Scroll-Einblendung
   ===========================================================================
   `webux-fx` markiert einen Block, der am Effekt teilnimmt; die Variante steht
   in `webux-fx--<name>`. Der Ausgangszustand steht ausschliesslich unter
   `.is-fx-armed` (Guard 1), das Ziel unter `.is-fx-in`. */
@media (prefers-reduced-motion: no-preference) {

	.webux-fx.is-fx-armed {
		opacity: 0;
		transition:
			opacity var(--wx-fx-dur) var(--wx-fx-ease) var(--wx-fx-delay),
			transform var(--wx-fx-dur) var(--wx-fx-ease) var(--wx-fx-delay),
			filter var(--wx-fx-dur) var(--wx-fx-ease) var(--wx-fx-delay),
			clip-path var(--wx-fx-dur) var(--wx-fx-ease) var(--wx-fx-delay);
		/* Der Browser darf die Ebene vorbereiten, aber nur solange der Block
		   noch aussteht - `will-change` dauerhaft zu setzen kostet Speicher. */
		will-change: opacity, transform;
	}

	.webux-fx--up.is-fx-armed    { transform: translate3d(0, var(--wx-fx-dist), 0); }
	.webux-fx--down.is-fx-armed  { transform: translate3d(0, calc(var(--wx-fx-dist) * -1), 0); }
	.webux-fx--left.is-fx-armed  { transform: translate3d(calc(var(--wx-fx-dist) * -1), 0, 0); }
	.webux-fx--right.is-fx-armed { transform: translate3d(var(--wx-fx-dist), 0, 0); }

	.webux-fx--zoom.is-fx-armed     { transform: scale(var(--wx-fx-scale)); }
	.webux-fx--zoom-out.is-fx-armed { transform: scale(calc(2 - var(--wx-fx-scale))); }

	/* Weichzeichnen -> scharf. Zusaetzlich ein kleiner Aufstieg, sonst wirkt der
	   Uebergang wie ein Fokusfehler statt wie eine Bewegung. */
	.webux-fx--blur.is-fx-armed {
		filter: blur(var(--wx-fx-blur));
		transform: translate3d(0, calc(var(--wx-fx-dist) * 0.4), 0);
	}

	/* Maskiert aufdecken: der Block wird von unten "aufgezogen". clip-path
	   schneidet nur die Darstellung, das Kastenmodell bleibt unveraendert. */
	.webux-fx--mask.is-fx-armed {
		clip-path: inset(0 0 100% 0);
		transform: translate3d(0, calc(var(--wx-fx-dist) * 0.5), 0);
		opacity: 1; /* Der Schnitt uebernimmt das Verbergen, kein Doppelfade. */
	}

	/* 3D-Kippen um die X-Achse. Die Perspektive muss am Element selbst haengen,
	   weil der Elternknoten ein beliebiger Layout-Container sein kann. */
	.webux-fx--tilt.is-fx-armed {
		transform: perspective(1200px) rotateX(var(--wx-fx-tilt)) translate3d(0, calc(var(--wx-fx-dist) * 0.5), 0);
		transform-origin: 50% 100%;
	}

	/* Startversatz je Block (Panel „Bewegung & Hover" -> Verzögerung). Als
	   Klassen statt als Inline-Style: dreizehn Bloecke reichen eigene
	   CSS-Variablen ueber das style-Attribut des Wrappers durch, und
	   set_attribute() wuerde dieses Attribut ersetzen. */
	.webux-fx--delay-1 { --wx-fx-delay: 100ms; }
	.webux-fx--delay-2 { --wx-fx-delay: 200ms; }
	.webux-fx--delay-3 { --wx-fx-delay: 300ms; }
	.webux-fx--delay-4 { --wx-fx-delay: 400ms; }
	.webux-fx--delay-5 { --wx-fx-delay: 500ms; }
	.webux-fx--delay-6 { --wx-fx-delay: 600ms; }

	/* Zielzustand.

	   `transform` faellt hier NICHT auf `none`, sondern auf --wx-fx-hover-t.
	   Grund: diese Regel wiegt 0,3,0 und schlaegt damit jede Hover-Regel
	   (0,2,0). Ein Block mit Einblendung UND Hover haette nach dem Einblenden
	   keinen Hover mehr - genau die Kombination, die eine Karte im Standard
	   bekommt. Ueber die Variable liest der Zielzustand den Hover-Wert mit, und
	   ohne Hover steht dort `none` wie zuvor.

	   `clip-path` wird nur dort zurueckgesetzt, wo es gesetzt wurde. Ein
	   `inset(0 0 0 0)` auf jedem Block bliebe fuer immer stehen und wuerde alles
	   abschneiden, was ueber den Rahmen hinausragt - Schatten einer angehobenen
	   Karte zum Beispiel. */
	.webux-fx.is-fx-armed.is-fx-in {
		opacity: 1;
		transform: var(--wx-fx-hover-t, none);
		filter: none;
		will-change: auto;
	}

	/* Der Endwert liegt bewusst AUSSERHALB des Rahmens und nicht auf `inset(0)`:
	   ein Schnitt genau am Rahmen bliebe fuer immer stehen und wuerde alles
	   abschneiden, was darueber hinausragt - den Schatten einer angehobenen
	   Karte etwa oder einen Fokusring mit outline-offset. Von `inset(0 0 100% 0)`
	   laesst sich dorthin sauber ueberblenden (beides vierwertige inset()). */
	.webux-fx--mask.is-fx-armed.is-fx-in {
		clip-path: inset(-100% -100% -100% -100%);
	}

	/* --- Gestaffelte Kinder -------------------------------------------------
	   Bei listenartigen Bloecken (Karten, Schritte, Bewertungen ...) traegt der
	   Block `webux-fx--stagger`, und inc/webux-effects.php haengt jedem
	   wiederholten Kind die Klasse `webux-fx-i` an. Die Kinder starten leicht
	   versetzt, der Block selbst blendet ohne eigenen Versatz ein.

	   Der Zaehler steht in einer eigenen Klasse (`webux-fx-i--3`) und weder in
	   :nth-child noch in einem Inline-Style:

	     - :nth-child geht schief, sobald eine Karte das einzige Kind ihres
	       Link-Wrappers ist (genau so baut die Objektliste ihre Kacheln) - dann
	       waere jede Karte „das erste Kind" und es gaebe gar keinen Versatz.
	     - Ein Inline-Style waere ein Ersetzen des style-Attributs, und dreizehn
	       Bloecke reichen darueber eigene CSS-Variablen durch.

	   Ueber zwoelf Positionen hinaus laeuft alles mit demselben Versatz -
	   laenger will niemand auf eine Liste warten. */
	.webux-fx-i--0  { --wx-i: 0; }
	.webux-fx-i--1  { --wx-i: 1; }
	.webux-fx-i--2  { --wx-i: 2; }
	.webux-fx-i--3  { --wx-i: 3; }
	.webux-fx-i--4  { --wx-i: 4; }
	.webux-fx-i--5  { --wx-i: 5; }
	.webux-fx-i--6  { --wx-i: 6; }
	.webux-fx-i--7  { --wx-i: 7; }
	.webux-fx-i--8  { --wx-i: 8; }
	.webux-fx-i--9  { --wx-i: 9; }
	.webux-fx-i--10 { --wx-i: 10; }
	.webux-fx-i--11 { --wx-i: 11; }

	.webux-fx--stagger.is-fx-armed .webux-fx-i {
		opacity: 0;
		transform: translate3d(0, var(--wx-fx-dist), 0);
		transition:
			opacity var(--wx-fx-dur) var(--wx-fx-ease) calc(var(--wx-fx-delay) + var(--wx-i, 0) * var(--wx-fx-step)),
			transform var(--wx-fx-dur) var(--wx-fx-ease) calc(var(--wx-fx-delay) + var(--wx-i, 0) * var(--wx-fx-step));
	}

	/* Die Kinder erben die Richtung des Blocks, damit "von links" auch bei einer
	   Staffelung von links kommt und nicht plötzlich von unten. */
	.webux-fx--down.webux-fx--stagger.is-fx-armed .webux-fx-i     { transform: translate3d(0, calc(var(--wx-fx-dist) * -1), 0); }
	.webux-fx--left.webux-fx--stagger.is-fx-armed .webux-fx-i     { transform: translate3d(calc(var(--wx-fx-dist) * -1), 0, 0); }
	.webux-fx--right.webux-fx--stagger.is-fx-armed .webux-fx-i    { transform: translate3d(var(--wx-fx-dist), 0, 0); }
	.webux-fx--zoom.webux-fx--stagger.is-fx-armed .webux-fx-i     { transform: scale(var(--wx-fx-scale)); }
	.webux-fx--zoom-out.webux-fx--stagger.is-fx-armed .webux-fx-i { transform: scale(calc(2 - var(--wx-fx-scale))); }
	.webux-fx--fade.webux-fx--stagger.is-fx-armed .webux-fx-i     { transform: none; }

	/* Auch hier der Hover-Durchgriff: die Karten einer gestaffelten Gruppe sind
	   genau die Elemente, die anschliessend den Hover tragen. */
	.webux-fx--stagger.is-fx-armed.is-fx-in .webux-fx-i {
		opacity: 1;
		transform: var(--wx-fx-hover-t, none);
	}

	/* Der Traegerblock einer Staffelung blendet selbst nicht aus - sonst faedet
	   die ganze Gruppe zusaetzlich zu den Kindern und der Versatz verpufft. */
	.webux-fx--stagger.is-fx-armed {
		opacity: 1;
		transform: none;
		will-change: auto;
	}

	/* --- Einzeln statt als Gruppe -------------------------------------------
	   Ist die Gruppe hoeher als drei Viertel des Bildschirms - auf dem Telefon
	   faellt jedes Raster auf eine Spalte zusammen und wird das fast immer -,
	   setzt assets/js/webux-effects.js `is-fx-items` und gibt jedem Kind einen
	   eigenen Waechter. Sonst faedet die ganze Spalte, sobald ihr Kopf
	   auftaucht, und alles unterhalb ist fertig, bevor man dort ankommt: man
	   saehe den Effekt genau einmal je Block.

	   Der Zustand haengt dann am KIND (`.webux-fx-i.is-fx-in`) statt am
	   Traeger. Der Kaskadenversatz faellt dabei weg - wer einzeln erscheint,
	   soll nicht auch noch auf seinen Vorlauf warten. */
	.webux-fx--stagger.is-fx-armed.is-fx-items .webux-fx-i {
		transition-delay: 0s;
	}

	.webux-fx--stagger.is-fx-armed.is-fx-items .webux-fx-i.is-fx-in {
		opacity: 1;
		transform: var(--wx-fx-hover-t, none);
	}
}

/* --- Parallax --------------------------------------------------------------
   Keine scroll-getriebene Animation mehr (Begruendung direkt unten). Browser
   ohne `animation-timeline` bekommen wie bisher gar nichts - der Block steht
   dann einfach still, was voellig unauffaellig ist.

   Bewegt wird nur ein Bild INNERHALB des Blocks, nicht der Block selbst: sonst
   wandert Text aus seinem Abstand heraus.

   inc/webux-effects.php laesst `parallax` fuer `webux/image-band` nicht zu: das
   Band hat seine eigene Parallaxe (assets/js/webux-parallax.js), zwei Quellen
   fuer dasselbe Bild wuerden sich streiten. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.webux-fx--parallax {
			overflow: hidden;
		}

		/* Frueher lief hier eine scroll-getriebene Animation (view(), -6 % bis
		   +6 %). Die hat Chrome nach einem Ueberscrollen am Seitenende den
		   Scroll blockieren koennen (siehe image-band/style.css) und ist
		   deshalb raus. Ihr Ergebnis war ohnehin fest: `overflow: hidden` oben
		   macht den Block selbst zum Scroll-Container, an dem view() sich
		   misst - und der scrollt nie. Der Versatz haengt also nur von der Lage
		   des Bildes im Block ab. assets/js/webux-effects.js rechnet genau
		   diesen Wert nach (parallaxOffset) und schreibt ihn in --wx-fx-par-y.
		   Das @supports bleibt, damit Browser ohne view() weiterhin gar nichts
		   bekommen - wie bisher. */
		.webux-fx--parallax :where(img, video, .webux-fx-parallax-layer) {
			translate: 0 var(--wx-fx-par-y, 0%);
			/* Der Zuschnitt gleicht die Verschiebung aus, damit an keinem Rand
			   eine Luecke entsteht. */
			scale: 1.12;
		}
	}
}

/* ===========================================================================
   2. Hover
   ===========================================================================
   Hover-Effekte haengen an `webux-fx-h--<name>`. Sie brauchen kein JavaScript
   (Ausnahme: `tilt` und `spotlight` lesen die Zeigerposition) und keine
   Armierung - ein Hover kann nichts verbergen.

   Drei Entwurfsentscheidungen, jede aus einem echten Fehler geboren:

   a) JEDE Bewegung laeuft ueber --wx-fx-hover-t und nicht ueber ein direktes
      `transform`. Der Zielzustand der Einblendung wiegt 0,3,0 und wuerde ein
      Hover-transform (0,2,0) sonst schlicht ueberstimmen.

   b) Alles, was an `:hover` haengt, steht in `@media (hover: hover)`. Auf einem
      Touchgeraet bleibt ein einmal ausgeloester Hover-Zustand nach dem Antippen
      kleben; ihn nachtraeglich zu neutralisieren hiesse, die eigenen Werte des
      Blocks (Rahmenfarbe, Schatten) mit zu ueberschreiben. Er wird deshalb dort
      gar nicht erst gesetzt.

   c) `:focus-within` steht ausserhalb dieser Abfrage - es kommt von der
      Tastatur, nicht vom Finger, und muss auf jedem Geraet wirken
      (WCAG 2.1: Bedienung nicht nur per Zeiger). */

.webux-fx-h--lift,
.webux-fx-h--glow,
.webux-fx-h--zoom-media,
.webux-fx-h--tilt,
.webux-fx-h--sheen,
.webux-fx-h--border,
.webux-fx-h--press,
.webux-fx-h--spotlight {
	transition:
		transform var(--wx-fx-hover-dur) var(--wx-fx-hover-ease),
		box-shadow var(--wx-fx-hover-dur) var(--wx-fx-hover-ease),
		border-color var(--wx-fx-hover-dur) var(--wx-fx-hover-ease),
		filter var(--wx-fx-hover-dur) var(--wx-fx-hover-ease);
}

/* Ruhelage der bewegten Effekte: der Wert kommt aus der Variablen (a).
   Ohne Hover steht dort nichts und `none` gilt - wie ohne diese Datei. */
.webux-fx-h--lift,
.webux-fx-h--glow,
.webux-fx-h--tilt,
.webux-fx-h--press {
	transform: var(--wx-fx-hover-t, none);
}

/* --- Bild zoomt im Rahmen ---------------------------------------------------
   Zwei Selektoren, weil die Klasse mal am Rahmen selbst sitzt (core/image
   rendert eine <figure> als Wurzel, Galeriekacheln ebenso) und mal am Block
   darum herum (eine Karte mit einer Bildfigur darin). Ohne den ersten Fall
   waechst das Bild aus seinem Rahmen heraus statt darin zu zoomen.

   Der Zuschnitt braucht den Radius des Bildes, sonst schneidet ein eckiger
   Rahmen beim Ueberfahren genau die Rundung weg, die vorher zu sehen war. Ein
   Rahmen kennt den Radius seines Kindes nicht, deshalb steht er in einer
   Variablen mit 0 als Vorgabe - die zwei Bloecke, die das BILD und nicht seinen
   Rahmen runden, tragen ihn unten nach. */
.webux-fx-h--zoom-media:where(figure, .wp-block-image, [class*="__media"], [class*="__image"]),
.webux-fx-h--zoom-media :where(figure, .wp-block-image, [class*="__media"], [class*="__image"]) {
	overflow: hidden;
	border-radius: var(--wx-fx-media-radius, 0);
}

.webux-fx-h--zoom-media :where(img, video) {
	transition: transform calc(var(--wx-fx-hover-dur) * 1.6) var(--wx-fx-hover-ease);
}

/* Teaser: hell/dunkel runden das Bild selbst (0.75rem). Die Karten-Variante
   nicht - dort raeumt die Karte mit ihrem eigenen Radius auf, und ein Radius am
   Rahmen wuerde eine Kerbe in die randlose Karte schneiden. */
.webux-teaser.webux-fx-h--zoom-media:not(.is-style-card) .webux-teaser__media {
	--wx-fx-media-radius: 0.75rem;
}

/* Karte: Bild-Eckenradius kommt aus dem Blockfeld „Bild-Eckenradius". */
.webux-card.webux-fx-h--zoom-media .webux-card__media {
	--wx-fx-media-radius: var(--webux-cards-mediar, 0);
}

/* --- Luft fuer den Schatten rahmenloser Karten -------------------------------
   Eine Karte ohne Hintergrund und ohne Rand, deren Textkoerper keinen seitlichen
   Innenabstand hat (Bild und Text stehen buendig an der Kartenkante), hat beim
   Anheben nichts, was den Schatten von den Buchstaben trennt: er laeuft direkt
   an ihnen entlang.

   Der Innenabstand schafft ihm Luft, das gleich grosse negative Aussenmass gibt
   sie dem Layout zurueck - Bild, Titel und Text bleiben auf den Pixel genau, wo
   sie waren, groesser wird nur der Kasten, auf dem der Schatten liegt. Dauerhaft
   und nicht erst beim Ueberfahren: ein Innenabstand, der bei Hover entstuende,
   waere ein Sprung.

   Warum hier und nicht in der site.css: die wird zusaetzlich aus dem separaten
   Immo-Repo deployt und ueberschrieben. Der Selektor bleibt trotzdem eng - die
   Regel gilt nur fuer eine Karte, die den Hebe-Effekt auch wirklich traegt. */
.lv-services .webux-card.webux-fx-h--lift {
	padding: 12px;
	margin: -12px;
}

/* --- Unterstrich ------------------------------------------------------------
   Der Strich liegt auf einem Verlauf im Hintergrund, damit die Schrift selbst
   unangetastet bleibt (text-decoration liesse sich nicht animieren). */
.webux-fx-h--underline :where(a, .webux-teaser__title, .webux-card__title) {
	background-image: linear-gradient(var(--wx-fx-tint), var(--wx-fx-tint));
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0 1px;
	transition: background-size var(--wx-fx-hover-dur) var(--wx-fx-hover-ease);
	text-decoration: none;
}

.webux-fx-h--underline :where(a):focus-visible {
	background-size: 100% 1px;
}

/* --- Lichtreflex ------------------------------------------------------------
   Ein schmaler heller Streifen wandert einmal ueber die Flaeche. Liegt auf
   einem ::after, ist zeigerdurchlaessig und deckt nichts ab. */
.webux-fx-h--sheen {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.webux-fx-h--sheen::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 45%;
	pointer-events: none;
	z-index: 2;
	opacity: 0;
	background: linear-gradient(
		100deg,
		rgba(255, 255, 255, 0) 0%,
		rgba(255, 255, 255, 0.45) 50%,
		rgba(255, 255, 255, 0) 100%
	);
	/* translateX statt `left`: `left` zu animieren waere Layout je Frame, und
	   der Vertrag oben sagt opacity/transform/filter/clip-path. */
	transform: translateX(-140%) skewX(-18deg);
}

/* --- Zeiger-Lichtkegel ------------------------------------------------------
   Ein weicher Radialverlauf folgt dem Zeiger. Die Position schreibt
   assets/js/webux-effects.js in --wx-mx / --wx-my; ohne Skript bleibt der Kegel
   bei 50%/50% und ist schlicht ein zentrierter Schimmer. */
.webux-fx-h--spotlight {
	position: relative;
	isolation: isolate;
}

.webux-fx-h--spotlight::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 1;
	opacity: 0;
	transition: opacity var(--wx-fx-hover-dur) var(--wx-fx-hover-ease);
	background: radial-gradient(
		42rem circle at var(--wx-mx, 50%) var(--wx-my, 50%),
		rgba(255, 255, 255, 0.16),
		transparent 45%
	);
}

/* --- Fokus-Zustand (jedes Geraet) ------------------------------------------ */
.webux-fx-h--lift:focus-within,
.webux-fx-h--glow:focus-within {
	box-shadow: var(--wx-fx-shadow);
}

.webux-fx-h--border:focus-within {
	border-color: var(--wx-fx-tint);
	box-shadow: inset 0 0 0 1px var(--wx-fx-tint), var(--wx-fx-shadow-soft);
}

.webux-fx-h--spotlight:focus-within::before {
	opacity: 1;
}

.webux-fx-h--underline:focus-within :where(a, .webux-teaser__title, .webux-card__title) {
	background-size: 100% 1px;
}

/* --- Zeiger-Zustand (nur Geraete mit echtem Hover) ------------------------- */
@media (hover: hover) {

	.webux-fx-h--lift:hover,
	.webux-fx-h--glow:hover {
		box-shadow: var(--wx-fx-shadow);
	}

	.webux-fx-h--glow:hover {
		/* Erst der Markenschein, darunter der Tiefenschatten. color-mix mit einer
		   Vorab-Deklaration: aeltere Engines nehmen die erste Zeile. */
		box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06), var(--wx-fx-shadow);
		box-shadow:
			0 0 0 1px color-mix(in srgb, var(--wx-fx-tint) 35%, transparent),
			0 14px 44px -18px color-mix(in srgb, var(--wx-fx-tint) 60%, transparent),
			var(--wx-fx-shadow);
	}

	.webux-fx-h--border:hover {
		border-color: var(--wx-fx-tint);
		box-shadow: inset 0 0 0 1px var(--wx-fx-tint), var(--wx-fx-shadow-soft);
	}

	.webux-fx-h--underline:hover :where(a, .webux-teaser__title, .webux-card__title) {
		background-size: 100% 1px;
	}

	.webux-fx-h--spotlight:hover::before {
		opacity: 1;
	}
}

/* Bewegungsanteil: Zeiger UND Bewegung erlaubt. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {

	.webux-fx-h--lift:hover,
	.webux-fx-h--glow:hover {
		--wx-fx-hover-t: translate3d(0, calc(var(--wx-fx-lift) * -1), 0);
	}

	.webux-fx-h--press:hover {
		--wx-fx-hover-t: scale(0.985);
	}

	/* Neigen zum Zeiger. --wx-rx / --wx-ry setzt das Skript; ohne Skript bleibt
	   beides 0 und der Effekt faellt still auf das blosse Anheben zurueck. */
	.webux-fx-h--tilt {
		transform-style: preserve-3d;
	}

	.webux-fx-h--tilt:hover {
		--wx-fx-hover-t:
			perspective(900px)
			rotateX(var(--wx-rx, 0deg))
			rotateY(var(--wx-ry, 0deg))
			translate3d(0, calc(var(--wx-fx-lift) * -0.5), 0);
		box-shadow: var(--wx-fx-shadow);
	}

	.webux-fx-h--zoom-media:hover :where(img, video) {
		transform: scale(var(--wx-fx-media-zoom));
	}

	.webux-fx-h--sheen:hover::after {
		opacity: 1;
		animation: webux-fx-sheen 900ms var(--wx-fx-hover-ease) 1;
	}

	@keyframes webux-fx-sheen {
		from { transform: translateX(-140%) skewX(-18deg); }
		to   { transform: translateX(320%) skewX(-18deg); }
	}
}

/* Fokus-Bewegung (Tastatur, jedes Geraet). */
@media (prefers-reduced-motion: no-preference) {
	.webux-fx-h--lift:focus-within,
	.webux-fx-h--glow:focus-within {
		--wx-fx-hover-t: translate3d(0, calc(var(--wx-fx-lift) * -1), 0);
	}

	.webux-fx-h--zoom-media:focus-within :where(img, video) {
		transform: scale(var(--wx-fx-media-zoom));
	}
}

/* ===========================================================================
   3. Druck
   ===========================================================================
   Beim Drucken wird nie gescrollt, der IntersectionObserver feuert also nie.
   Ein armierter, aber nicht enthuellter Block kaeme leer aufs Papier. Der
   gesamte Effekt ist reine Bildschirm-Choreografie und wird hier aufgehoben. */
@media print {
	.webux-fx,
	.webux-fx.is-fx-armed,
	.webux-fx.is-fx-armed .webux-fx-i {
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
		clip-path: none !important;
		transition: none !important;
		animation: none !important;
	}

	.webux-fx-h--sheen::after,
	.webux-fx-h--spotlight::before {
		display: none !important;
	}
}
