/* ---------------------------------------------------------------------------
   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 {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-3);
	font-size: var(--fs-3xl);
	font-weight: var(--fw-bold);
	letter-spacing: -0.03em;
	line-height: 1.1;
	margin-bottom: var(--sp-3);
}

/* Sized to the type, so it scales with the heading down to mobile. */
.hero__mark {
	width: 1em;
	height: 1em;
	flex-shrink: 0;
}

.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;
}

/* Worked example on the landing page, shown in a phone.

   It used to be a flush card, which made it read as one more panel of the
   homepage rather than as a screen. The frame is the whole point: it says
   "this is what you will be looking at" before a word of copy does. Drawn in
   CSS -- an image would be one more asset to keep in step with the real UI. */
.sample__layout {
	display: flex;
	flex-direction: column;
}

/* Proportioned like a handset rather than sized by its contents. Without a
   fixed ratio the two frames took the height of whatever was inside them, so
   a six-row list and a five-meter panel came out as two different objects. */
.device {
	width: 252px;
	flex-shrink: 0;
	padding: 9px;
	background: var(--device-bezel);
	border: 1px solid var(--device-bezel-edge);
	border-radius: 40px;
	box-shadow: var(--shadow-lg);
}

.device__screen {
	position: relative;
	/* 9:19.5, an iPhone. The screen clips: a slate runs past the bottom of a
	   phone in life too, and a cut-off row says "scrolls" better than a
	   list that happens to end. */
	aspect-ratio: 9 / 19.5;
	background: var(--bg);
	border-radius: 32px;
	overflow: hidden;
	padding-top: 26px;
}

/* The Dynamic Island: hardware showing through the screen, so it takes the
   bezel colour in both themes rather than a border token. */
.device__notch {
	position: absolute;
	top: 8px;
	left: 50%;
	transform: translateX(-50%);
	width: 66px;
	height: 18px;
	border-radius: var(--radius-pill);
	background: var(--device-bezel);
}

@media (max-width: 899px) {
	.device {
		width: 236px;
	}
}

/* The nav strip every real page opens with. Without it the screens started at
   the page heading, which is not what either page looks like. */
.device__nav {
	display: flex;
	align-items: center;
	gap: 5px;
	padding: 5px var(--sp-2);
	border-bottom: 1px solid var(--border);
	font-size: 0.5625rem;
	font-weight: var(--fw-semibold);
	letter-spacing: -0.01em;
}

.device__mark {
	width: 11px;
	height: 11px;
	flex-shrink: 0;
}

/* The rail's league and site controls, which on a phone sit above the title.
   Present because the mock is meant to be what a visitor actually lands on,
   and this is the first thing on the real page after the nav. */
.device__switch {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	gap: 3px var(--sp-2);
	padding: var(--sp-2);
	background: var(--surface);
	border-bottom: 1px solid var(--border);
}

.device__flabel {
	font-size: 0.5rem;
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
}

.device__seg {
	display: flex;
	background: var(--surface-2);
	border-radius: var(--radius-sm);
	padding: 1px;
	font-size: 0.5rem;
	font-weight: var(--fw-semibold);
}

.device__seg b,
.device__seg i {
	flex: 1;
	text-align: center;
	padding: 2px 0;
	border-radius: 3px;
	font-style: normal;
}

.device__seg b {
	background: var(--surface);
	color: var(--text);
}

.device__seg i {
	color: var(--text-subtle);
	font-weight: var(--fw-medium);
}

.device__thead {
	display: flex;
	gap: var(--sp-2);
	padding: 3px var(--sp-2);
	background: var(--surface-2);
	font-size: 0.5rem;
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--text-subtle);
}

.device__thead span:first-child {
	margin-right: auto;
}

.device__thead-r {
	text-align: right;
}

.device__back {
	padding: var(--sp-2) var(--sp-2) 0;
	font-size: 0.5625rem;
	color: var(--text-muted);
}

/* .stat-strip at phone scale -- same tiles, same order as the player page. */
.pdetail__tiles {
	display: flex;
	gap: 4px;
	margin-bottom: var(--sp-3);
}

.pdetail__tile {
	flex: 1;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	padding: 4px 5px;
}

.pdetail__tile span {
	display: block;
	font-size: 0.5rem;
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--text-subtle);
}

.pdetail__tile b {
	display: block;
	font-size: 0.8125rem;
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
	font-variant-numeric: tabular-nums;
}

.pdetail__section {
	font-size: 0.5rem;
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-subtle);
	margin-bottom: var(--sp-2);
}

.device__bar {
	padding: var(--sp-2) var(--sp-3) var(--sp-3);
	border-bottom: 1px solid var(--border);
}

.device__title {
	display: block;
	font-size: var(--fs-base);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
}

.device__sub {
	display: block;
	margin-top: 1px;
	font-size: var(--fs-xs);
	color: var(--text-subtle);
}

.mini {
	margin: 0;
	padding: 0;
	list-style: none;
	background: var(--surface);
}

.mini__row {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-2);
	border-bottom: 1px solid var(--border);
}

.mini__row:last-child {
	border-bottom: 0;
}

.mini__who {
	display: flex;
	flex-direction: column;
	margin-right: auto;
	min-width: 0;
}

.mini__name {
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	letter-spacing: -0.01em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.mini__meta {
	font-size: var(--fs-xs);
	color: var(--text-subtle);
}

.mini__sal {
	font-size: 0.625rem;
	color: var(--text-muted);
	font-variant-numeric: tabular-nums;
}

.mini__meta {
	font-size: 0.625rem;
}

/* The real .kjpi cell, shrunk. Reusing the macro means the bar tiers itself
   off the same thresholds the slate uses, so this cannot drift from it. */
.mini__kjpi .kjpi {
	min-width: 40px;
}

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

/* Two screens, because one showed the product without showing the point of
   it: the slate is where a player is spotted, the detail view is where the
   score is justified. Staggered rather than rotated -- an angled render is a
   marketing flourish this design has no other examples of. */
.sample__devices {
	display: flex;
	gap: var(--sp-4);
	align-items: flex-start;
	justify-content: center;
}

@media (max-width: 899px) {
	.sample__devices {
		flex-direction: column;
		align-items: center;
	}
}

/* Player screen. Reuses ui.rating_meter, so the tier colours and thresholds
   are the real ones and cannot drift from the page it depicts. */
.pdetail {
	background: var(--surface);
	padding: var(--sp-3);
}

.meters--compact {
	gap: var(--sp-2);
}

.meters--compact .meter__label {
	font-size: var(--fs-xs);
}

.meters--compact .meter__value {
	font-size: var(--fs-xs);
}

/* Two buttons, one per league. Big enough to be the obvious thing to do on
   this page, and unmistakably off when the season is not running. */
.league-picker {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: var(--sp-3);
	margin-bottom: var(--sp-6);
}

.league-pick {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-4);
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-lg);
	background: var(--surface);
	color: var(--text);
	transition: border-color var(--dur) var(--ease),
		background var(--dur) var(--ease);
}

a.league-pick:hover {
	background: var(--surface-2);
	border-color: var(--text-subtle);
	text-decoration: none;
}

/* A span, not a dimmed anchor: nothing to focus and nothing to click. */
.league-pick--off {
	border-style: dashed;
	border-color: var(--border);
	background: transparent;
	cursor: not-allowed;
}

.league-pick__mark {
	display: grid;
	place-items: center;
	width: 42px;
	height: 42px;
	flex-shrink: 0;
	border-radius: var(--radius);
	background: var(--surface-2);
	color: var(--text-muted);
}

.league-pick--off .league-pick__mark {
	color: var(--text-subtle);
}

.league-pick__mark svg {
	width: 21px;
	height: 21px;
}

.league-pick__text {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.league-pick__name {
	font-size: var(--fs-lg);
	font-weight: var(--fw-bold);
	letter-spacing: -0.02em;
	line-height: 1.2;
}

.league-pick--off .league-pick__name {
	color: var(--text-muted);
}

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

/* A season about to start is the one thing here worth noticing. */
.league-pick__status--soon {
	color: var(--text-muted);
	font-weight: var(--fw-medium);
}

/* A rule instead of a heading over the screens. They are an illustration, not
   a topic, and a label above them was one more piece of furniture. */
.section-rule {
	border: 0;
	border-top: 1px solid var(--border);
	margin: var(--sp-6) 0 var(--sp-5);
}

.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;
}
