/* ---------- Player profile ---------- */

.osw-profile { position: relative; }

/* ---------- Hero: a pure photo rotator now -- no identity content lives on
   top of it any more (see .osw-identity below). Full-bleed, same
   50%-50vw edge-to-edge trick used for the page masthead in base.css and
   the roster head banner in roster.css.

   Height is driven by aspect-ratio, not viewport height -- a vh-based
   height stays tall on a narrow phone screen (portrait viewports are
   mostly height), which crowds the page below the fold. Anchoring to
   width instead means the banner actually gets shorter as the screen
   narrows, with min/max guards so it never collapses or overgrows. */
.osw-hero {
	position: relative;
	/* Explicit width is load-bearing here, not decorative: once max-height
	   clamps the aspect-ratio box, a block element with only width:auto gets
	   its width *recomputed from the clamped height* to preserve the ratio
	   instead of staying full-bleed -- shrinks the whole banner in from the
	   right and leaves a gap of bare page background, with everything inside
	   clipped to that narrower box and so reading as "stuck to the left".
	   Pinning width to 100vw overrides that. */
	width: 100vw;
	aspect-ratio: 2.9 / 1;
	min-height: 18.5rem;
	max-height: 33.8rem;
	margin-inline: calc(50% - 50vw);
	overflow: hidden;
	background: var(--osw-ground);
}
@media (max-width: 720px) {
	.osw-hero { aspect-ratio: 3 / 3.22; min-height: 19.3rem; max-height: 25.8rem; }
}
@media (max-width: 480px) {
	.osw-hero { aspect-ratio: 4 / 4.03; min-height: 17.7rem; }
	.osw-hero__roster-label { display: none; }
	.osw-roster-switch__select { max-width: 6.5rem; }
	.osw-hero__arrow { width: 2.25rem; height: 2.25rem; }
	.osw-hero__arrow svg { width: 1.05rem; height: 1.05rem; }
}

/* No action photos: nothing to rotate, so the banner collapses to a short
   decorative strip instead of the tall aspect-ratio box above. It no longer
   has to make room for a headshot/name overlay (that's .osw-identity's job
   now, unconditionally), so this can stay short even with no photos. */
.osw-hero--flat {
	aspect-ratio: auto;
	min-height: 6.5rem;
	max-height: none;
	background: linear-gradient(155deg, var(--osw-panel), var(--osw-ground));
}

.osw-hero__track { position: relative; width: 100%; height: 100%; }
.osw-hero__track--empty { background: var(--osw-panel); }

.osw-hero__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 1.1s ease;
}
.osw-hero__slide.is-active { opacity: 1; }
.osw-hero__slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 30%;
}

/* No flat wash across the whole photo any more -- the club wants the hero
   photo itself to read bright and clear, not muted under a grey film. See
   .osw-hero__scrim below for the one place it still darkens: a small pool
   in the bottom-left corner, behind where the headshot overlaps. */
.osw-hero__overlay {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/* Two layers: a very light full-width fade at the very bottom edge, just
   enough that the photo doesn't cut hard into the solid dark identity band
   below it, plus a real dark pool anchored bottom-left where the headshot
   overlaps -- that's the one spot on the photo that still needs guaranteed
   contrast, since a light patch of ice/jersey right behind a light headshot
   border would wash the two together. Everywhere else on the photo is left
   essentially unwashed. */
.osw-hero__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(180deg, transparent 70%, rgba(8,8,10,0.55) 100%),
		radial-gradient(48% 85% at 8% 100%, rgba(8,8,10,0.82) 0%, rgba(8,8,10,0.4) 55%, transparent 80%);
	pointer-events: none;
}

/* Prev/next -- vertically centered at the rotator's own edges, a plain
   translucent circle so it reads on top of any photo without needing its
   own backdrop panel. */
.osw-hero__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 999px;
	border: none;
	background: rgba(10,10,10,0.45);
	color: #fff;
	cursor: pointer;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: background 0.15s ease;
}
.osw-hero__arrow:hover { background: rgba(10,10,10,0.7); }
.osw-hero__arrow svg { width: 1.35rem; height: 1.35rem; }
.osw-hero__arrow--prev { left: var(--osw-pad); }
.osw-hero__arrow--next { right: var(--osw-pad); }

.osw-hero__dots {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	bottom: var(--osw-pad);
	z-index: 3;
	display: flex;
	gap: 0.5rem;
}
.osw-hero__dot {
	width: 0.55rem;
	height: 0.55rem;
	border-radius: 999px;
	border: 1px solid rgba(255,255,255,0.7);
	background: transparent;
	padding: 0;
	cursor: pointer;
}
.osw-hero__dot.is-active { background: #fff; }

/* "Jump to another player" -- top-right corner of the rotator, the one
   piece of identity-adjacent UI that stays on the photo rather than moving
   down into .osw-identity, since it's really rotator/page-level navigation
   rather than a fact about this player.

   .osw-hero itself is full-bleed 100vw, so a plain right: var(--osw-pad)
   pins this to the *viewport* edge -- correct on narrow screens, but on
   anything wider than the 1200px content column it drifts well past the
   right edge of everything else on the page. The extra term mirrors how
   .osw-wrap centers itself: half the leftover space past --osw-maxw, plus
   the same gutter .osw-wrap uses, so this lines up with the actual right
   edge of the identity band beneath it. */
.osw-hero__roster-nav {
	position: absolute;
	top: var(--osw-pad);
	right: calc(max(0px, (100vw - var(--osw-maxw)) / 2) + var(--osw-pad));
	z-index: 4;
	display: flex;
	align-items: center;
	gap: 0.6rem;
}
.osw-hero__roster-label {
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	font-size: var(--osw-step-0);
	font-weight: 700;
	color: rgba(255,255,255,0.7);
}
/* Dark glass pill with a white outline, not a bright white one -- reads as
   a subtle, almost-invisible-until-you-look-for-it control sitting on the
   photo, rather than a bright UI element competing with the photo itself.
   Text/icon are --osw-ink (near-white) now that the pill itself is dark,
   the inverse of the old light-pill-dark-text version. */
.osw-roster-switch {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.5rem;
	background: rgba(10,10,10,0.55);
	border: 1px solid rgba(255,255,255,0.7);
	border-radius: 999px;
	padding: 0.4rem 2.5rem 0.4rem 0.45rem;
	box-shadow: 0 10px 24px -12px rgba(0,0,0,0.55);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}
.osw-roster-switch__icon {
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	border-radius: 999px;
	background: rgba(255,255,255,0.12);
	color: var(--osw-ink);
	flex: none;
}
.osw-roster-switch__icon svg { width: 1.25rem; height: 1.25rem; }
.osw-roster-switch__select {
	appearance: none;
	-webkit-appearance: none;
	background: transparent;
	border: none;
	max-width: 11rem;
	color: var(--osw-ink);
	font-family: var(--osw-condensed);
	font-weight: 600;
	font-size: var(--osw-step-1);
	cursor: pointer;
}
.osw-roster-switch__select option { color: var(--osw-ink); background: var(--osw-panel); }
/* A native select's own arrow can't be restyled consistently across
   browsers, so the chevron is drawn on the wrapper instead and the real one
   hidden via appearance: none above. White, to match the dark pill's own
   white outline/text instead of the old light pill's dark chevron. */
.osw-roster-switch::after {
	content: "";
	position: absolute;
	right: 1rem;
	top: 50%;
	width: 0.5rem;
	height: 0.5rem;
	border-right: 2px solid rgba(255,255,255,0.75);
	border-bottom: 2px solid rgba(255,255,255,0.75);
	transform: translateY(-65%) rotate(45deg);
	pointer-events: none;
}

/* ---------- Identity band: name, position, jersey number and the
   DOB/grad/height/hometown/shoots facts row. Its own solid dark card below
   the rotator now, rather than overlaid on the photo -- see the docblock in
   single-osw_player.php for why. ---------- */

.osw-identity {
	background: linear-gradient(155deg, var(--osw-panel), var(--osw-ground));
	border-bottom: 1px solid var(--osw-line);
}
.osw-identity__inner {
	position: relative;
	display: flex;
	align-items: flex-end;
	gap: clamp(1.5rem, 3vw, 2.5rem);
	padding-block: clamp(1.5rem, 4vw, 2.5rem);
	/* Room on the right for .osw-identity__number, which is positioned
	   absolutely against this element -- without this the number badge can
	   sit on top of the tail end of a long facts row instead of in clear
	   space beside it. */
	padding-right: clamp(6rem, 11vw, 9rem);
}
@media (max-width: 640px) {
	.osw-identity__inner { padding-right: var(--osw-pad); }
}
@media (max-width: 640px) {
	.osw-identity__inner { flex-direction: column; align-items: flex-start; gap: 1.25rem; }
}

/* Pulled up over the hero's own bottom edge with a negative margin, rather
   than the two being flush -- a trading-card cue (the photo "sits on top
   of" the action shot) matching the reference comp. .osw-hero itself clips
   its own overflow, but that only affects its own descendants; this element
   lives in the sibling .osw-identity section after it in the DOM, so it
   paints on top of the hero's box in normal stacking order with no z-index
   needed. Fixed -90px overlap (club asked for 80-100px), not a responsive
   clamp -- simpler, and the request was a literal pixel amount, not a
   proportion of viewport width.

   275px fixed width per club request (was 25% of the content column) -- a
   literal pixel size rather than a proportion, so it no longer scales with
   viewport width until the mobile overrides below take over. */
.osw-identity__photo {
	position: relative;
	flex: none;
	width: 275px;
	margin-top: -90px;
}
@media (max-width: 640px) {
	.osw-identity__photo { width: 9rem; margin-top: -70px; }
}

/* The crop/zoom + no-shadow + darker-background treatment all belong on a
   wrapping frame around the headshot, not on the headshot element itself --
   .osw-identity__committed (the committed-school logo) is a sibling that
   deliberately overflows past the headshot's own edge by design, so the
   overflow:hidden needed to crop the zoomed photo can't live on
   .osw-identity__photo (their shared parent) without clipping that too. */
.osw-identity__frame {
	width: 100%;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: 6px;
	/* "Sharp outline": a crisp, clearly-visible light border rather than the
	   old --osw-line hairline, which is dark grey and nearly invisible
	   against this section's own near-black background. */
	border: 2px solid rgba(255,255,255,0.85);
	/* Darker than the page's own ground -- shows at the edges if a photo's
	   own crop doesn't perfectly fill the square, without reading as an
	   obviously different panel colour. */
	background: #0a0a0a;
}
.osw-identity__headshot {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
/* Zoomed 12.5% (club asked for 10-15%) so the photo crops in tighter and
   fills the square with more of the player rather than headroom/background
   -- .osw-identity__frame's overflow:hidden crops the excess. Only the real
   <img>, not the initials placeholder below, which has no photo to zoom
   into. */
img.osw-identity__headshot {
	transform: scale(1.125);
	transform-origin: center;
}
.osw-identity__headshot--empty {
	display: grid;
	place-items: center;
	font-family: var(--osw-brand);
	font-size: 2.5rem;
	color: var(--osw-ink-mute);
}

/* Large jersey-number badge, right-aligned to the content column -- the
   corner badge that used to sit pinned to the headshot itself was removed
   per club request (the headshot's own frame now has no room reserved for
   it anyway, since the frame clips to its own edges). This is the only
   place the jersey number appears in the identity band now, besides the
   roster switcher's own label. Positioned against .osw-identity__inner
   (position:relative, with padding-right reserved for exactly this),
   vertically centred on the row so it reads as a fixed anchor beside the
   name/facts rather than tracking either one. */
.osw-identity__number {
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	z-index: 1;
	width: clamp(5.5rem, 8vw, 7.5rem);
	height: clamp(5.5rem, 8vw, 7.5rem);
	display: grid;
	place-items: center;
	border-radius: 999px;
	border: 4px solid var(--osw-red);
	background: var(--osw-ground);
	color: var(--osw-ink);
	font-family: var(--osw-condensed);
	font-weight: 700;
	font-size: clamp(2.25rem, 4vw, 3.25rem);
	box-shadow: var(--osw-shadow);
}
/* Hidden at the same breakpoint .osw-identity__inner stacks to a column and
   drops its reserved padding-right (see above) -- keeping both changes on
   one breakpoint avoids a middle range where the padding is reserved but
   the badge it was reserved for isn't there. */
@media (max-width: 640px) {
	.osw-identity__number { display: none; }
}

.osw-identity__committed {
	position: absolute;
	right: -0.5rem;
	top: -0.5rem;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 999px;
	background: #fff;
	border: 2px solid var(--osw-ground);
	display: grid;
	place-items: center;
	overflow: hidden;
	box-shadow: 0 4px 10px rgba(0,0,0,0.4);
}
.osw-identity__committed img { width: 100%; height: 100%; object-fit: contain; padding: 0.2rem; }

.osw-identity__text { position: relative; min-width: 0; flex: 1 1 auto; }

.osw-identity__name {
	position: relative;
	z-index: 1;
	margin: 0;
	line-height: 0.95;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
}
.osw-identity__first {
	display: block;
	font-weight: 500;
	font-size: clamp(1.5rem, 3vw, 2rem);
	/* White, like the last name -- was --osw-ink-mute (a deliberate muted
	   hierarchy between first/last), dropped per club request. */
	color: var(--osw-ink);
}
.osw-identity__last {
	display: block;
	/* 700, not 800 -- Oswald's @font-face stack (fonts.css) only ships
	   500/600/700 weight files. 800 has no matching face, so the browser was
	   synthesizing a fake bold on top of the real 700 file, which renders
	   visibly chunkier/rounder than the real weight -- almost like a
	   different typeface next to a reference rendered with an actual bold. */
	font-weight: 700;
	font-size: clamp(2.75rem, 7.5vw, 4.75rem);
	letter-spacing: -0.01em;
	color: var(--osw-ink);
}

.osw-identity__position {
	position: relative;
	z-index: 1;
	margin: 0.3rem 0 0;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.6rem;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: var(--osw-step-1);
	font-weight: 700;
	color: var(--osw-red);
}
.osw-identity__cap {
	font-size: var(--osw-step-min);
	font-weight: 700;
	color: var(--osw-ink);
	background: color-mix(in srgb, var(--osw-ink) 10%, transparent);
	border: 1px solid var(--osw-line);
	border-radius: 999px;
	padding: 0.2rem 0.7rem;
}

.osw-identity__facts {
	position: relative;
	z-index: 1;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.25rem;
	list-style: none;
	margin: 1rem 0 0;
	padding: 0;
}
/* A vertical divider between items, matching the reference comp's "|"
   separators -- skipped on whichever item lands first on its own line, so a
   wrap never leaves a divider stranded at the start of a row. */
.osw-identity__facts li:not(:first-child)::before {
	content: "|";
	margin-right: 1.25rem;
	/* ink-mute, not the hairline colour -- --osw-line (#2c2c2e) is nearly
	   invisible against this section's own near-black background; the
	   reference comp's dividers read clearly, so this needs real contrast. */
	color: var(--osw-ink-mute);
	font-weight: 400;
}
.osw-identity__facts li {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-family: var(--osw-condensed);
	font-size: var(--osw-step-0);
	font-weight: 600;
	color: var(--osw-ink);
}
.osw-identity__facts-icon {
	display: grid;
	place-items: center;
	color: var(--osw-red);
	flex: none;
}
.osw-identity__facts-icon svg { width: 1.1rem; height: 1.1rem; }
.osw-identity__facts-label {
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--osw-ink-mute);
	font-weight: 700;
}

@media (max-width: 480px) {
	.osw-identity__photo { width: 7.5rem; margin-top: -3.5rem; }
	.osw-identity__number { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.osw-hero__slide { transition: none; }
}

/* ---------- Body ---------- */

.osw-profile__body { padding-top: clamp(1.5rem, 4vw, 2.5rem); }

.osw-profile__recruiting {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	background: var(--osw-panel);
	border: 1px solid var(--osw-line);
	border-radius: 8px;
	padding: 1.1rem 1.4rem;
	margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}
.osw-profile__committed { display: flex; align-items: center; gap: 0.85rem; }
.osw-profile__committed img { width: 3rem; height: 3rem; object-fit: contain; }
.osw-profile__committed-label {
	display: block;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var(--osw-step-min);
	color: var(--osw-ink-mute);
}
.osw-profile__committed strong { font-family: var(--osw-condensed); font-size: var(--osw-step-2); }

.osw-profile__links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
.osw-profile__links a {
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: var(--osw-step-0);
	font-weight: 600;
	color: var(--osw-red);
	text-decoration: none;
}
.osw-profile__links a:hover { text-decoration: underline; }

/* Bottom clearance for whichever section actually ends the page -- the bio
   grid when there's no stats/gallery panel to follow it, or the panels grid
   itself (see .osw-profile__panels) when there is. */
.osw-profile__body > .osw-bio:last-child { padding-bottom: clamp(3rem, 6vw, 5rem); }

.osw-profile__section { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.osw-profile__section h2 {
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var(--osw-step-2);
	color: var(--osw-red);
	margin: 0 0 0.6rem;
}

/* ---------- Bio card grid: "Get to know {name}" ---------- */

.osw-bio h2 { margin-bottom: 1rem; }

.osw-bio-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1rem;
}
@media (min-width: 560px) {
	.osw-bio-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
	.osw-bio-grid { grid-template-columns: repeat(3, 1fr); }
}

.osw-bio-card {
	background: var(--osw-panel);
	border: 1px solid var(--osw-line);
	border-radius: 10px;
	padding: 1.1rem 1.25rem 1.3rem;
	transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
@media (hover: hover) {
	.osw-bio-card:hover {
		transform: translateY(-3px);
		border-color: var(--osw-red);
		box-shadow: 0 16px 30px -20px rgba(0,0,0,0.55);
	}
}

/* Icon + label sit inline on one row now, rather than the icon stacked in
   its own tinted circle above the label -- a plain red glyph beside the
   uppercase heading, same weight as a document's own section headers. */
.osw-bio-card__head {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	margin: 0 0 0.6rem;
}
.osw-bio-card__icon {
	display: grid;
	place-items: center;
	color: var(--osw-red);
	flex: none;
}
.osw-bio-card__icon svg { width: 1.35rem; height: 1.35rem; }

/* White, not red -- the icon beside it already carries the red accent, per
   the reference comp's card headings. */
.osw-bio-card__label {
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var(--osw-step-1);
	font-weight: 700;
	color: var(--osw-ink);
}

.osw-bio-card__body {
	font-family: var(--osw-body);
	font-size: var(--osw-step-0);
	color: var(--osw-ink);
	line-height: 1.55;
}
.osw-bio-card__body p { margin: 0; }
.osw-bio-card__body ul { margin: 0; padding-left: 1.15rem; }
.osw-bio-card__body li { margin-bottom: 0.2rem; }
.osw-bio-card__body li:last-child { margin-bottom: 0; }

/* High school -- a lead line inside the Academics card, set apart from the
   achievements list below it rather than just another bullet. Compound
   selector (not just the class alone) to out-specificity the plain
   ".osw-bio-card__body p { margin: 0; }" reset above, same pattern used for
   the stats table label columns further down this file. */
.osw-bio-card__body p.osw-bio-card__school {
	font-weight: 700;
	color: var(--osw-ink);
	margin: 0 0 0.4rem;
}

/* The merged "Favourites" card (ice cream / colour / role model) -- a small
   uppercase muted label followed by the value on the same line, one per
   field, rather than a paragraph per card the way the three separate cards
   used to read. Skips any field that's blank on this player's profile (see
   the loop in single-osw_player.php), so this only ever renders the fields
   that actually have something in them. */
.osw-bio-card__body p.osw-bio-card__fav {
	margin: 0 0 0.5rem;
}
.osw-bio-card__body p.osw-bio-card__fav:last-child { margin-bottom: 0; }
.osw-bio-card__fav-label {
	display: block;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var(--osw-step-min);
	font-weight: 700;
	color: var(--osw-ink-mute);
}

/* The quote is the one card that gets to look different -- a highlight
   rather than just another fact next to "favourite ice cream": a tinted
   background, a bigger quote-mark, italic pulled-quote type, and (where
   there's room) double width. */
.osw-bio-card--quote {
	background: linear-gradient(155deg, color-mix(in srgb, var(--osw-red) 12%, var(--osw-panel)), var(--osw-panel));
	border-color: color-mix(in srgb, var(--osw-red) 35%, var(--osw-line));
}
@media (min-width: 560px) {
	.osw-bio-card--quote { grid-column: span 2; }
}
.osw-bio-card--quote .osw-bio-card__icon svg { width: 1.75rem; height: 1.75rem; }
.osw-bio-card--quote .osw-bio-card__body p {
	font-family: var(--osw-condensed);
	font-style: italic;
	font-weight: 500;
	font-size: var(--osw-step-2);
	line-height: 1.4;
}

/* ---------- Stats + Gallery: two boxed cards side by side on desktop,
   stacked on mobile. Either can render alone (a player with a career but no
   gallery photos, or vice versa) -- :only-child spans the full row rather
   than leaving half of it blank. ---------- */

.osw-profile__panels {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
	padding-bottom: clamp(3rem, 6vw, 5rem);
}
@media (min-width: 720px) {
	.osw-profile__panels { grid-template-columns: 1fr 1fr; align-items: start; }
}
.osw-profile__panels > .osw-profile__section:only-child { grid-column: 1 / -1; }

.osw-profile__panel {
	background: var(--osw-panel);
	border: 1px solid var(--osw-line);
	border-radius: 10px;
	padding: 1.25rem 1.4rem 1.5rem;
	/* Overrides .osw-profile__section's own margin-bottom -- spacing between
	   panels comes from the grid's own gap instead. */
	margin-bottom: 0;
}

.osw-stats__season {
	margin: -0.3rem 0 1rem;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: var(--osw-step-min);
	color: var(--osw-ink-mute);
}

.osw-stats-scroll { overflow-x: auto; }
/* Full width of the panel, columns split evenly -- table-layout:fixed with
   no widths pinned on any cell divides the row equally across however many
   columns a goalie's (4) or skater's (5) table has. */
.osw-stats-table {
	width: 100%;
	border-collapse: collapse;
	table-layout: fixed;
}
.osw-stats-table th {
	padding: 0 0.5rem 0.75rem;
	font-family: var(--osw-condensed);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: var(--osw-step-min);
	font-weight: 700;
	color: var(--osw-ink-mute);
	text-align: center;
	border-bottom: 1px solid var(--osw-line);
	white-space: nowrap;
}
.osw-stats-table td {
	padding: 0.85rem 0.5rem;
	font-family: var(--osw-condensed);
	font-size: var(--osw-step-1);
	font-weight: 600;
	text-align: center;
	border-bottom: 1px solid var(--osw-line);
	white-space: nowrap;
}
.osw-stats-table tbody tr:last-child td { border-bottom: none; }

/* Keep the outer edges flush with the panel's own padding. */
.osw-stats-table th:first-child, .osw-stats-table td:first-child { padding-left: 0; }
.osw-stats-table th:last-child, .osw-stats-table td:last-child { padding-right: 0; }

/* Year/Division: no pinned widths -- every column (these two included)
   splits the row equally under table-layout:fixed. Still genuinely
   left-aligned though. The plain .osw-stats-table__label selector alone was
   losing to the higher-specificity ".osw-stats-table th/td" center-align
   rule above (element+class beats class-alone) -- these compound
   th/td.osw-stats-table__label selectors carry enough specificity to
   actually win. */
.osw-stats-table th.osw-stats-table__label,
.osw-stats-table td.osw-stats-table__label { text-align: left; }
.osw-stats-table th.osw-stats-table__label { color: var(--osw-ink-mute); }
.osw-stats-table td.osw-stats-table__label:first-child {
	font-weight: 700;
	color: var(--osw-ink);
	padding-right: 0.75rem;
}
.osw-stats-table td.osw-stats-table__label:nth-child(2) {
	font-family: var(--osw-body);
	font-weight: 400;
	font-size: var(--osw-step-0);
	color: var(--osw-ink-mute);
	padding-right: 0.75rem;
}

.osw-stats-table__accent { color: var(--osw-red); }

/* ---------- Gallery: a player's own small photo album, separate from the
   hero rotator. A plain horizontally-scrolling, scroll-snapping strip --
   the prev/next buttons just scroll it by a viewport width (see the inline
   script in single-osw_player.php); a visitor can just as easily drag/swipe
   the strip itself on a touch device. ---------- */

.osw-gallery { position: relative; }

.osw-gallery__viewport {
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
}
.osw-gallery__viewport::-webkit-scrollbar { display: none; }

.osw-gallery__track { display: flex; gap: 0.75rem; }

.osw-gallery__item {
	flex: none;
	width: 8.5rem;
	aspect-ratio: 4 / 3;
	border-radius: 8px;
	overflow: hidden;
	scroll-snap-align: start;
	background: var(--osw-ground);
}
.osw-gallery__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

.osw-gallery__nav {
	position: absolute;
	bottom: 1.5rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 999px;
	border: 1px solid var(--osw-line);
	background: var(--osw-ground);
	color: var(--osw-ink);
	cursor: pointer;
}
.osw-gallery__nav svg { width: 1rem; height: 1rem; }
.osw-gallery__nav--next { right: 0.4rem; }
.osw-gallery__nav--prev { right: 3rem; }
