

/* ---- the monogram fallback ----------------------------------------------
   Almost every player on the live site has no headshot attachment, so
   stepfox_gi_pl_face() returns a .sfgi-face--mono span. gridiron.css sizes the
   CREST monograms but never the FACE ones, which left a 16px numeral adrift in
   a 168px circle. When a real photo does arrive it is an <img>, and the base
   guard's `[class^="sfgi-"] img { height: auto }` outranks .sfgi-phero__photo's
   own height — hence the element-qualified override, which must FILL the
   circle rather than letterbox inside it. */
.sfgi-phero__photo.sfgi-face--mono {
	font-family: var(--sfgi-f-display);
	font-size: 62px;
	line-height: 1;
	letter-spacing: 0.02em;
	color: color-mix(in srgb, var(--sfgi-ink) 72%, transparent);
	background:
		radial-gradient(circle at 50% 28%, color-mix(in srgb, var(--sfgi-team, var(--sfgi-accent)) 40%, transparent), transparent 70%),
		var(--sfgi-panel-2);
}

/* ==========================================================================
   6. PLAYER GRID — .sfgi-grid--players
   Live DOM:
     <div class="sfgi-grid sfgi-grid--players" data-cols="4" data-noun="players">
       <div class="sfgi-filters"> … </div>
       <div class="sfgi-cards sfgi-cards--players" data-grid data-visible-max="0">
         <a class="sfgi-card sfgi-pcard sfgi-tilt sfgi-reveal sfgi-holo" …>
   829 players ship on /players/, so the card wrapper stays on
   content-visibility. gridiron.css already turns that on for
   `.sfgi-grid [data-grid] > .sfgi-card` with a 260px placeholder; a player
   card is taller than that, and an under-guess makes the scrollbar jump.
   ========================================================================== */

.sfgi-grid--players {
	--sfgi-pcols: 2;
	scroll-margin-top: 24px;
}
.sfgi-grid--players [data-grid] {
	grid-template-columns: repeat(var(--sfgi-pcols), minmax(0, 1fr));
	gap: var(--sfgi-gap-sm);
	min-width: 0;
}
.sfgi-grid--players [data-grid] > .sfgi-card {
	contain-intrinsic-size: auto 322px;
}
/* A grid pinned to one column by the block author stays pinned at every
   width; the rest step up with the viewport, capped by data-cols. */
.sfgi-grid--players[data-cols="1"] { --sfgi-pcols: 1; }

@media (min-width: 600px) {
	.sfgi-grid--players { --sfgi-pcols: 3; }
	.sfgi-grid--players [data-grid] { gap: var(--sfgi-gap); }
	.sfgi-grid--players[data-cols="1"] { --sfgi-pcols: 1; }
	.sfgi-grid--players[data-cols="2"] { --sfgi-pcols: 2; }
}
@media (min-width: 769px) {
	.sfgi-grid--players { --sfgi-pcols: 4; }
	.sfgi-grid--players[data-cols="1"] { --sfgi-pcols: 1; }
	.sfgi-grid--players[data-cols="2"] { --sfgi-pcols: 2; }
	.sfgi-grid--players[data-cols="3"] { --sfgi-pcols: 3; }
}
@media (min-width: 1025px) {
	.sfgi-grid--players[data-cols="5"] { --sfgi-pcols: 5; }
	.sfgi-grid--players[data-cols="6"] { --sfgi-pcols: 6; }
}
.sfgi-pcard__chips .sfgi-chip {
	max-width: 100%;
	padding: 3px 9px;
	font-size: 10px;
	letter-spacing: 0.16em;
}

/* The card's own monogram fallback, and the object-fit that makes a real
   headshot FILL the round tile instead of letterboxing inside it (the base
   guard's `img { height: auto }` outranks .sfgi-pcard__face on its own). */
.sfgi-pcard__face.sfgi-face--mono {
	font-family: var(--sfgi-f-display);
	font-size: calc(var(--sfgi-pface) * 0.36);
	line-height: 1;
	color: color-mix(in srgb, var(--sfgi-ink) 66%, transparent);
	background:
		radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--sfgi-team, var(--sfgi-accent)) 38%, transparent), transparent 72%),
		var(--sfgi-panel-2);
}
.sfgi-leadcard__face .sfgi-face--mono {
	font-family: var(--sfgi-f-display);
	font-size: 28px;
	line-height: 1;
	color: color-mix(in srgb, var(--sfgi-ink) 78%, transparent);
}
/* Fill the square crop; do not letterbox. Element-qualified so it outranks the
   `[class^="sfgi-"] img { height: auto }

/* ==========================================================================
   10. MOTION — cooperating with assets/fx.js
   fx.js writes, on a `.sfgi-tilt` card: --rx --ry (deg, capped at 7),
   --mx --my (0-100%) and --lift (px); on a `.sfgi-layer[data-depth]` inside
   it: --px --py --z; and on a `.sfgi-holo` element: --holo (0-200%). It adds
   `sfgi-fx` to <body> on boot and `sfgi-fx-pointer` only when the pointer
   effects are actually allowed to run, so all of this is dead weight for a
   no-JS visitor, a touch device or anyone who asked for reduced motion.

   The tilt is deliberately scoped to `sfgi-fx-pointer`: /players/ paints 829
   cards, and a non-none transform on every one of them is a cost worth paying
   only where the effect is real.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

	/* The parallax layers. .sfgi-pcard and .sfgi-leadcard both clip their
	   overflow, which flattens preserve-3d, so --z is left alone and the shift
	   is done in the plane — which is the half of the effect that survives. */
	body.sfgi-fx-pointer .sfgi-pcard .sfgi-layer,
	body.sfgi-fx-pointer .sfgi-leadcard .sfgi-layer,
	body.sfgi-fx-pointer .sfgi-phero .sfgi-layer {
		transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
		transition: transform var(--sfgi-t) var(--sfgi-ease);
	}

	/* The scroll reveal. Gated on `sfgi-fx-reveal`, which fx.js adds ONLY when
	   an IntersectionObserver is present and motion is allowed — gating on
	   `sfgi-fx` alone would leave an older browser staring at a blank page.
	   Every selector also demands `.sfgi-reveal` itself: fx.js only ever adds
	   `.is-in` to elements carrying that class, so hiding anything else would
	   hide it for good. `.sfgi-leaders__item` is NOT one of them — the anchor
	   inside it is. */
	body.sfgi-fx-reveal .sfgi-pcard.sfgi-reveal,
	body.sfgi-fx-reveal .sfgi-lead.sfgi-reveal,
	body.sfgi-fx-reveal .sfgi-prank__row.sfgi-reveal {
		opacity: 0;
		transform: translate3d(0, 14px, 0);
		transition:
			opacity .5s var(--sfgi-ease) var(--fxd, 0ms),
			transform .5s var(--sfgi-ease) var(--fxd, 0ms);
	}
	body.sfgi-fx-reveal .sfgi-pcard.sfgi-reveal.is-in,
	body.sfgi-fx-reveal .sfgi-lead.sfgi-reveal.is-in,
	body.sfgi-fx-reveal .sfgi-prank__row.sfgi-reveal.is-in {
		opacity: 1;
		transform: none;
	}
	/* Once revealed, a card must go back to answering the tilt. */
	body.sfgi-fx-pointer.sfgi-fx-reveal .sfgi-pcard.sfgi-reveal.is-in {
		transform: perspective(var(--sfgi-persp)) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translate3d(0, var(--lift, 0px), 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.sfgi-pcard,
	.sfgi-leadcard,
	.sfgi-phero,
	.sfgi-lead,
	.sfgi-leaders__item,
	.sfgi-prank__row,
	.sfgi-pcard .sfgi-layer,
	.sfgi-leadcard .sfgi-layer,
	.sfgi-phero .sfgi-layer {
		opacity: 1;
		transform: none;
		transition: none;
		animation: none;
	}
}
