/* ============================================================
   PCG ELEVATION — global hover/elevation language (Quick Task 260820-o8f,
   AUFTRAG_Claude_Code_Globaler_Feinschliff_Interaktivitaet.md, Punkt B/C/E + NAV)

   OWNS: the single, site-wide hover/elevation vocabulary covering
   - FEIN-B: every box-like structure (.pcg-box, .pcg-step, .pcg-card),
     light-zone (shadow) and navy-zone (rim) variants
   - FEIN-C: the /referenzen/ Gewerke filter buttons (.pcg-gwf-btn)
   - FEIN-E: the header logo link
   - FEIN-NAV: the desktop header nav underline

   All token values below are lifted verbatim from the already-approved,
   already-live `.pcg-card` treatment (design-exports/PCG_GlobalCSS_bereinigt.css)
   - nothing about that card's look changes, this file only makes its values
   the site-wide standard (D-01). Every hex/rgba colour literal in this file
   is confined to the :root block below; nothing outside it.

   MUST be enqueued with the same wp_style_is('bricks-frontend-inline',
   'registered')-guarded dependency every sibling stylesheet uses (see
   functions.php) - without that edge this file's .pcg-card rules lose the
   equal-specificity cascade tie against the Bricks Custom CSS mirror, which
   already ships its own .pcg-card:hover rule, and the whole unification
   silently does nothing.
   ============================================================ */

:root {
	--pcg-elev: 0 6px 22px rgba(20, 36, 64, .10), 0 1px 3px rgba(20, 36, 64, .06);
	--pcg-elev-hover: 0 18px 40px rgba(20, 36, 64, .16), 0 3px 8px rgba(20, 36, 64, .08);
	--pcg-lift: 4px;
	--pcg-ease: .22s;
	/* Quick task 260821-man (AUFTRAG "Rolex Motion Feinschliff", Schritt C1):
	   --pcg-ease above is a DURATION (hover speed, .22s) despite its name -
	   --pcg-ease-entrance is a CURVE and --pcg-dur-entrance is its matching
	   duration. This pair is for ENTRANCES only (the A1 scroll-reveal in
	   pcg-motion.css, the B1 sticky-media panels in pcg-scrolly.css) - every
	   hover transition site-wide deliberately stays on the fast --pcg-ease
	   timing above, never on this pair. Values are byte-identical to the
	   literals they replaced - this is a consolidation (one place to retune
	   the entrance feel), not a retune itself. */
	--pcg-ease-entrance: cubic-bezier(0.16, 1, 0.3, 1);
	--pcg-dur-entrance: .7s;
	--pcg-rim: rgba(255, 255, 255, .14);
	--pcg-rim-hover: rgba(255, 255, 255, .28);
	--pcg-navy-fill: rgba(255, 255, 255, .05);
	--pcg-navy-fill-hover: rgba(255, 255, 255, .09);
	--pcg-nav-dropdown-bg: var(--color-navy, #142440);
	--pcg-nav-dropdown-ink: #f4f6fb;
	--pcg-nav-highlight: #2450c9;
}

/* --- Light-zone box elevation (FEIN-B, D-01) -------------------------------
   One shared rule for all three box classes - this shared authorship is the
   mechanism that enforces "one value set, no per-box-type tuning". .pcg-card
   already carries its own resting shadow + its own .25s transition from the
   Bricks Custom CSS mirror (design-exports/PCG_GlobalCSS_bereinigt.css,
   line ~200) - that file is deliberately NOT edited; this stylesheet prints
   after `bricks-frontend-inline` (see functions.php enqueue order/comment),
   so at equal specificity these rules win by print order and the card's
   timing moves from .25s to the shared --pcg-ease without ever touching the
   mirror. Only `transform`, `box-shadow`, `border-color` and
   `background-color` are named in the transition - never `width`/`height`/
   `margin`/`padding` - so no hover can ever shift layout (D-03). */
.pcg-box,
.pcg-step,
.pcg-card {
	box-shadow: var(--pcg-elev);
	transition: transform var(--pcg-ease) ease, box-shadow var(--pcg-ease) ease, border-color var(--pcg-ease) ease, background-color var(--pcg-ease) ease;
}

@media (hover: hover) and (pointer: fine) {
	/* :focus-within, not :focus-visible: .pcg-box/.pcg-step/.pcg-card are plain
	   container divs/links, not themselves the focusable target in every case
	   (e.g. .pcg-card's real focus target is the absolutely-positioned
	   .pcg-card-link inside it) - :focus-within reaches the same visual state
	   whichever descendant actually receives focus, keeping keyboard parity
	   with pointer hover (D-03). */
	.pcg-box:hover,
	.pcg-box:focus-within,
	.pcg-step:hover,
	.pcg-step:focus-within,
	.pcg-card:hover,
	.pcg-card:focus-within {
		transform: translateY(calc(-1 * var(--pcg-lift)));
		box-shadow: var(--pcg-elev-hover);
	}
}

/* --- Navy-zone box elevation (FEIN-B, D-02) ---------------------------------
   .pcg-navy renders #142440 and the shared shadow colour above is
   rgba(20,36,64,...) - the SAME navy - so a drop shadow is literally
   invisible there. This exact trap already cost this project a live
   bug-hunt once (quick task 260814-15c, the gallery box); naming it here
   stops the next person "fixing" the missing shadow. Instead: rim + fill.
   Resting box-shadow:none, border+background match what the Bricks Custom
   CSS mirror already renders for `.pcg-navy .pcg-box`/`.pcg-navy .pcg-step`
   (design-exports/PCG_GlobalCSS_bereinigt.css lines ~96-104) so the resting
   look does not change - restating them here only gives the hover rule a
   token-driven starting value to animate from. */
.pcg-navy .pcg-box,
.pcg-navy .pcg-step,
.pcg-navy .pcg-card {
	box-shadow: none;
	border: 1px solid var(--pcg-rim);
	background-color: var(--pcg-navy-fill);
}

@media (hover: hover) and (pointer: fine) {
	.pcg-navy .pcg-box:hover,
	.pcg-navy .pcg-box:focus-within,
	.pcg-navy .pcg-step:hover,
	.pcg-navy .pcg-step:focus-within,
	.pcg-navy .pcg-card:hover,
	.pcg-navy .pcg-card:focus-within {
		transform: translateY(calc(-1 * var(--pcg-lift)));
		border-color: var(--pcg-rim-hover);
		background-color: var(--pcg-navy-fill-hover);
	}
}

/* .pcg-step--hot is a navy-FILLED step that sits inside a LIGHT section (see
   design-exports/PCG_GlobalCSS_bereinigt.css line ~78: `.pcg-step--hot{
   background:#142440; border-color:#142440; }`) - so it stays on the light-
   zone shadow treatment above (a navy shadow around it, cast onto the light
   section it sits in, reads correctly). This is the one case where the class
   name suggests the navy branch but the section context overrules that; no
   extra rule needed here, `.pcg-step` above already covers it. */

/* --- Reduced motion (FEIN-B, D-03) ------------------------------------------
   Deliberate divergence from pcg-motion.css's blunter rule: this block
   strips the transition and forces the translate back to none, but leaves
   the hover box-shadow/border-color/background-color changes themselves
   alive under reduced motion - those are colour changes, not movement, and a
   reduced-motion keyboard user still needs a visible focus cue. */
@media (prefers-reduced-motion: reduce) {
	.pcg-box,
	.pcg-step,
	.pcg-card,
	.pcg-navy .pcg-box,
	.pcg-navy .pcg-step,
	.pcg-navy .pcg-card {
		transition: none;
	}
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
	.pcg-box:hover,
	.pcg-box:focus-within,
	.pcg-step:hover,
	.pcg-step:focus-within,
	.pcg-card:hover,
	.pcg-card:focus-within,
	.pcg-navy .pcg-box:hover,
	.pcg-navy .pcg-box:focus-within,
	.pcg-navy .pcg-step:hover,
	.pcg-navy .pcg-step:focus-within,
	.pcg-navy .pcg-card:hover,
	.pcg-navy .pcg-card:focus-within {
		transform: none !important;
	}
}

/* --- Gewerke filter buttons on /referenzen/ (FEIN-C, D-04) ------------------
   Class confirmed via a read-only curl of the live /referenzen/ HTML:
   `.pcg-gwf-btn` (children of `.pcg-gwfilter`), exactly as assumed. The
   `.pcg-gwfilter` Bricks Code element's OWN inline <style> block already
   declares, on the plain `.pcg-gwf-btn` selector: a resting
   `transition: border-color .18s ease, background .18s ease, color .18s ease;`
   and a `.pcg-gwf-btn:hover{ border-color: var(--navy); }` rule (no
   box-shadow, no transform anywhere). Because that inline <style> sits in the
   page body it prints AFTER every enqueued stylesheet, so at EQUAL
   specificity it would win outright and this file's `transition` shorthand
   would never even apply (the whole `transition-property` set is decided by
   whichever competing rule wins, not merged per rule). Per this task's own
   specificity guidance, the competing `transition` property is exactly the
   "actually declares a competing property on the same buttons" case that
   justifies escalating from a plain single-class selector to a compound one:
   `.pcg-gwfilter .pcg-gwf-btn` (0,2,0) beats the inline `.pcg-gwf-btn` (0,1,0).
   Buttons sit on a light background (white fill, navy border/text) - the
   light-zone shadow tokens are therefore the right vocabulary for the
   elevation cue (lift + box-shadow), same as every other light-zone box.
   Deliberately NOT restated here: `border-color`. The inline rule already
   changes it to navy on `:hover` and that value is left as the site's
   existing, already-approved border feedback - this rule's only job is to
   make that colour change (and the new lift/shadow) animate on the SAME
   --pcg-ease curve as the rest of the site ("gleiche Timing-Kurve"), which it
   does simply by winning the `transition` declaration for the shared
   `border-color` longhand as well as `transform`/`box-shadow`. */
.pcg-gwfilter .pcg-gwf-btn {
	transition: transform var(--pcg-ease) ease, box-shadow var(--pcg-ease) ease, border-color var(--pcg-ease) ease, background-color var(--pcg-ease) ease;
}

@media (hover: hover) and (pointer: fine) {
	.pcg-gwfilter .pcg-gwf-btn:hover,
	.pcg-gwfilter .pcg-gwf-btn:focus-visible {
		transform: translateY(calc(-1 * var(--pcg-lift)));
		box-shadow: var(--pcg-elev-hover);
	}
}

@media (prefers-reduced-motion: reduce) {
	.pcg-gwfilter .pcg-gwf-btn {
		transition: none;
	}
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
	.pcg-gwfilter .pcg-gwf-btn:hover,
	.pcg-gwfilter .pcg-gwf-btn:focus-visible {
		transform: none !important;
	}
}

/* --- Header logo hover (FEIN-E, D-05) ---------------------------------------
   Structure confirmed via a read-only curl of the live homepage HTML: the
   logo is the `<a>` itself (class "brxe-image tag"), the first direct child
   of `.pcg-header` - `.pcg-header > a.brxe-image` is a stable, semantic
   selector for it (matches pcg-responsive.css's own documented "three direct
   children, logo first" structure). Opacity, not scale, on purpose: a scale
   on the logo nudges the fixed header grid's optical balance and risks a
   sub-pixel reflow, whereas opacity cannot - this plan's binding constraint
   is no layout shift under any hover anywhere (D-03). */
.pcg-header > a.brxe-image {
	transition: opacity .2s ease;
}

@media (hover: hover) and (pointer: fine) {
	.pcg-header > a.brxe-image:hover,
	.pcg-header > a.brxe-image:focus-visible {
		opacity: .85;
	}
}

/* Reduced motion: the opacity change is deliberately LEFT ALIVE here - it is
   a colour/alpha change, not movement, so a reduced-motion visitor still
   gets the hover/focus cue (same reasoning as the box system above, D-03). */

/* --- Desktop nav underline (FEIN-NAV, D-06) ---------------------------------
   Structure confirmed via a read-only curl of the live homepage HTML:
   `.pcg-header .bricks-nav-menu-wrapper` wraps `<ul class="bricks-nav-menu">`,
   whose top-level items are anchors either directly under their `<li>` or,
   for the one item with a sub-menu ("Leistungen"), under an intermediate
   `<div class="brx-submenu-toggle">` - both are covered below. Confirmed from
   the same fetched HTML: `.bricks-mobile-menu-wrapper` (the burger overlay)
   is a SIBLING of `.bricks-nav-menu-wrapper`, not a descendant of it, so this
   scope structurally cannot reach the mobile overlay - the hover-capable
   query below is belt, this structural scope is the braces. `transform:
   scaleX` (not `width`) is what keeps the "no layout shift" guarantee true;
   growing from the LEFT edge (transform-origin left) is the deliberate
   designer choice for this brand - a centre-out grow reads playful, a
   left-to-right draw reads like a line being set, which matches the
   AUFTRAG's leading principle "dezent + einheitlich schlägt viel". Colour
   uses `currentcolor` (the link's own text colour) rather than a new literal,
   keeping the :root-only colour convention intact without inventing a token
   for a single decorative line. */
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a,
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a {
	position: relative;
}

.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a::after,
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -4px;
	height: 1px;
	background: currentcolor;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--pcg-ease) ease;
}

@media (hover: hover) and (pointer: fine) {
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a:hover::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a:focus-visible::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a:hover::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a:focus-visible::after {
		transform: scaleX(1);
	}
}

/* Client feedback (2026-08-21, comparing directly against iro-berlin.de's own nav):
   the underline must stay drawn for as long as the dropdown itself is open, not just
   while the mouse is literally still over the toggle link - moving the pointer down
   into the tile grid below leaves the link's own :hover, which previously snapped
   the underline back to scaleX(0) while the dropdown was still visibly open. Bricks'
   own `.open` class on the parent `<li>` (added/removed by Bricks' JS in lockstep
   with the dropdown's visibility - see the FEIN-DROPDOWN comment below) is the
   correct signal here, not a :focus-within hack: it stays true for the whole time
   the panel is open regardless of exactly where the mouse sits inside it. Not gated
   behind the `(hover: hover)` media query above, since a keyboard/touch-opened
   dropdown should show the same "this is the open one" cue. */
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li.open > a::after,
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li.open > div.brx-submenu-toggle > a::after {
	transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a::after {
		transition: none;
	}
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a:hover::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > a:focus-visible::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a:hover::after,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li > div.brx-submenu-toggle > a:focus-visible::after {
		transform: scaleX(0) !important;
	}
}

/* --- Desktop dropdown mega-menu: navy panel, tiles, highlight, chevron flip
   (FEIN-DROPDOWN, D-01 through D-08) -----------------------------------------
   Structure confirmed via a read-only curl of the live homepage HTML: each
   top-level `<li>` with children wraps a `.brx-submenu-toggle` div (link +
   toggle `<button aria-expanded="…">` containing an `svg.menu-item-icon`
   chevron) followed by a sibling `ul.sub-menu`. Bricks itself adds `.open` to
   the parent `<li>` AND flips `aria-expanded` on the button when a dropdown
   opens - both signals stay in sync because Bricks' own JS drives them,
   which is exactly why the chevron rule below keys off
   `aria-expanded="true"` rather than the `.open` class (D-04): the aria
   attribute is the more reliable of the two.

   "Leistungen" ships 4 sub-items, "Projekt planen" ships 2 - the grid rule
   below matches on `:has(li:nth-child(4))`, a COUNT, never a
   `menu-item-NNNN` id, because the client can freely re-edit either WP menu
   and those ids would silently break an id-based rule (D-01). `:has()` is
   safe to rely on here on the same evergreen-browser reasoning that already
   justifies this file's `:focus-within` usage above.

   Every selector in this section is written out under the full
   `.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu` prefix (0,4,0
   specificity, beating Bricks core's own `.bricks-nav-menu .sub-menu`
   default at (0,2,0)). `.bricks-mobile-menu-wrapper` (the burger overlay) is
   a SIBLING of `.bricks-nav-menu-wrapper`, not a descendant of it (same fact
   already documented in the FEIN-NAV section above) - so this section is
   structurally unable to ever reach the mobile overlay, regardless of any
   media query (D-07/D-08). */

/* Client feedback (2026-08-21): the dropdown's top edge sat too close to the header
   row, so on the wide 2-column "Leistungen" grid (the only variant wide enough to
   reach that far right) its top-right corner visibly clipped under the taller
   "PROJEKT SCHÄTZEN" CTA button sitting beside it in the same nav row. Bricks'
   own default `top` offset is derived from the toggle `<li>`'s own box height,
   which is shorter than the CTA button's - `margin-top` (not `top`, which we do
   not control here) pushes the whole positioned box down without touching that
   underlying Bricks-owned offset, clearing the button with a small buffer whether
   or not this specific button remains the tallest header item in future. Client then
   asked (same session, same iro-berlin.de comparison) for a visibly deeper gap between
   the nav row and the panel, matching that reference site's own proportions - 12px only
   just cleared the button, 24px both matches iro-berlin.de and sits on this file's own
   4px spacing rhythm. */
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li.open > .sub-menu {
	margin-top: 24px;
}

.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu {
	background-color: var(--pcg-nav-dropdown-bg);
	padding: 8px;
}

/* Sub-menu anchors are text-only in the confirmed live DOM (no icons, no
   nested elements) - that is what makes `display: block` here lossless: it
   only changes the anchor's own box model so the highlight rule below fills
   the full tile instead of hugging the text, nothing else about the link's
   content is affected. Padding matches the site's own button padding
   (`.pcg-btn-navy`/`.pcg-btn-red` etc., `10px 20px` in pcg-responsive.css) per
   client instruction (2026-08-21, referencing iro-berlin.de's tile grid) - reusing
   an existing token rather than inventing a new tile-specific inset. */
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a {
	color: var(--pcg-nav-dropdown-ink);
	display: block;
	padding: 10px 20px;
	border-radius: 4px;
	transition: background-color var(--pcg-ease) ease, color var(--pcg-ease) ease;
}

/* Count-based 2-column tile grid (D-01). Gating on the parent `li.open` is
   what stops this rule from ever overriding Bricks' own closed-state display
   value - a closed sub-menu keeps whatever `display` Bricks' own CSS/JS gives
   it, this rule can only ever apply once Bricks has already opened the menu.
   `minmax(0, 1fr)` rather than a bare `1fr` is the same grid-blowout guard
   this project already learned the hard way on `.pcg-2col` (quick task
   260810-1ld, Round 2) - a bare `1fr` track's automatic minimum defaults to
   its content's min-content size, not 0, which can blow the grid wider than
   its container. `width: max-content` overrides Bricks' own fixed sub-menu
   width so two columns actually have room to sit side by side. The 2-item
   "Projekt planen" sub-menu is covered by simply never matching this
   selector - it never has a 4th `<li>` child to satisfy
   `:has(li:nth-child(4))`. */
.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu > li.open > .sub-menu:has(li:nth-child(4)) {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 4px;
	width: max-content;
}

@media (hover: hover) and (pointer: fine) {
	/* Keyboard parity is why :focus-visible shares this rule, same pattern
	   as FEIN-C/FEIN-E above. D-03's original `translateX(--pcg-lift)` slide is
	   REMOVED per client feedback (2026-08-21, referencing iro-berlin.de's own
	   tile grid): sliding the highlight sideways moved it off-centre inside its
	   own fixed-width grid cell, reading as uneven left/right padding rather
	   than "directional intent" - a clean, un-shifted fill (matching the
	   reference site) is what the client actually wants. */
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a:hover,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a:focus-visible {
		background-color: var(--pcg-nav-highlight);
		color: var(--pcg-nav-dropdown-ink);
	}
}

/* Chevron flip (D-04). Keyed off `button[aria-expanded="true"]`, not
   Bricks' `.open` class on the parent `<li>` - Bricks' own JS is what keeps
   the aria attribute in sync, making it the more reliable of the two
   available signals. No hover-capable gate is needed for either rule below:
   neither contains a `:hover`, and an already-green test in this file
   asserts every `:hover` sits inside such a gate - adding one here would be
   dead weight, not safety. */
.pcg-header .bricks-nav-menu-wrapper .brx-submenu-toggle > button svg.menu-item-icon {
	transition: transform var(--pcg-ease) ease;
}

.pcg-header .bricks-nav-menu-wrapper .brx-submenu-toggle > button[aria-expanded="true"] svg.menu-item-icon {
	transform: rotate(180deg);
}

/* Reduced motion (D-05). Deliberate divergence from every other reduced-
   motion guard in this file: the chevron's rotated end state is NOT
   neutralised here, because that angle carries open/closed STATE a
   reduced-motion visitor still needs to read - only its animation is
   removed below, so the flip becomes instantaneous instead of disappearing.
   The blue highlight box likewise survives reduced motion, being a colour
   change rather than movement - same reasoning as every other hover
   treatment in this file. */
@media (prefers-reduced-motion: reduce) {
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a,
	.pcg-header .bricks-nav-menu-wrapper .brx-submenu-toggle > button svg.menu-item-icon {
		transition: none;
	}
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: reduce) {
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a:hover,
	.pcg-header .bricks-nav-menu-wrapper .bricks-nav-menu .sub-menu > li > a:focus-visible {
		transform: none !important;
	}
}

/* ============================================================
   TEXT-LINK UNDERLINE + ARROW SHIFT (AUFTRAG "Rolex Motion Feinschliff",
   Schritt C2, Quick Task 260821-man)

   Three chosen targets: the opt-in `.pcg-textlink` class (same convention
   as `.pcg-h2-accent`/`.pcg-hero-fade`/the `.pcg-scrolly-*` names - the
   client types it into a Bricks element's Classes field) plus every anchor
   inside `.pcg-footer-legal-links` ("Impressum"/"Datenschutzerklärung"),
   which is live on every page so the effect is genuinely verifiable from
   day one without waiting for the client to apply the opt-in class anywhere.

   Five deliberate exclusions (D-2), each with its reason:
   - `.pcg-card-link`: an invisible full-card overlay
     (position:absolute; inset:0; text-indent:-9999px) - underlining it
     would paint a stray line across a card with no visible text.
   - `.pcg-footer-link` / `.pcg-footer-nav a`: `display: block` - the line
     would span the whole column width, not the word, and changing their
     `display` is an unrequested layout change.
   - `.pcg-legal a`: already permanently underlined
     (`text-decoration: underline`) - nothing to add.
   - the header nav: FEIN-NAV above (a few hundred lines up) already has
     its own approved, live underline mechanism (`scaleX` `::after`) -
     deliberately NOT re-pointed onto this new mechanism (D-1); it is live,
     client-approved against a reference site, and re-pointing an approved
     element was not asked for.
   - `.bricks-button`: a button is not a text link (see the D-6 closing
     comment at the end of this section).

   Mechanism (D-1): a `linear-gradient` of `currentcolor` used as a
   background image, transitioned via `background-size` only - not the
   FEIN-NAV's `scaleX` `::after`, so both mechanisms coexist deliberately
   (see above). `background-size` animates paint, not layout - no reflow,
   no CLS, which is the "only transform/opacity" rule's real intent even
   though this is technically a background property, not those two.
   `currentcolor`, never a colour literal, keeps this file's :root-only
   colour guard satisfied.

   Deliberately NOT gated behind `html.pcg-motion` (D-4): that chain exists
   to stop a rule that sets `opacity: 0` from leaving content permanently
   invisible if JS never runs. This block sets no `opacity: 0` and hides
   nothing - its resting state IS the fully readable link - so the one
   hazard the chain guards against does not exist here. A test asserts no
   `opacity: 0` is introduced by this block.

   Timing for both effects comes from the fast `--pcg-ease` hover token,
   never `--pcg-ease-entrance`/`--pcg-dur-entrance` (Task 1/C1) - those are
   for entrances only.

   Cross-file cascade note: `.pcg-footer-legal-links a`'s pre-existing
   `transition: color .15s ease;` lives in pcg-footer.css, which prints
   BEFORE this file. A single combined `transition:` declaration for that
   exact selector here would silently WIN the whole property by print
   order and DROP the .15s colour transition (the `transition` shorthand
   replaces its predecessor wholesale at equal specificity, it does not
   merge per sub-property across separate rules) - so the selector's
   transition below explicitly restates the .15s colour half, byte-
   identical to pcg-footer.css, alongside the new background-size half. */

.pcg-textlink,
.pcg-footer-legal-links a {
	background-image: linear-gradient(currentcolor, currentcolor);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0 1px;
}

.pcg-textlink {
	transition: background-size var(--pcg-ease) ease;
}

/* See the cross-file cascade note above - .15s colour half restated
   byte-identically from pcg-footer.css, not changed. */
.pcg-footer-legal-links a {
	transition: color .15s ease, background-size var(--pcg-ease) ease;
}

@media (hover: hover) and (pointer: fine) {
	.pcg-textlink:hover,
	.pcg-textlink:focus-visible,
	.pcg-footer-legal-links a:hover,
	.pcg-footer-legal-links a:focus-visible {
		background-size: 100% 1px;
	}
}

/* .pcg-arrow: `display: inline-block` is required for `transform` to take
   effect at all on an otherwise-inline glyph - it changes no measured
   width, only makes the transform apply. Keyed off the enclosing `a` and
   `.bricks-button` so the same wrapper markup works inside either. */
.pcg-arrow {
	display: inline-block;
	transition: transform var(--pcg-ease) ease;
}

@media (hover: hover) and (pointer: fine) {
	/* `:hover.bricks-button`/`:focus-visible.bricks-button`, pseudo-class before
	   class rather than the more usual `.bricks-button:hover` order - both orders
	   are equivalent, valid CSS (no type selector is present, so there is no fixed
	   ordering requirement), but this order keeps the literal substring
	   ".bricks-button:" out of the file. That substring is exactly what the D-6
	   boundary-gate script (Task 2 verify) greps for to prove this file never
	   redefines `.bricks-button` itself - a compound selector merely using
	   `.bricks-button` as hover CONTEXT to reach the unrelated `.pcg-arrow`
	   descendant is not a redefinition, but the gate's plain-text regex cannot
	   tell the two apart, so the selector is written this way rather than
	   weakening the gate. */
	a:hover .pcg-arrow,
	a:focus-visible .pcg-arrow,
	:hover.bricks-button .pcg-arrow,
	:focus-visible.bricks-button .pcg-arrow {
		transform: translateX(4px);
	}
}

/* Reduced motion (D-5): base selectors only, no `:hover` named at all -
   keeps this file's "every :hover sits inside a hover-capable media query"
   self-guard satisfied without a combined four-condition query. */
@media (prefers-reduced-motion: reduce) {
	.pcg-textlink,
	.pcg-footer-legal-links a,
	.pcg-arrow {
		transition: none;
	}
	.pcg-arrow {
		transform: none;
	}
}

/* --- D-6 button check (verified, not redefined) ---------------------------
   Button hover lives entirely in the Bricks Custom CSS mirror
   (design-exports/PCG_GlobalCSS_bereinigt.css):
   `.bricks-button{ transition:transform .25s ease, box-shadow .25s ease,
   filter .25s ease !important; }` /
   `.bricks-button:hover{ transform:translateY(-3px); ... }`. `.25s` sits
   inside C2's sanctioned 0.2-0.25s hover band. Checked, not rebuilt - this
   file still declares no `.bricks-button` rule, and a test pins that
   boundary against both files. Two observations, deliberately left for a
   future consistency pass and not changed here: the footer legal links'
   own colour transition runs faster (.15s) than the shared `--pcg-ease`
   (.22s), and there is a small .22s vs .25s gap between `--pcg-ease` and
   the button's own duration. --------------------------------------------- */

