/* ---------------------------------------------------------------------------
   KJPI Analytics -- application styles.

   Depends on tokens.css. No color, font or spacing literal belongs in this
   file; everything resolves through a custom property.
   --------------------------------------------------------------------------- */

/* === reset =============================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd,
ul,
ol {
	margin: 0;
}

ul[class],
ol[class] {
	padding: 0;
	list-style: none;
}

img,
svg {
	max-width: 100%;
	display: block;
}

/* A class that sets `display` outranks the user-agent [hidden] rule, so
   `element.hidden = true` silently does nothing on anything styled. */
[hidden] {
	display: none !important;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

table {
	border-collapse: collapse;
	border-spacing: 0;
}

body {
	font-family: var(--font);
	font-size: var(--fs-base);
	line-height: var(--lh-base);
	color: var(--text);
	background: var(--bg);
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	-webkit-font-smoothing: antialiased;
}

a {
	color: var(--accent);
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
	border-radius: var(--radius-sm);
}

::selection {
	background: var(--accent-soft);
	color: var(--text);
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* Numerals in data contexts must line up column to column. */
.num,
td.num,
th.num,
.stat-table td,
.data-table td.num {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	top: 0;
	left: var(--sp-2);
	z-index: 100;
	transform: translateY(-150%);
	background: var(--accent);
	color: var(--accent-fg);
	padding: var(--sp-2) var(--sp-4);
	border-radius: 0 0 var(--radius) var(--radius);
	transition: transform var(--dur) var(--ease);
}

.skip-link:focus {
	transform: translateY(0);
	text-decoration: none;
}

/* === app shell =========================================================== */

.page {
	flex: 1;
	width: 100%;
	max-width: var(--page-max);
	margin: 0 auto;
	padding: var(--sp-5) var(--sp-5) var(--sp-7);
}

.page--narrow {
	max-width: 760px;
}

.page--flush {
	padding-left: 0;
	padding-right: 0;
}

@media (max-width: 767px) {
	.page {
		padding: var(--sp-4) var(--sp-4) var(--sp-6);
	}
}

/* === navigation ========================================================== */

.nav {
	position: sticky;
	top: 0;
	z-index: 40;
	background: var(--surface);
	border-bottom: 1px solid var(--border);
}

.nav__inner {
	max-width: var(--page-max);
	margin: 0 auto;
	min-height: var(--nav-height);
	padding: 0 var(--sp-5);
	display: flex;
	align-items: center;
	gap: var(--sp-5);
}

@media (max-width: 767px) {
	.nav__inner {
		padding: 0 var(--sp-4);
		gap: var(--sp-3);
	}
}

.nav__brand {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	font-size: var(--fs-md);
	font-weight: var(--fw-semibold);
	letter-spacing: -0.01em;
	color: var(--text);
	white-space: nowrap;
}

.nav__brand:hover {
	text-decoration: none;
	color: var(--text);
}

.nav__brand svg {
	width: 22px;
	height: 22px;
	color: var(--accent);
}

.nav__brand b {
	font-weight: var(--fw-bold);
}

.nav__links {
	display: flex;
	align-items: center;
	gap: var(--sp-1);
	margin-right: auto;
}

.nav__link {
	padding: var(--sp-2) var(--sp-3);
	border-radius: var(--radius);
	color: var(--text-muted);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
}

.nav__link:hover {
	background: var(--surface-2);
	color: var(--text);
	text-decoration: none;
}

.nav__link[aria-current="page"] {
	color: var(--text);
	background: var(--surface-2);
}

.nav__actions {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}

/* Theme toggle. Shows the icon for the mode it will switch TO. */
.theme-toggle {
	display: inline-grid;
	place-items: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
	color: var(--text-muted);
	cursor: pointer;
	transition: background var(--dur) var(--ease),
		color var(--dur) var(--ease);
}

.theme-toggle:hover {
	background: var(--surface-2);
	color: var(--text);
}

.theme-toggle svg {
	width: 17px;
	height: 17px;
}

.theme-toggle__moon {
	display: none;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .theme-toggle__sun {
		display: none;
	}

	:root:not([data-theme="light"]) .theme-toggle__moon {
		display: block;
	}
}

:root[data-theme="dark"] .theme-toggle__sun {
	display: none;
}

:root[data-theme="dark"] .theme-toggle__moon {
	display: block;
}

:root[data-theme="light"] .theme-toggle__sun {
	display: block;
}

:root[data-theme="light"] .theme-toggle__moon {
	display: none;
}

/* === footer ============================================================== */

.footer {
	border-top: 1px solid var(--border);
	background: var(--surface);
	padding: var(--sp-5);
	margin-top: auto;
}

.footer__inner {
	max-width: var(--page-max);
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2) var(--sp-4);
	font-size: var(--fs-sm);
	color: var(--text-subtle);
}

.footer a {
	color: var(--text-muted);
}

/* === typography ========================================================== */

.page-title {
	font-size: var(--fs-2xl);
	font-weight: var(--fw-bold);
	line-height: var(--lh-tight);
	letter-spacing: -0.02em;
	margin-bottom: var(--sp-2);
}

.section-title {
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
	margin-bottom: var(--sp-3);
}

.prose {
	max-width: 68ch;
	color: var(--text-muted);
}

.prose h1 {
	font-size: var(--fs-2xl);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
	line-height: var(--lh-tight);
	color: var(--text);
	margin-bottom: var(--sp-4);
}

.prose h2 {
	font-size: var(--fs-lg);
	font-weight: var(--fw-semibold);
	color: var(--text);
	margin: var(--sp-6) 0 var(--sp-3);
}

.prose h3,
.prose h4,
.prose h5,
.prose h6 {
	font-size: var(--fs-md);
	font-weight: var(--fw-semibold);
	color: var(--text);
	margin: var(--sp-5) 0 var(--sp-2);
}

.prose h5,
.prose h6 {
	font-size: var(--fs-base);
}

code {
	font-family: var(--font-mono);
	font-size: 0.9em;
	padding: 1px 5px;
	border-radius: var(--radius-sm);
	background: var(--surface-2);
	color: var(--text);
}

.prose p,
.prose ul,
.prose ol {
	margin-bottom: var(--sp-4);
}

.prose ul,
.prose ol {
	padding-left: var(--sp-5);
}

.prose li {
	margin-bottom: var(--sp-2);
}

.prose hr {
	border: 0;
	border-top: 1px solid var(--border);
	margin: var(--sp-6) 0;
}

.lede {
	font-size: var(--fs-lg);
	color: var(--text-muted);
	line-height: 1.5;
}

/* === buttons ============================================================= */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	padding: var(--sp-2) var(--sp-4);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius);
	background: var(--surface);
	color: var(--text);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
	cursor: pointer;
	white-space: nowrap;
	transition: background var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

/* Touch targets. The 38px a .btn computes to clears WCAG 2.5.8's 24px floor
   but misses both Apple's 44pt guidance and WCAG 2.5.5, and on the homepage
   these are the primary actions. Keyed on pointer rather than viewport width
   because this is a property of the input device, not the layout: a touch
   tablet at 1024px needs the larger target and a mouse at 700px does not. */
@media (pointer: coarse) {
	.btn {
		min-height: 44px;
	}
}

.btn:hover {
	background: var(--surface-2);
	text-decoration: none;
}

.btn svg {
	width: 15px;
	height: 15px;
}

.btn--primary {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--accent-fg);
}

.btn--primary:hover {
	background: var(--accent-hover);
	border-color: var(--accent-hover);
}

.btn--ghost {
	border-color: transparent;
	background: transparent;
	color: var(--text-muted);
}

.btn--ghost:hover {
	background: var(--surface-2);
	color: var(--text);
}

.btn--danger {
	background: var(--bad);
	border-color: var(--bad);
	color: var(--text-inverse);
}

.btn--block {
	width: 100%;
}

.btn[disabled] {
	opacity: 0.5;
	cursor: not-allowed;
}

/* === forms =============================================================== */

.field {
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}

.field__label {
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
}

.input,
.select {
	width: 100%;
	padding: var(--sp-2) var(--sp-3);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius);
	background: var(--surface);
	color: var(--text);
	font-size: var(--fs-sm);
	transition: border-color var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
}

.input::placeholder {
	color: var(--text-subtle);
}

.input:focus,
.select:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px var(--accent-soft);
}

.select {
	appearance: none;
	padding-right: var(--sp-6);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23858c9b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--sp-3) center;
	background-size: 15px;
	cursor: pointer;
}

.search-field {
	position: relative;
}

.search-field .input {
	padding-left: var(--sp-6);
}

.search-field__icon {
	position: absolute;
	left: var(--sp-3);
	top: 50%;
	transform: translateY(-50%);
	width: 15px;
	height: 15px;
	color: var(--text-subtle);
	pointer-events: none;
}

.checkbox {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	font-size: var(--fs-sm);
	cursor: pointer;
	padding: var(--sp-1) 0;
}

.checkbox input {
	width: 16px;
	height: 16px;
	accent-color: var(--accent);
	cursor: pointer;
	margin: 0;
}

/* === cards / surfaces ==================================================== */

.card {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: var(--sp-5);
}

.panel {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	overflow: hidden;
}

.empty-state {
	text-align: center;
	padding: var(--sp-8) var(--sp-5);
	color: var(--text-muted);
}

.empty-state__title {
	font-size: var(--fs-lg);
	font-weight: var(--fw-semibold);
	color: var(--text);
	margin-bottom: var(--sp-2);
}

/* === badges ============================================================== */

.badge {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-1);
	padding: 2px var(--sp-2);
	border-radius: var(--radius-pill);
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	letter-spacing: 0.02em;
	background: var(--surface-2);
	color: var(--text-muted);
	white-space: nowrap;
}

.badge--good {
	background: var(--good-soft);
	color: var(--good);
}

.badge--warn {
	background: var(--warn-soft);
	color: var(--warn);
}

.badge--bad {
	background: var(--bad-soft);
	color: var(--bad);
}

.badge--accent {
	background: var(--accent-soft);
	color: var(--accent);
}

.badge svg {
	width: 11px;
	height: 11px;
}

/* Injury marker: a real <details> disclosure, no tooltip library. */
.injury {
	display: inline-block;
	position: relative;
}

.injury > summary {
	list-style: none;
	cursor: pointer;
	display: inline-flex;
}

.injury > summary::-webkit-details-marker {
	display: none;
}

.injury__note {
	position: absolute;
	z-index: 30;
	top: calc(100% + var(--sp-1));
	left: 0;
	width: max-content;
	max-width: 280px;
	padding: var(--sp-3);
	background: var(--surface);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius);
	box-shadow: var(--shadow-lg);
	font-size: var(--fs-sm);
	font-weight: var(--fw-normal);
	line-height: 1.45;
	color: var(--text-muted);
	white-space: normal;
	text-align: left;
}

.injury__note strong {
	display: block;
	color: var(--text);
	margin-bottom: var(--sp-1);
}

/* === data table ========================================================== */

.table-wrap {
	overflow-x: auto;
	overscroll-behavior-x: contain;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
}

.data-table {
	width: 100%;
	font-size: var(--fs-sm);
}

.data-table th,
.data-table td {
	padding: var(--sp-3);
	text-align: right;
	white-space: nowrap;
	border-bottom: 1px solid var(--border);
}

.data-table th:first-child,
.data-table td:first-child,
.data-table .cell--left {
	text-align: left;
}

.data-table thead th {
	position: sticky;
	top: 0;
	z-index: 2;
	background: var(--surface-2);
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
	border-bottom: 1px solid var(--border-strong);
}

.data-table tbody tr:last-child td {
	border-bottom: 0;
}

.data-table tbody tr:hover td {
	background: var(--surface-2);
}

/* Sticky player column, so horizontal scroll never loses the row identity. */
.data-table .col--sticky {
	position: sticky;
	left: 0;
	z-index: 1;
	background: var(--surface);
}

.data-table thead .col--sticky {
	z-index: 3;
	background: var(--surface-2);
}

.data-table tbody tr:hover .col--sticky {
	background: var(--surface-2);
}

.data-table .col--sticky::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: -1px;
	width: 1px;
	background: var(--border);
}

.data-table .col--rank {
	color: var(--text-subtle);
	font-variant-numeric: tabular-nums;
	width: 1%;
}

/* Sortable headers */
.sortable {
	cursor: pointer;
	user-select: none;
}

.sortable button {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-1);
	padding: 0;
	margin: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-transform: inherit;
	letter-spacing: inherit;
	cursor: pointer;
}

.sortable button:hover {
	color: var(--text);
}

.sort-arrow {
	width: 11px;
	height: 11px;
	opacity: 0;
	flex: none;
	transition: opacity var(--dur) var(--ease),
		transform var(--dur) var(--ease);
}

.sortable:hover .sort-arrow {
	opacity: 0.4;
}

[aria-sort="ascending"] .sort-arrow {
	opacity: 1;
	transform: rotate(180deg);
}

[aria-sort="descending"] .sort-arrow {
	opacity: 1;
}

[aria-sort] button {
	color: var(--text);
}

/* Player identity cell */
.player-cell {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	min-width: 0;
}

.player-cell__name {
	font-weight: var(--fw-medium);
	color: var(--text);
}

.player-cell__name:hover {
	color: var(--accent);
}

.player-cell__meta {
	color: var(--text-subtle);
	font-size: var(--fs-xs);
	font-variant-numeric: tabular-nums;
}

/* KJPI cell: the number, plus a strength bar underneath it. */
.kjpi {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 3px;
	min-width: 52px;
}

.kjpi__value {
	font-variant-numeric: tabular-nums;
	font-weight: var(--fw-semibold);
	font-size: var(--fs-base);
	line-height: 1.1;
	color: var(--text);
}

.kjpi__bar {
	width: 100%;
	height: 3px;
	border-radius: var(--radius-pill);
	background: var(--rating-track);
	overflow: hidden;
}

.kjpi__fill {
	display: block;
	height: 100%;
	border-radius: inherit;
	background: var(--accent);
}

/* Tier the bar rather than painting every row with the brand colour. The
   width already carries magnitude; the hue carries which band the score is
   in, which is what makes a sorted column scannable in groups. Thresholds
   match .meter, so a 60 reads the same here as on the player page. */
.kjpi--high .kjpi__fill {
	background: var(--rating-high);
}

.kjpi--mid .kjpi__fill {
	background: var(--rating-mid);
}

.kjpi--low .kjpi__fill {
	background: var(--rating-low);
}

/* Value against the position's target: an actual threshold, so traffic
   lights are meaningful here in a way they are not for a ranking. */
.value--over {
	color: var(--good);
	font-weight: var(--fw-semibold);
}

.value--near {
	color: var(--warn);
}

.value--under {
	color: var(--text-subtle);
}

.row--hit td {
	background: var(--good-soft);
}

.data-table tbody tr.row--hit:hover td,
.data-table tbody tr.row--hit:hover .col--sticky {
	background: var(--good-soft);
	filter: brightness(0.98);
}

.row--miss td {
	background: var(--bad-soft);
}

.data-table tbody tr.row--miss:hover td,
.data-table tbody tr.row--miss:hover .col--sticky {
	background: var(--bad-soft);
	filter: brightness(0.98);
}

.row--hit .col--sticky,
.row--miss .col--sticky {
	background: inherit;
}

/* === league page layout ================================================== */

/* Three children -- rail, main, ad -- in DOM order, so the narrow layout
   stacks as filters / table / ad with no duplicated markup. On desktop the
   ad is placed back under the rail. Rendering two ad units and hiding one per
   breakpoint does not work: the hidden one measures 0px wide and AdSense
   rejects it ("Fluid responsive ads must be at least 250px wide"). */
.slate {
	display: grid;
	grid-template-columns: var(--rail-width) minmax(0, 1fr);
	gap: var(--sp-5);
	align-items: start;
}

.slate > .rail {
	grid-column: 1;
	grid-row: 1;
}

.slate__main {
	grid-column: 2;
	grid-row: 1 / span 2;
	min-width: 0;
}

.slate__ad {
	grid-column: 1;
	grid-row: 2;
}

@media (max-width: 1023px) {
	.slate {
		grid-template-columns: minmax(0, 1fr);
	}

	.slate > .rail,
	.slate__main,
	.slate__ad {
		grid-column: 1;
		grid-row: auto;
	}
}

.rail {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
	position: sticky;
	top: calc(var(--nav-height) + var(--sp-5));
}

@media (max-width: 1023px) {
	.rail {
		position: static;
		gap: var(--sp-3);
	}
}

.rail__group {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: var(--sp-4);
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}

/* Below the two-column breakpoint the rail stacks above the table. As a
   vertical list it pushed the first row of data off the bottom of a phone
   screen, so the controls pair up and the ad moves below the table.
   This must stay AFTER the base .rail__group rule: same specificity, so
   source order is what decides it. */
@media (max-width: 1023px) {
	.rail__group {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
		gap: var(--sp-3) var(--sp-4);
		align-items: end;
	}

	.rail__group .search-field,
	.rail__group #filter-clear {
		grid-column: 1 / -1;
	}

	/* The league/site switcher keeps full-width rows: paired into half
	   tracks, "DraftKings" does not fit and was overflowing its control. */
	.rail__group--switch {
		grid-template-columns: minmax(0, 1fr);
	}

	.segmented__option {
		min-width: 0;
		font-size: var(--fs-sm);
	}

}

.slate__header {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--sp-3);
	margin-bottom: var(--sp-4);
}

.slate__count {
	font-size: var(--fs-sm);
	color: var(--text-subtle);
	font-variant-numeric: tabular-nums;
}

.slate__aside {
	display: flex;
	align-items: baseline;
	gap: var(--sp-3);
}

.slate__meta {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

/* Segmented control for site / league switching */
.segmented {
	display: flex;
	padding: 3px;
	gap: 2px;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius);
}

.segmented__option {
	flex: 1;
	text-align: center;
	padding: var(--sp-2) var(--sp-2);
	border-radius: var(--radius-sm);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
	color: var(--text-muted);
	white-space: nowrap;
}

.segmented__option:hover {
	color: var(--text);
	text-decoration: none;
}

.segmented__option[aria-current="true"] {
	background: var(--surface);
	color: var(--text);
	box-shadow: var(--shadow-sm);
}

/* === player detail ======================================================= */

.player-header {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--sp-4);
	margin-bottom: var(--sp-5);
}

.player-header__name {
	font-size: var(--fs-2xl);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
	line-height: var(--lh-tight);
}

.player-header__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
	margin-top: var(--sp-2);
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.stat-strip {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
	margin-bottom: var(--sp-5);
}

.stat-tile {
	flex: 1 1 120px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: var(--sp-4);
}

.stat-tile__label {
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
	margin-bottom: var(--sp-1);
}

.stat-tile__value {
	font-size: var(--fs-xl);
	font-weight: var(--fw-bold);
	font-variant-numeric: tabular-nums;
	line-height: 1.15;
	letter-spacing: -0.01em;
}

.stat-tile__sub {
	font-size: var(--fs-xs);
	color: var(--text-subtle);
	margin-top: var(--sp-1);
	font-variant-numeric: tabular-nums;
}

.player-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--sp-5);
	margin-bottom: var(--sp-5);
	align-items: start;
}

@media (max-width: 899px) {
	.player-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Rating meters -- these replace the Chart.js bar chart entirely. */
.meters {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}

.meter__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--sp-3);
	margin-bottom: var(--sp-2);
}

.meter__label {
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
}

.meter__weight {
	font-size: var(--fs-xs);
	color: var(--text-subtle);
	font-variant-numeric: tabular-nums;
}

.meter__value {
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	font-variant-numeric: tabular-nums;
	margin-left: auto;
}

.meter__track {
	height: 8px;
	border-radius: var(--radius-pill);
	background: var(--rating-track);
	overflow: hidden;
}

.meter__fill {
	display: block;
	height: 100%;
	border-radius: inherit;
	background: var(--rating-mid);
	transition: width var(--dur) var(--ease);
}

.meter--high .meter__fill {
	background: var(--rating-high);
}

.meter--high .meter__value {
	color: var(--rating-high);
}

.meter--mid .meter__fill {
	background: var(--rating-mid);
}

.meter--mid .meter__value {
	color: var(--rating-mid);
}

.meter--low .meter__fill {
	background: var(--rating-low);
}

.meter--low .meter__value {
	color: var(--rating-low);
}

.meter--weight .meter__fill {
	background: var(--accent);
}

.meter--weight .meter__value {
	color: var(--text-muted);
}

.meter--none .meter__fill {
	background: var(--border-strong);
	width: 0;
}

.meter--none .meter__value {
	color: var(--text-subtle);
	font-weight: var(--fw-normal);
}

/* News list */
.news {
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}

.news__item {
	padding: var(--sp-3);
	background: var(--surface-2);
	border-radius: var(--radius);
	font-size: var(--fs-sm);
	color: var(--text-muted);
	line-height: 1.5;
}

.news__item a {
	color: var(--accent);
}

.alert {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	border-radius: var(--radius);
	font-size: var(--fs-sm);
	margin-bottom: var(--sp-4);
}

.alert svg {
	flex: none;
	width: 16px;
	height: 16px;
	margin-top: 2px;
}

.alert--danger {
	background: var(--bad-soft);
	color: var(--bad);
}

.alert--info {
	background: var(--accent-soft);
	color: var(--accent);
}

.alert--warn {
	background: var(--warn-soft);
	color: var(--warn);
}

.alert strong {
	font-weight: var(--fw-semibold);
}

/* === home ================================================================ */

.hero {
	padding: var(--sp-7) 0 var(--sp-6);
	text-align: center;
}

.hero__title {
	font-size: var(--fs-3xl);
	font-weight: var(--fw-bold);
	letter-spacing: -0.03em;
	line-height: 1.1;
	margin-bottom: var(--sp-3);
}

.hero__title b {
	color: var(--accent);
}

.hero__sub {
	font-size: var(--fs-lg);
	color: var(--text-muted);
	max-width: 52ch;
	margin: 0 auto var(--sp-5);
}

@media (max-width: 767px) {
	.hero {
		padding: var(--sp-5) 0;
	}

	.hero__title {
		font-size: var(--fs-2xl);
	}

	.hero__sub {
		font-size: var(--fs-md);
	}
}

.trust {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.league-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: var(--sp-4);
	margin-bottom: var(--sp-6);
}

.league-block {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
	padding: var(--sp-5);
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
}

/* No space-between: it pinned the badge to the far edge of the block, which on
   a wide viewport left it stranded most of a screen away from the league name
   it annotates -- far enough that it read as missing. A badge belongs beside
   the thing it labels. */
.league-block__head {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
}

.league-block__name {
	font-size: var(--fs-xl);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
}

.league-block__sites {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
}

.league-block__sites .btn {
	flex: 1 1 auto;
}

.league-block__note {
	color: var(--text-muted);
	font-size: var(--fs-sm);
	margin: 0;
}

/* Leagues with nothing to show yet. Deliberately not .league-block: a border
   around an empty container makes the emptiness the loudest thing on the row. */
.league-status {
	list-style: none;
	margin: 0 0 var(--sp-6);
	padding: 0;
}

.league-status__row {
	display: flex;
	align-items: baseline;
	gap: var(--sp-3);
	padding: var(--sp-3) 0;
	border-bottom: 1px solid var(--border);
}

.league-status__row:last-child {
	border-bottom: 0;
}

.league-status__name {
	font-size: var(--fs-lg);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
	min-width: 3.5rem;
}

.league-status__when {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

/* Worked example on the landing page. The body of the card is .stat-strip and
   .meters straight from the player page, so what a visitor sees here is the
   real component rather than a lookalike built to resemble it. */
.sample__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--sp-3);
	margin-bottom: var(--sp-4);
}

.sample__player {
	font-size: var(--fs-lg);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
}

.sample__meta {
	margin-top: 2px;
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.home-cta {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-3);
	margin-bottom: var(--sp-5);
}

/* Component glossary and FAQ on /about */
.glossary {
	display: grid;
	gap: var(--sp-3);
	margin-bottom: var(--sp-5);
}

.glossary__term {
	font-weight: var(--fw-semibold);
	color: var(--text);
}

.faq {
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}

.faq__item {
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}

.faq__item > summary {
	cursor: pointer;
	padding: var(--sp-3) var(--sp-4);
	font-weight: var(--fw-medium);
	color: var(--text);
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
}

.faq__item > summary::-webkit-details-marker {
	display: none;
}

.faq__item > summary::after {
	content: "+";
	color: var(--text-subtle);
	font-size: var(--fs-lg);
	line-height: 1;
	flex: none;
}

.faq__item[open] > summary::after {
	content: "\2212";
}

.faq__answer {
	padding: 0 var(--sp-4) var(--sp-4);
	color: var(--text-muted);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

/* === ads ================================================================= */

/* The slot reserves its height so a slow ad cannot shift the layout. */
.ad-slot {
	min-height: 120px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	border-radius: var(--radius);
	background: var(--surface-2);
}

.ad-slot ins {
	display: block;
	width: 100%;
}

/* === admin =============================================================== */

.admin-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	margin-bottom: var(--sp-5);
}

.admin-section {
	margin-bottom: var(--sp-6);
}

.form-stack {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
	max-width: 440px;
}

.fieldset {
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: var(--sp-4);
	margin: 0;
}

.fieldset > legend {
	padding: 0 var(--sp-2);
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
}

/* === error pages ========================================================= */

.error-page {
	text-align: center;
	padding: var(--sp-8) var(--sp-4);
}

.error-page__code {
	font-size: var(--fs-3xl);
	font-weight: var(--fw-bold);
	color: var(--text-subtle);
	letter-spacing: -0.03em;
}

.error-page__title {
	font-size: var(--fs-xl);
	font-weight: var(--fw-semibold);
	margin: var(--sp-2) 0 var(--sp-3);
}

.error-page p {
	color: var(--text-muted);
	margin-bottom: var(--sp-5);
}

/* === utilities (deliberately few) ======================================== */

.stack {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}

.row-flex {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}

.muted {
	color: var(--text-muted);
}

.subtle {
	color: var(--text-subtle);
}

.text-sm {
	font-size: var(--fs-sm);
}

.mt-4 {
	margin-top: var(--sp-4);
}

.mb-4 {
	margin-bottom: var(--sp-4);
}

.hidden {
	display: none !important;
}
