/* ============================================================
   PCG MOTION — Scroll-Reveal + Hover-Lift (Quick Task 260811-3im)
   Cowork-Brief: design-exports/AUFTRAG_Claude_Code_Animationen_Motion.md

   OWNS: jede neue Motion-/Animations-Regel dieser Runde (Scroll-Reveal-
   Entrance, Hover-Lift auf klickbaren Karten/Kacheln, prefers-reduced-
   motion-Absicherung, optionaler H2-Akzent). Zuständig NICHT für
   allgemeines responsives/mobiles Layout (das bleibt pcg-responsive.css,
   D-01 - ein anderes Thema mit einem anderen Eigentümer, siehe
   CONVENTIONS.md "ein Eigentümer pro Aufgabe").

   MUSS NACH `bricks-frontend-inline` (dem Bricks-Custom-CSS-Handle)
   gedruckt werden - functions.php bindet diese Datei genau mit dieser
   wp_style_is()-abgesicherten Abhängigkeit ein, sonst verliert diese
   Datei die Kaskaden-Bindung gegen die Bricks-Custom-CSS-Spiegeldatei
   (design-exports/PCG_GlobalCSS_bereinigt.css).

   Es werden ausschließlich `transform`/`opacity` animiert (plus
   `box-shadow`/`border-color` bei reinen Hover-Regeln) - keine
   Layout-Eigenschaften, kein `will-change`, keine Keyframe-Animation.

   Quick task 260821-g06 (AUFTRAG A1, "Rolex Motion Feinschliff"): die
   Scroll-Reveal-Entrance nutzt genau EINE sanktionierte eigene Easing-Kurve,
   `cubic-bezier(0.16, 1, 0.3, 1)` - jede weitere eigene Kurve in dieser
   Datei ist ein Fehler. Alle Hover-/Settle-Timings fahren weiterhin über
   das gemeinsame `--pcg-ease`-Token (pcg-elevation.css), keine zweite
   eigene Kurve dort.

   Quick task 260821-man (Schritt C1): die Kurve und die Dauer der
   Reveal-Entrance sind jetzt NICHT mehr hier als Literal notiert, sondern
   über `var(--pcg-ease-entrance, ...)` / `var(--pcg-dur-entrance, ...)` aus
   pcg-elevation.css eingebunden - dort liegt jetzt die einzige
   Quelle der Wahrheit für diesen Wert, mit demselben Literal als Fallback,
   falls diese Datei je vor pcg-elevation.css geladen würde. Sichtbar ändert
   sich nichts (byte-identische Werte).
   ============================================================ */

/* --- Scroll-Reveal-Entrance (MOTION-01, Brief §1) -------------------------
   Wird NUR versteckt, solange html.pcg-motion gesetzt ist (gesetzt durch
   das inline Head-Boot-Skript in functions.php - siehe dessen eigener
   Kommentar dort für die vollständige Sicherheitskette). Keine andere
   Regel in dieser Datei, und nirgendwo sonst im Theme, darf ein
   opacity:0 außerhalb dieses html.pcg-motion-Präfixes setzen - das wäre
   der einzige wirklich schlimme Fehlerfall eines Scroll-Reveals (Inhalt
   dauerhaft unsichtbar), und er ist hier strukturell unmöglich, weil
   nichts ohne diese Klasse versteckt wird. Bewusst ausgeschlossen:
   .pcg-hero-h1/.pcg-h1 (voraussichtliches LCP-Element, D-06), .pcg-body
   (Lesbarkeit, D-07/Brief VERMEIDEN), sowie alles im Preisrechner,
   KI-Visualizer, Header und Footer.

   Quick task 260811-ldk (Task 2c, EDITOR-03): inside the Bricks builder,
   html.pcg-motion is now never armed at all (see the
   pcg_is_bricks_builder() guard around the pcg-motion-boot script in
   functions.php), and wp-content/themes/bricks-child/assets/css/
   pcg-builder.css force-shows these same seven selectors as a belt-and-
   braces layer. Live behaviour on this file is UNCHANGED by this round -
   no declaration below was touched, only this comment was added. --------- */
html.pcg-motion .pcg-h2,
html.pcg-motion .pcg-eyebrow,
html.pcg-motion .pcg-lead,
html.pcg-motion .pcg-card,
html.pcg-motion .pcg-box,
html.pcg-motion .pcg-step,
html.pcg-motion a.brxe-block[href^="/leistungen/"] {
	opacity: 0;

	/* Quick task 260908-1lk ("ruhiger, weniger Spielerei", Kundenentscheidung
	   vom 08.09.2026). Zwei neue Stellschrauben, bewusst NICHT ueber
	   --pcg-dur-entrance: dieses Token steckt auch in Hover- und
	   Settle-Regeln, es hier zu aendern haette dort mitgezogen.

	   Und bewusst OHNE :root-Deklaration irgendwo im Theme - genau wie
	   --pcg-hero-* und --pcg-gallery-aspect-ratio. Grund: das
	   Bricks-Custom-CSS-Feld wird VOR allen Theme-Dateien ausgeliefert
	   (nachgemessen: Position 9 von 24). Gaebe es hier ein :root mit einem
	   Wert, wuerde es das Kundenfeld ueberstimmen. So gewinnt das Feld, und
	   ohne Feld gilt der Rueckfallwert hier.

	   26px -> 10px und .7s -> .45s: die Kacheln kommen jetzt fast
	   gleichzeitig statt einzeln nacheinander. */
	transform: translateY(var(--pcg-reveal-weg, 10px));
	transition: opacity var(--pcg-reveal-dauer, .45s) var(--pcg-ease-entrance, cubic-bezier(0.16, 1, 0.3, 1)), transform var(--pcg-reveal-dauer, .45s) var(--pcg-ease-entrance, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Eingeblendeter Zustand - JS setzt .pcg-revealed genau einmal pro Element
   (wiederholt sich nie, Brief §1 "einmalig"). transform:none statt
   translateY(0), damit kein Compositor-Layer und keine Safari-
   Subpixel-Textunschärfe nach dem Einblenden übrig bleibt. */
html.pcg-motion .pcg-revealed {
	opacity: 1;
	transform: none;
}

/* Der Selektor der Gewerke-Kachel (0,3,2: eine Klasse + ein Attribut + ein
   Tag) schlägt die einfache .pcg-revealed-Regel oben (0,2,1: zwei Klassen)
   in der Spezifität - ohne diese selektor-gebundene Variante blieben die
   vier Kacheln nach dem Reveal dauerhaft unsichtbar (key_links Eintrag 1,
   genau dieser eine Fehlerfall). */
html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed {
	opacity: 1;
	transform: none;
}

/* Settle-Zustand - JS setzt .pcg-motion-settled REVEAL_SETTLE_MS nach
   Abschluss des Reveals und übergibt damit das Transition-Timing von der
   0.7s-Entrance zurück auf die var(--pcg-ease)-Hover-Geschwindigkeit (=.22s)
   (key_links Eintrag 4) - ohne das würde jeder Hover auf einem
   eingeblendeten Element mit Reveal-Geschwindigkeit laufen.
   Quick task 260821-g06: REVEAL_SETTLE_MS (site-interactions.js) ist
   ABSICHTLICH größer als diese Entrance-Dauer (750ms > 700ms) gehalten -
   wird nur einer der beiden Werte geändert, reißt der Opacity-Fade
   mittendrin ab (die Settle-Regel ersetzt die Transition und lässt
   `opacity` aus der Eigenschaftsliste fallen, bevor der Fade fertig ist).
   Immer beide Werte gemeinsam ändern. */
/* Quick task 260820-o8f: duration re-pointed from a hard-coded .25s onto the
   shared --pcg-ease token (pcg-elevation.css) so the settle-state speed and the
   box/card/step/filter-button hover speed are the same one timing curve
   site-wide. The a.brxe-block[href^="/leistungen/"] Gewerke-tile rule below is
   explicitly out of this plan's scope (AUFTRAG D/F/G) and is left untouched
   other than this same shared-token substitution its own selector already used. */
html.pcg-motion .pcg-motion-settled {
	transition: transform var(--pcg-ease) ease, box-shadow var(--pcg-ease) ease;
}
html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-motion-settled {
	transition: transform .25s ease, box-shadow .25s ease;
}

/* --- Hover-Lift auf KLICKBAREN Karten/Kacheln (MOTION-02, Brief §2) -------
   `@media (hover: hover) and (pointer: fine)` schließt Touch-Geräte aus,
   damit dort kein Hover-Zustand hängen bleibt (kein echtes "Hover" auf dem
   Handy). Info-Kästen (.pcg-box, .pcg-step) bekommen bewusst KEINE
   Hover-Regel hier (D-05) - sonst würde fälschlich "klickbar" signalisiert,
   wo es nichts zu klicken gibt. .bricks-button wird hier NICHT neu
   definiert - die Bricks-Custom-CSS bleibt dessen alleiniger Eigentümer
   (Brief §3, Bestätigung nur, kein Neubau). -------------------------------- */
@media (hover: hover) and (pointer: fine) {
	/* Projekt-/Referenzkarten: die Basisbehandlung existiert bereits in der
	   Bricks-Custom-CSS (design-exports/PCG_GlobalCSS_bereinigt.css,
	   .pcg-card:hover) und bleibt dort. Diese Datei ergänzt nur die
	   Varianten, die der Reveal-Transform sonst in der Spezifität schlagen
	   würde. :focus-within ist das Tastatur-Äquivalent, weil
	   .pcg-card-link das eigentliche Fokus-Ziel ist. */
	/* Quick task 260820-o8f: re-pointed onto pcg-elevation.css's shared --pcg-lift/
	   --pcg-elev-hover tokens (was a hard-coded translateY(-5px) that outranked
	   pcg-elevation.css's plain .pcg-card:hover at this rule's higher (0,3,1)
	   specificity, so revealed cards kept lifting 5px while every other box lifted
	   4px - exactly the inconsistency AUFTRAG "Globaler Feinschliff" Punkt B asks to
	   remove). Site-wide there is now exactly one lift value. */
	html.pcg-motion .pcg-card.pcg-revealed:hover,
	html.pcg-motion .pcg-card.pcg-revealed:focus-within {
		transform: translateY(calc(-1 * var(--pcg-lift)));
		box-shadow: var(--pcg-elev-hover);
	}
	/* Quick task 260908-1lk: der Bild-Zoom beim Hover ist die "Spielerei", die
	   der Kunde am 08.09.2026 ausdruecklich raus haben wollte - das Anheben
	   der Karte bleibt, der Zoom nicht. Rueckfall ist 1 (= kein Zoom); wer
	   ihn zurueckholen will, setzt --pcg-karte-zoom im Bricks-Feld auf 1.03.
	   Die Regel selbst bleibt bewusst stehen: sie schlaegt die Reveal-Regel
	   in der Spezifitaet, und ein ersatzloses Loeschen haette den
	   Karten-Hover dem Zufall der Kaskade ueberlassen. */
	html.pcg-motion .pcg-card.pcg-revealed:hover .pcg-card-media img {
		transform: scale(var(--pcg-karte-zoom, 1));
	}

	/* Vier Gewerke-Kacheln: tragen keine .pcg-* Klasse - der href-Präfix ist
	   der stabile, live-bestätigte Weg, sie zu erreichen (discovered fact
	   5). Eigene Transition außerhalb von html.pcg-motion, damit die Kachel
	   auch dann einen Hover hat, falls JS/Reveal aus irgendeinem Grund nie
	   greift (z.B. IntersectionObserver fehlt) - und die
	   html.pcg-motion-Variante, damit sie auch gegen die Reveal-Regel
	   gewinnt, sobald sie eingeblendet ist. */
	a.brxe-block[href^="/leistungen/"] {
		transition: transform .25s ease, box-shadow .25s ease;
	}
	a.brxe-block[href^="/leistungen/"]:hover,
	a.brxe-block[href^="/leistungen/"]:focus-visible,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:hover,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:focus-visible {
		transform: translateY(-5px);
		box-shadow: 0 18px 40px rgba(20, 36, 64, 0.16), 0 3px 8px rgba(20, 36, 64, 0.08);
	}
	a.brxe-block[href^="/leistungen/"] img {
		transition: transform .4s ease;
	}
	/* Quick task 260908-1lk: gleiche Stellschraube wie bei den Referenzkarten,
	   damit beide Bild-Zooms an EINEM Wert haengen und nicht auseinanderlaufen. */
	a.brxe-block[href^="/leistungen/"]:hover img,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:hover img {
		transform: scale(var(--pcg-karte-zoom, 1));
	}
}

/* --- prefers-reduced-motion (MOTION-06, Brief PFLICHT) --------------------
   Belt-and-braces hinter dem eigenen frühen Return des Head-Snippets (D-02):
   ein Besucher, der "Bewegung reduzieren" ERST NACH dem Laden der Seite
   einschaltet, landet trotzdem statisch - `!important` schlägt jede Regel
   oben unabhängig vom html.pcg-motion-Präfix. --------------------------- */
@media (prefers-reduced-motion: reduce) {
	html.pcg-motion .pcg-h2,
	html.pcg-motion .pcg-eyebrow,
	html.pcg-motion .pcg-lead,
	html.pcg-motion .pcg-card,
	html.pcg-motion .pcg-box,
	html.pcg-motion .pcg-step,
	html.pcg-motion a.brxe-block[href^="/leistungen/"],
	.pcg-card,
	a.brxe-block[href^="/leistungen/"] {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}

/* "Bewegung reduzieren" gilt auch für den Hover-Lift selbst, nicht nur für
   den Scroll-Reveal - der Kunden-Checkliste (Task 3, Schritt 7) zufolge
   darf sich unter "Bewegung reduzieren" gar nichts mehr anheben, auch nicht
   bei echtem Maus-Hover. Bewusst in DIESELBE (hover: hover)-Bedingung
   verkettet (nicht in den obigen, separaten
   @media (prefers-reduced-motion: reduce)-Block) - so bleibt jede
   :hover-Regel dieser Datei weiterhin innerhalb einer
   @media (hover: hover)-Abfrage (Datei-Konvention, siehe Kommentar oben am
   Hover-Abschnitt), und die Selektoren sind textgleich mit denen im
   Hover-Abschnitt, sodass diese Regel den !important-Gleichstand allein
   durch die spätere Position in der Datei gewinnt. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
	html.pcg-motion .pcg-card.pcg-revealed:hover,
	html.pcg-motion .pcg-card.pcg-revealed:focus-within,
	a.brxe-block[href^="/leistungen/"]:hover,
	a.brxe-block[href^="/leistungen/"]:focus-visible,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:hover,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:focus-visible {
		transform: none !important;
		box-shadow: none !important;
	}
	html.pcg-motion .pcg-card.pcg-revealed:hover .pcg-card-media img,
	a.brxe-block[href^="/leistungen/"]:hover img,
	html.pcg-motion a.brxe-block[href^="/leistungen/"].pcg-revealed:hover img {
		transform: none !important;
	}
}

/* --- Optionaler H2-Akzent (MOTION-05, Brief §5, D-04) ---------------------
   Bewusst ein OPT-IN-Klasse, nicht global auf .pcg-h2 erzwungen - eine
   sitezweite ::after-Deko würde auf ~10 Vorlagen landen (inkl. CTA-Bänder
   und beiden Tool-Seiten) ohne Vorschau-Möglichkeit hier - genau der
   "Deko-Overkill", vor dem der Brief warnt.

   Für den Kunden: Um diesen Akzent an EINER Überschrift auszuprobieren, in
   Bricks die Überschrift anklicken -> rechts Style -> CSS -> Classes ->
   dort "pcg-h2-accent" eintragen -> speichern -> Seite ansehen. Gefällt es
   nicht: Klasse einfach wieder entfernen. -------------------------------- */
.pcg-h2-accent::before {
	content: "";
	display: block;
	width: 40px;
	height: 3px;
	background: #EE0000;
	border-radius: 2px;
	margin-bottom: 12px;
}

/* --- Bestätigungs-Checks (MOTION-03 §3, MOTION-04 §4) ---------------------
   Button-Hover und Zähler-Count-up sind bereits korrekt (discovered facts
   1-3) - dieser Kommentar dokumentiert, dass sie geprüft, nicht neu gebaut
   wurden. tests/pcg-motion.test.cjs beweist es: die Bricks-Custom-CSS-
   Spiegeldatei enthält weiterhin die .bricks-button:hover- und
   .pcg-card:hover-Regeln, und diese Datei definiert nirgends
   .bricks-button. Der Count-up-Regressionstest lebt bereits in Task 1's
   JS-Assertions. -------------------------------------------------------- */

/* ============================================================
   A2 — HERO-SCROLL-TIEFE (AUFTRAG "Rolex Motion Feinschliff",
   Schritt A2, Quick Task 260821-gcr)

   Beim Scrollen durch den Hero blenden Überschrift und Untertext aus
   (opacity 1 -> 0) und driften leicht nach oben, während das
   Hero-Hintergrundbild durch eine minimale Skalierung (1.0 -> 1.06)
   plus einen kleinen Abwärts-Drift optische Tiefe gewinnt - das Bild
   "hinkt" dadurch spürbar hinter dem Text her. Desktop-only (siehe
   die @media-Bedingung unten, byte-synchron mit der JS-
   matchMedia-Konstante HERO_DESKTOP_MEDIA_QUERY in
   site-interactions.js - siehe deren eigenen Kommentar).

   Malreihenfolge (discovered fact 4, Planungsphase): Bricks rendert
   den Verlaufs-Overlay der Sektion bereits über
   `#brxe-pbqjeq::before`; `::after` ist frei. `#brxe-pbqjeq` selbst
   ist `position: relative` OHNE eigenen z-index und erzeugt daher
   KEINEN Stacking-Context - ein `::after { z-index: -1 }` würde ohne
   Gegenmaßnahme hinter das undurchsichtige Sektions-Hintergrundbild
   rutschen (unsichtbar). `isolation: isolate` auf der Sektion
   erzeugt den nötigen Stacking-Context, ohne Layout oder den
   bestehenden z-index anzufassen - damit ist die Malreihenfolge
   exakt: Sektionshintergrund -> ::after (dieser Tiefen-Layer,
   z-index -1) -> ::before (Verlaufs-Overlay) -> #brxe-vputtu
   (Inhalt).

   Coverage-Invariante (design_decision, Planungsphase): der
   Hintergrund-Drift in px MUSS unter der Hälfte des Zoom-Überhangs
   bleiben, sonst zeigt die eigene, untransformierte
   Sektions-Hintergrundfläche eine sichtbare Naht am Rand. Mit den
   Fallback-Werten unten (Zoom 0.06, Drift 16px) auf einer
   600px-hohen Referenz-Hero-Höhe: 0.06 / 2 * 600px = 18px Budget,
   16px genutzt - siehe Test "gcr: coverage invariant" in
   tests/pcg-motion.test.cjs.

   Hinweis für die künftige Sticky-Hero-Reveal-Umsetzung (ein
   eigenes, hier NICHT gebautes AUFTRAG): der Clip unten ist
   absichtlich als ZWEISTUFIGES, progressives Paar deklariert -
   `overflow: hidden` zuerst, `overflow: clip` danach (spiegelt das
   `min-height: calc(100vh + 90px)` / `calc(100svh + 90px)`-Idiom,
   das pcg-responsive.css bereits nutzt). Ältere Browser clippen über
   die erste Deklaration, moderne über die zweite - `clip` erzeugt
   (anders als `hidden`) KEINEN Scroll-Container und kann die
   künftige Sticky-Hero-Reveal daher strukturell nicht blockieren.

   Alle vier Custom Properties werden ausschließlich als
   `var(--name, FALLBACK)` konsumiert, OHNE eigenen `:root`-Default
   (gleiche Regel wie beim `--pcg-hero-`-Namensraum, discovered fact
   8) - ein `:root`-Default würde nach dem Bricks-Custom-CSS-Feld
   drucken und die eigene Übersteuerung des Kunden dort stumm
   schlagen. ============================================================ */

@media (min-width: 992px) and (hover: hover) {
	/* Quick task 260821-nq9 ("Rolex Motion Feinschliff Zwei"): `position: relative` is a
	   structural prerequisite of the ::after depth layer below (`position: absolute;
	   inset: 0` needs a positioned ancestor to paint against) - not a design value, which
	   is why it belongs here rather than in a per-section Bricks panel field. Bricks
	   already sets `position: relative` on the homepage hero via its own panel, so this is
	   a no-op there and a structural safety net on any newly-generalised section. */
	html.pcg-motion .pcg-hero-parallax,
	html.pcg-motion .pcg-hero-cine,
	html.pcg-motion .pcg-hero-about,
	html.pcg-motion .pcg-hero-ref {
		isolation: isolate;
		overflow: hidden;
		overflow: clip;
		position: relative;
	}

	/* Tiefen-Layer: übernimmt das Hintergrundbild per `background: inherit` (kein
	   fest kodiertes url(), folgt also für immer dem eigenen Hero-Bild des Kunden),
	   wird per --pcg-motion-hero-scroll (0 -> 1, geschrieben von initHeroScroll())
	   nach unten gedriftet und leicht hochskaliert. --pcg-motion-hero-parallax'
	   Fallback (16px) MUSS unter --pcg-motion-hero-zoom / 2 * 600px (=18px)
	   bleiben, siehe Coverage-Invariante oben. */
	html.pcg-motion .pcg-hero-parallax::after,
	html.pcg-motion .pcg-hero-cine::after,
	html.pcg-motion .pcg-hero-about::after,
	html.pcg-motion .pcg-hero-ref::after {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		pointer-events: none;
		background: inherit;
		transform-origin: center;
		transform:
			translateY(calc(var(--pcg-motion-hero-scroll, 0) * var(--pcg-motion-hero-parallax, 16px)))
			scale(calc(1 + var(--pcg-motion-hero-scroll, 0) * var(--pcg-motion-hero-zoom, 0.06)));
	}

	/* Überschrift + Untertext (dritter Selektor = Opt-in-Fluchttür, damit der Kunde
	   den Effekt später z.B. auf die Eyebrow oder die Buttons legen kann, indem er
	   in Bricks die Klasse "pcg-hero-fade" im Classes-Feld einträgt - ohne SFTP-
	   Runde). Der opacity-Fallback von 0 lässt den Ausdruck vor JS-Ausführung auf 1
	   auflösen (LCP-Absicherung, kein opacity:0-Startzustand).

	   Quick task 260821-nq9: vierter Selektor - `html.pcg-motion .pcg-hero-parallax
	   .pcg-hero-fade` - macht das ganze Muster erst wiederverwendbar (F5,
	   Planungsphase): die Opt-in-Fluchttür war bisher NUR innerhalb `#brxe-pbqjeq`
	   erreichbar, auf keiner anderen Sektion. Die ersten drei Selektoren bleiben
	   byte-unverändert, damit die Startseite exakt weiter so matcht wie heute.

	   `transition: none` steht jetzt explizit (statt implizit zu fehlen): die Werte
	   werden bei jedem Frame frisch aus der Scroll-Position berechnet, und eine echte
	   Inhalts-Überschrift trägt eine Typografie-Klasse (z.B. .pcg-h2), die auf die
	   Scroll-Reveal-Regel weiter oben matcht - die einzige andere Regel dieser Datei,
	   die eine `transition` deklariert - und die sonst diesen Pro-Frame-Fade über ihre
	   eigenen 0.7s verschmieren würde (F10, Planungsphase). Ein pauschaler
	   Reveal-Neutralisierungs-Block wurde erwogen und bewusst verworfen: diese
	   Fade-Regel schlägt die Reveal-Regeln bei `opacity`/`transform` bereits über die
	   Spezifität (F10) - eine pauschale Neutralisierung würde auch den gewollten
	   Reveal-Eintritt von Eyebrow/Lead in derselben Sektion töten. */
	html.pcg-motion .pcg-hero-cine > .brxe-container,
	html.pcg-motion .pcg-hero-about > .brxe-container,
	html.pcg-motion .pcg-hero-ref > .brxe-container,
	html.pcg-motion .pcg-hero-cine .pcg-hero-fade,
	html.pcg-motion .pcg-hero-about .pcg-hero-fade,
	html.pcg-motion .pcg-hero-ref .pcg-hero-fade,
	html.pcg-motion .pcg-hero-parallax .pcg-hero-fade {
		opacity: calc(1 - var(--pcg-motion-hero-scroll, 0));
		transform: translateY(calc(var(--pcg-motion-hero-scroll, 0) * var(--pcg-motion-hero-drift, -32px)));
		transition: none;
	}

	/* ============================================================
	/ueber-uns/ — Sektion 1 bekommt Sticky-Curtain + A2 (Quick Task 260824-9ht)
	============================================================
	Vom Client am 2026-08-24 freigegeben: derselbe Effekt wie auf der Startseite,
	plus der A2-Effekt ("Rolex"), und ausdruecklich NUR auf der ersten Sektion —
	nicht alle vier stapeln.

	Gemessen vor dem Bauen: alle vier Sektionen der Seite sind bildschirmhoch
	(812px) und blickdicht, Sektion 1 (`#brxe-ghlupd`) endet inhaltlich bei
	714px. Sie erfuellt die Fits-Sicherung also klar, und die Folgesektion deckt
	vollstaendig ab. Der Pin loest sich ausserdem nach dem Reveal selbst — die
	Fehlerklasse vom 2026-08-22 ist damit strukturell ausgeschlossen.

	KEIN Pin-Versatz noetig: anders als der Startseiten-Hero (`margin-top:-90px`)
	liegt diese Sektion im normalen Fluss. `--pcg-curtain-top` bleibt also beim
	Standard `0px`.

	A2-FADE-ZIEL IST DER GANZE INHALTS-CONTAINER, NICHT NUR DIE UEBERSCHRIFT —
	und das ist eine bewusste Abweichung vom Startseiten-Muster: dort schwebt der
	Hero-Text frei, hier sitzt er in den navy-transparenten Kaesten
	(`.pcg-glassbox`, Quick Task 260824-4kd). Nur die Ueberschrift auszublenden
	wuerde einen sichtbar leeren Kasten stehen lassen. Stattdessen tritt der
	komplette Inhalt zurueck (Textkasten UND Zahlen-Kacheln), waehrend das Foto
	uebernimmt — dasselbe Empfinden wie auf der Startseite, nur an diesen Aufbau
	angepasst.
	============================================================ */
	html.pcg-motion #brxe-ghlupd > .brxe-container {
		opacity: calc(1 - var(--pcg-motion-hero-scroll, 0));
		transform: translateY(calc(var(--pcg-motion-hero-scroll, 0) * -32px));
		transition: none;
	}
}

/* Belt-and-braces hinter initHeroScroll()'s eigenem html.pcg-motion-Gate (D-02-
   Muster, wie beim Scroll-Reveal oben): ein Besucher, der "Bewegung reduzieren"
   ERST NACH dem Laden der Seite einschaltet, landet trotzdem vollständig statisch
   und mit dauerhaft lesbarer Überschrift. Danach platziert, damit die
   !important-Regeln in der Druckreihenfolge gewinnen. Bewusst OHNE transition -
   Block 1 deklariert keine, es gibt also nichts zu kappen. */
@media (prefers-reduced-motion: reduce) {
	html.pcg-motion .pcg-hero-parallax,
	html.pcg-motion .pcg-hero-cine,
	html.pcg-motion .pcg-hero-about,
	html.pcg-motion .pcg-hero-ref,
	html.pcg-motion .pcg-hero-parallax::after,
	html.pcg-motion .pcg-hero-cine::after,
	html.pcg-motion .pcg-hero-about::after,
	html.pcg-motion .pcg-hero-ref::after,
	html.pcg-motion .pcg-hero-cine > .brxe-container,
	html.pcg-motion .pcg-hero-about > .brxe-container,
	html.pcg-motion .pcg-hero-ref > .brxe-container,
	html.pcg-motion .pcg-hero-cine .pcg-hero-fade,
	html.pcg-motion .pcg-hero-about .pcg-hero-fade,
	html.pcg-motion .pcg-hero-ref .pcg-hero-fade,
	html.pcg-motion .pcg-hero-parallax .pcg-hero-fade {
		opacity: 1 !important;
		transform: none !important;
	}
}

/* ============================================================
   STICKY-HERO-CURTAIN (AUFTRAG Punkt F, Quick Task 260824-c7x)
   ============================================================
   Eine Sektion bleibt oben am Bildschirmrand kleben, waehrend die folgenden
   Sektionen darueber hinwegscrollen und sie zudecken - der cinematische Reveal
   aus Punkt F des Cowork-Auftrags. Erste und einzige Instanz: der
   Startseiten-Hero.

   (1) BEWUSST NICHT im Desktop-Block dieser Datei, anders als der A2-Effekt
   darueber. `position: sticky` wird vom Compositor gerechnet - kein
   Scroll-Listener, kein Layout-Thrash - und laeuft auf iOS Safari und Android
   genauso sauber wie auf dem Desktop. Der Kunde hat den Effekt am 2026-08-24
   ausdruecklich auch fuer Handys freigegeben, sofern er dort nichts kaputt
   macht. Was der alte Auftrag zu Recht verbietet, ist
   `background-attachment: fixed` - eine voellig andere Technik, die hier
   nirgends vorkommt.

   Die Bewegungs-Notausstiege bleiben: `html.pcg-motion` faellt bei
   `prefers-reduced-motion`, bei fehlendem IntersectionObserver und beim
   Reveal-Failsafe weg, und damit auch dieser Effekt.

   (2) ZWEI SELEKTOREN, wie beim A2-Effekt weiter oben: die wiederverwendbare
   Opt-in-Klasse `pcg-curtain` und die Hero-ID `#brxe-pbqjeq`. Die ID erspart
   dem Kunden das Eintragen einer Klasse im Bricks-Editor (dort ist das
   Entfernen einer Klasse ein bestaetigter Blocker, das Hinzufuegen ginge zwar,
   aber die ID-Variante ist hier praezedenzgestuetzt und aufwandsfrei). Die
   Klasse bleibt fuer jede kuenftige Sektion nutzbar.

   (3) `pcg-curtain-fits` wird von initCurtain() (site-interactions.js,
   Behaviour 8) gesetzt und nur dann, wenn der INHALT der Sektion - nicht ihre
   Box-Hoehe - beim gewaehlten Pin-Versatz noch vollstaendig auf den Bildschirm
   passt. Ohne diese Sicherung waere eigener unterer Inhalt hinter dem eigenen
   Pin dauerhaft unerreichbar. Genau daran ist der Effekt am 2026-08-22 auf
   /ueber-uns/ gescheitert: eine 508px kurze Sektion blieb ueber die gesamte
   restliche Seite angeheftet.

   (4) `--pcg-curtain-top` ist der Pin-Versatz, Standard `0px`. Der
   Startseiten-Hero steht ungepinnt bereits bei `margin-top: -90px` unter dem
   transparenten Header; mit `-90px` bleibt seine Bildausschnitt-Wirkung
   gepinnt exakt dieselbe wie heute. JS liest denselben Wert, damit
   Sicherung und Darstellung nie auseinanderlaufen.
   ============================================================ */

/* Ungated und ausserhalb jeder Media Query - macht die Klasse auf jeder
   kuenftigen Sektion selbststaendig, gilt auch im Bricks-Editor-Canvas, und ist
   ein No-op auf `#brxe-pbqjeq`, das denselben Wert schon vom Panel bekommt. */
.pcg-curtain {
	position: relative;
}

/* Das `!important` ist unvermeidbar und deshalb hier begruendet: das
   Bricks-Panel schreibt `#brxe-pbqjeq{position:relative}` ID-gebunden, und
   keine Klassenregel schlaegt eine ID-Regel. Der Panel-Wert bleibt bewusst
   stehen - der Bricks-Editor-Canvas, die Handy-Darstellung und das eigene
   ::before-Verlaufs-Overlay der Sektion brauchen alle einen positionierten
   Vorfahren. `top` traegt bewusst KEIN !important, damit der Kunde den
   Versatz jederzeit ueberschreiben kann. */
html.pcg-motion .pcg-curtain.pcg-curtain-fits,
html.pcg-motion .pcg-hero-ref.pcg-curtain-fits {
	position: sticky !important;
	top: var(--pcg-curtain-top, 0px);
}

/* Der Hero-Versatz. Als eigene Regel statt im Panel, weil JS denselben Wert
   liest - ein Panel-Wert waere fuer die Sicherung unsichtbar. */
/* Umgezogen 2026-08-25 (QS-Auftrag): stand vorher auf `#brxe-pbqjeq`. Die ID
   existiert seit dem Neubau des Heros nicht mehr, der Versatz war damit
   verloren — am Live-DOM nachgemessen: `--pcg-curtain-top` war leer, der Hero
   pinnte also 90px zu tief und der Fits-Waechter rechnete mit dem falschen Wert.
   Der Wert gehoert NUR an die Startseite: nur ihr Hero traegt `margin-top:-90px`
   (ebenfalls nachgemessen), /ueber-uns/ und /referenzen/ stehen bei 0. */
.pcg-hero-cine {
	--pcg-curtain-top: -90px;
}

/* Load-bearing: eine gepinnte Sektion wird durch nichts begrenzt - ihr
   enthaltendes Element ist `<main id="brx-content">`, das jede Sektion haelt.
   Ein NICHT positioniertes spaeteres Geschwisterelement malt UNTER einem
   positionierten; ohne diese Regel wuerde die gepinnte Sektion ueber jede
   spaetere Sektion malen, statt von ihr zugedeckt zu werden. Das `!important`
   ist noetig, weil Bricks-Panel-Werte auf einzelnen Sektionen ID-gebunden
   `position: relative` bzw. `static` schreiben koennen. */
html.pcg-motion .pcg-curtain.pcg-curtain-fits ~ *,
html.pcg-motion .pcg-hero-ref.pcg-curtain-fits ~ * {
	position: relative !important;
}




/* ============================================================
   /referenzen/ — die zudeckende Sektion muss blickdicht sein
   (Quick Task 260824-p2s)
   ============================================================
   VORAUSSETZUNG DES GANZEN EFFEKTS, nicht Kosmetik: eine gepinnte Sektion wird
   nur dadurch unsichtbar, dass die naechste sie ZUDECKT. `#brxe-onjufr` (die
   Projektkarten samt Gewerke-Filter, direkt unter dem Hero) hatte
   `background-color: rgba(0, 0, 0, 0)` — sie war durchsichtig und liess das
   Weiss des `<body>` durch. Ohne diese Regel saehe man beim Scrollen das
   Hero-Foto DURCH die Karten hindurch: exakt der Fehler, den der Kunde am
   2026-08-24 gemeldet hat.

   Der Wert ist bewusst genau das Weiss, das dort ohnehin schon zu sehen ist
   (`<body>` = `rgb(255, 255, 255)`, am Live-DOM nachgemessen). **Optisch
   aendert sich also nichts** — die Farbe wird nur von "geerbt" auf "gesetzt"
   umgestellt, damit sie ueberhaupt etwas verdecken kann.

   Kein `!important`: der Kunde soll diese Farbe jederzeit im Bricks-Panel
   ueberschreiben koennen. Wichtig ist nur, dass sie nicht durchsichtig bleibt.
   ============================================================ */
#brxe-onjufr {
	background-color: var(--pcg-refcards-bg, #fff);
}


/* ============================================================
   QS 260825 — JEDE zudeckende Sektion muss blickdicht sein
   ============================================================
   KUNDENMELDUNG 2026-08-25: „auf der Startseite schiebt die zweite Sektion in
   den Hero, ohne die Abgrenzung der Sektion". Am Live-DOM nachgemessen und
   bestaetigt: von sieben Sektionen der Startseite ist genau EINE durchsichtig —
   `#brxe-ivwuvq` mit `background-color: rgba(0,0,0,0)` — und das ist die
   Sektion direkt hinter dem gepinnten Hero. Alle sechs anderen haben eine
   Farbe. Beim Scrollen sieht man deshalb das Hero-Foto durch sie hindurch.

   DAS IST KEIN NEUER FEHLER, sondern derselbe wie am 2026-08-24 auf
   /referenzen/ (Quick Task 260824-p2s, `#brxe-onjufr`). Voraussetzung des
   ganzen Curtain-Effekts ist, dass die naechste Sektion die gepinnte ZUDECKT;
   eine durchsichtige Sektion kann das nicht.

   WARUM DIESE REGEL AUF KLASSEN STATT AUF DER ID STEHT — die Lehre aus genau
   dieser Sitzung: der Vorgaenger-Fix war ID-gebunden. Beim naechsten Neubau der
   Sektion vergibt Bricks eine neue Nummer, und der Fix faellt lautlos aus. Am
   selben Tag ist der Hero-Scroll-Effekt aus exakt diesem Grund monatelang
   unbemerkt tot gewesen. Diese Regel greift deshalb jede Geschwister-Sektion
   eines gepinnten Curtains, heute und nach jedem Umbau.

   WARUM DIE BEIDEN `:not()` — Sektionen, die ihre Farbe SELBST mitbringen,
   sollen sie behalten: `.pcg-navy` (Navy) und `.pcg-bg-light` (Hellgrau) sind
   die beiden Farbklassen des Design-Systems. Nur Sektionen ohne eigene Farbe
   bekommen hier einen Boden. Heute betrifft das genau eine Sektion; die Regel
   ist aber die Versicherung fuer alle kuenftigen.

   WARUM `#fff` — es ist die Farbe, die dort ohnehin zu sehen ist: eine
   durchsichtige Sektion zeigt das Weiss des `<body>` (am Live-DOM
   nachgemessen). **Optisch aendert sich also nichts** ausser dem, was der Kunde
   gemeldet hat: die Farbe wird von „geerbt" auf „gesetzt" umgestellt, damit sie
   ueberhaupt etwas verdecken kann.

   KEIN `!important`, und die Spezifitaet ist mit (0,4,0) bewusst niedriger als
   jede ID-Regel: setzt der Kunde im Bricks-Panel eine Hintergrundfarbe auf die
   Sektion, gewinnt sein Wert. Das ist die Hausregel aus `.claude/CLAUDE.md` —
   Panel schlaegt Datei.
   ============================================================ */
html.pcg-motion .pcg-curtain.pcg-curtain-fits ~ .pcg-section:not(.pcg-navy):not(.pcg-bg-light),
html.pcg-motion .pcg-hero-ref.pcg-curtain-fits ~ .pcg-section:not(.pcg-navy):not(.pcg-bg-light) {
	background-color: var(--pcg-curtain-cover-bg, #fff);
}

/* ============================================================
   UNTERMENÜ OHNE AUFPLOPP-ANIMATION AM HANDY
   (Quick-Task 260908-r9m, Client 2026-09-08)

   DER CLIENT, wörtlich: „Die Animation auf dem Handy, wenn man das
   Dropdown-Menü öffnet, verwirrt ein bisschen. Es ist eine Verkaufsseite
   und keine Spielseite. Es ploppt von innen nach außen auf. Ich würde es
   bevorzugen, wenn es ohne Animation aufploppt."

   WAS DAS AUFPLOPPEN ERZEUGT — live gemessen am 2026-09-08 bei 386px:
   Bricks setzt auf jedes Untermenü seine globale Kurzschreibweise
   `transition: 0.2s`. Das ist `transition: all 0.2s` — es animiert also
   NICHT nur die Deckkraft, sondern JEDE animierbare Eigenschaft. Beim
   Aufklappen wechselt dasselbe Element gleichzeitig von `position:
   absolute` auf statisch und von `opacity: 0` auf sichtbar; die
   Sammel-Animation zieht diesen Sprung über 0,2 s auseinander. Genau das
   sieht aus, als ginge das Menü „von innen nach außen" auf.

   WARUM HIER UND NICHT IM BRICKS-FELD: Es gibt im Bricks-Panel keine
   Einstellung „Untermenü ohne Übergang" — die Regel stammt aus dem
   Theme-Kern selbst. Diese Datei ist der dokumentierte Eigentümer für
   Bewegung und wird ausdrücklich NACH dem Bricks-Custom-CSS gedruckt
   (siehe Dateikopf), gewinnt also über die Reihenfolge. Kein
   `!important` nötig: `.brxe-nav-menu .bricks-nav-menu .sub-menu` (0,3,0)
   liegt von sich aus über der Bricks-Regel `:where(.brxe-nav-menu)
   .bricks-nav-menu .sub-menu` (0,2,0), weil `:where()` keine Spezifität
   beiträgt.

   NUR BIS 820px — dieselbe Grenze, die die Seite überall für „Handy und
   Tablet" benutzt. Am PC bleibt das sanfte Einblenden; dort ist es eine
   gewohnte Rückmeldung und kein Ploppen. Soll es auch dort weg, die
   Media-Query entfernen.

   WARUM DREI SELEKTOREN UND NICHT EINER — der Fehler, der beim ersten
   Versuch passiert ist: Bricks rendert ZWEI Menü-Listen ins selbe
   Dokument. `ul.bricks-nav-menu` ist die des PCs, `ul.bricks-mobile-menu`
   im `.bricks-mobile-menu-wrapper` die des Handys. BEIDE stehen immer im
   DOM, eine davon ist nur unsichtbar. Die erste Fassung dieser Regel nannte
   nur `.bricks-nav-menu` — und traf damit ausgerechnet die Liste, die am
   Handy niemand sieht. Die Nachmessung meldete trotzdem brav `none`, weil
   sie dasselbe falsche Element abfragte.
   WER HIER ETWAS ÄNDERT, misst gegen `.bricks-mobile-menu .sub-menu` nach,
   nicht gegen `.bricks-nav-menu .sub-menu`.

   Alle drei Selektoren liegen bei (0,3,0) — gleichauf mit Bricks' eigener
   Regel `.brxe-nav-menu .bricks-mobile-menu-wrapper .sub-menu`. Den
   Gleichstand entscheidet die Reihenfolge, und diese Datei wird später
   gedruckt (siehe Dateikopf). Deshalb weiterhin kein `!important`.

   BEWUSST OHNE STELLSCHRAUBEN-VARIABLE: `transition: var(--irgendwas,
   none)` hätte hübsch ausgesehen, aber der Vertragstest dieser Datei
   prüft JEDE `transition:`-Deklaration gegen eine Erlaubnisliste und
   kann hinter eine Variable nicht schauen. Ein Wert, den der Wächter
   nicht mehr lesen kann, ist die Bequemlichkeit nicht wert. Wer das
   Einblenden zurückholen will, ändert die eine Zeile unten auf
   `transition: opacity .15s ease;` — beides steht auf der Erlaubnisliste.

   NICHT ANGETASTET: der kleine Pfeil am Menüpunkt (0,1 s Drehung, aus
   dem Bricks-Kern). Er ist die Rückmeldung „dein Tippen ist angekommen"
   und gehört zum Bedienelement, nicht zum Aufklappen. Ihn hier zu
   wiederholen hätte außerdem eine zweite eigene Easing-Kurve in diese
   Datei gebracht, was der Dateikopf ausdrücklich verbietet.
   ============================================================ */
@media (max-width: 820px) {
	.brxe-nav-menu .bricks-nav-menu .sub-menu,
	.brxe-nav-menu .bricks-mobile-menu .sub-menu,
	.brxe-nav-menu .bricks-mobile-menu-wrapper .sub-menu {
		transition: none;
	}
}
