/**
 * Goldbach — filter chip loading feedback.
 *
 * Paired with assets/facetwp-loading.js.
 *
 * HARD CONSTRAINT: the chip's box must not change size between idle and
 * loading. Only `position` (no layout effect), `color`, and an out-of-flow
 * ::after are touched — never padding, border, font, width or height.
 */

/*
 * FacetWP's own front.css dims the whole facet row while refreshing:
 *
 *   .facetwp-facet.is-loading { opacity: 0.6; pointer-events: none; }
 *
 * A child can never exceed its parent's opacity, so that would wash the
 * spinner out to 60%. Keep the row solid. The `pointer-events: none` half of
 * FacetWP's rule is deliberately left in place — it is what stops a second
 * click queueing up mid-refresh.
 *
 * `.facetwp-type-radio` is on the same element and raises specificity to
 * (0,3,0), which beats FacetWP's (0,2,0) regardless of source order — FacetWP
 * prints front.css on wp_footer:25, i.e. after this file.
 */
.facetwp-facet.is-loading.facetwp-type-radio {
	opacity: 1;
}

.facetwp-facet .facetwp-radio[data-gc-loading] {
	/*
	 * Zero layout impact: `position: relative` never resizes a box, and
	 * `color` hides the label while it keeps occupying exactly the same space.
	 * `!important` is needed only to beat the page's own chip colour rule.
	 */
	position: relative;
	color: transparent !important;
	--gc-fwp-spinner: var( --bde-palette-color-5-f010046c-bc41-4ae8-b876-0d221424b326, #3a3c3c );
}

/*
 * Active chip: dark ([v2] darkmode #152F2D) background, so the spinner flips
 * to white. FacetWP's click handler toggles `.checked` synchronously before
 * the refresh starts, so the right variant is already applied by the time the
 * spinner appears — including the "click the active chip to clear it" case,
 * which un-checks and therefore correctly uses the dark spinner.
 */
.facetwp-facet .facetwp-radio.checked[data-gc-loading] {
	--gc-fwp-spinner: var( --bde-background-color, #fff );
}

.facetwp-facet .facetwp-radio[data-gc-loading]::after {
	content: '';
	position: absolute; /* out of flow — cannot affect the chip's box */
	top: 50%;
	left: 50%;
	width: 18px;
	height: 18px;
	/* Negative margins instead of translate(-50%,-50%), so `transform` stays
	   free for the rotation. */
	margin: -9px 0 0 -9px;
	box-sizing: border-box;
	border: 2px solid var( --gc-fwp-spinner );
	border-top-color: transparent;
	border-radius: 50%;
	animation: gc-fwp-spin 700ms linear infinite;
}

/* Namespaced — FacetWP's front.css already defines `@keyframes spin`. */
@keyframes gc-fwp-spin {
	to {
		transform: rotate( 360deg );
	}
}

@keyframes gc-fwp-pulse {
	50% {
		opacity: 0.25;
	}
}

/*
 * Content Reveal "See more" trigger.
 *
 * Breakdance's atom base only sets `cursor: pointer` for three variants:
 *
 *   .breakdance .button-atom--primary,
 *   .breakdance .button-atom--secondary,
 *   .breakdance .button-atom--custom { … cursor: pointer; … }
 *
 * This trigger uses `design.overlay.button.style = 'text'`, and
 * `.button-atom--text` only gets a colour — so it falls back to the browser's
 * <button> default, `cursor: default`. No prop can express this, and switching
 * to `style: 'custom'` would drag in padding, border-radius and kill the
 * underline. One declaration instead. (0,3,0), matching Breakdance's own
 * `.breakdance .bde-content-reveal .bde-content-reveal__button` layout rule.
 *
 * The `:disabled` state is deliberately not covered — this element never
 * renders one, and Breakdance's `cursor: not-allowed` should keep winning
 * if it ever did.
 */
.breakdance .bde-content-reveal .bde-content-reveal__button {
	cursor: pointer;
}

/*
 * Stop an expanding bio from inflating its neighbours.
 *
 * `.bde-loop` is `display: grid` (posts.css) and nothing anywhere declares
 * `align-items` on it — not posts.css, not page 2985, not block 2988 — so it
 * sits at the CSS Grid initial value and stretches every card in a row to the
 * tallest. At rest that is exactly right: it is what makes a row's cards equal
 * height and lets each card's `margin-top: auto` block sit on the bottom edge.
 * While a bio expands it is exactly wrong: the row grows and the neighbours
 * grow with it, stranding their bottom block a few hundred px below the name.
 *
 * This class is added ONCE, at rest, by assets/card-heights.js — in the same
 * task in which that script pins every card's measured stretch height as a
 * `min-height`. Because the pinned value *is* the height stretch was producing,
 * turning stretch off changes nothing on screen, and equal heights and the
 * bottom-aligned block both survive. Nothing is toggled afterwards.
 *
 * It replaces an earlier
 *
 *   .bde-loop-grid:has( .bde-content-reveal__container:is( .is-visible, … ) )
 *
 * which flipped `align-items` for the duration of the reveal. `align-items` is
 * not animatable and applies to the entire grid in a single frame, so every
 * card lost its stretch instantly: at 1440px, opening card 0 dropped card 2 by
 * 50.2px and card 26 — eight rows away — by 159.2px, in one frame, and snapped
 * them back on close. See the JS file for the full reasoning.
 *
 * Specificity (0,2,0), above `.bde-loop` (0,1,0); nothing else declares
 * `align-items`, so source order is irrelevant. No `:has()`, so this now also
 * works in Firefox < 121.
 *
 * Lives here rather than in the page or block because `.bde-loop-grid` is
 * outside block 2988's `%%SELECTOR%%` scope; this stylesheet's enqueue already
 * confines it to page 2985.
 */
.bde-loop-grid.gc-cards-locked {
	align-items: start;
}

@media ( prefers-reduced-motion: reduce ) {
	.facetwp-facet .facetwp-radio[data-gc-loading]::after {
		/* Closed ring, no rotation — a gentle opacity pulse instead. */
		border-top-color: var( --gc-fwp-spinner );
		animation: gc-fwp-pulse 1.2s ease-in-out infinite;
	}
}
