/*
 * Leaderboard widget styling.
 *
 * The widget is embedded in the game through an Iframe or HTML Element object, so
 * it has to sit on top of whatever the game is drawing: `?bg=transparent` removes
 * the panel background, and nothing here assumes a particular viewport size.
 *
 * ---------------------------------------------------------------------------
 * TO MATCH THE GAME'S LOOK, EDIT public/theme.css - NOT THIS FILE.
 * ---------------------------------------------------------------------------
 *
 * Every colour, font and radius below is a custom property, and theme.css loads
 * after this file so it can override any of them. Keeping your values there means
 * pulling a new version of the widget never clobbers your styling.
 *
 * The tokens, and what each one paints:
 *
 *   --font          whole widget; set this to the game's UI font
 *   --font-light    low-emphasis text: status line, run count, breakdown labels
 *   --font-numeric  scores and stat columns, if the game uses a separate face
 *   --bg            page behind the panel (invisible when bg=transparent)
 *   --panel         the panel itself
 *   --panel-alt     row hover, submit panel, breakdown block
 *   --border        every rule and outline
 *   --text          primary text
 *   --text-dim      column headers, stat figures, secondary text
 *   --accent        score preview, focus rings, primary button
 *   --accent-soft   the player's own row, at rest
 *   --accent-flash  the player's own row, mid-flash after submitting
 *   --gold/--silver/--bronze   ranks 1, 2 and 3
 *   --danger        error text
 *   --radius        corner rounding
 *   --pad           panel padding
 */

:root {
	--font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	/* Both default to --font, so a theme that sets only --font still works. */
	--font-light: var(--font);
	--font-numeric: var(--font);
	--bg: #0e1116;
	--panel: #161b22;
	--panel-alt: #1c222c;
	--border: #2a323d;
	--text: #e6edf3;
	--text-dim: #8b98a8;
	--accent: #4da3ff;
	--accent-soft: rgba(77, 163, 255, 0.14);
	--accent-flash: rgba(77, 163, 255, 0.42);
	--gold: #e3b341;
	--silver: #b6c2cf;
	--bronze: #cd7f47;
	--danger: #ff6b6b;
	--radius: 10px;
	--pad: 14px;
	color-scheme: dark;
}

:root[data-theme="light"] {
	--bg: #f4f6f9;
	--panel: #ffffff;
	--panel-alt: #eef2f7;
	--border: #d5dce5;
	--text: #16202b;
	--text-dim: #5d6b7c;
	--accent: #1667c8;
	--accent-soft: rgba(22, 103, 200, 0.10);
	--accent-flash: rgba(22, 103, 200, 0.28);
	--gold: #b8860b;
	--silver: #7c8794;
	--bronze: #a2653a;
	--danger: #c62828;
	color-scheme: light;
}

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

/* Author `display` rules outrank the user agent's `[hidden] { display: none }`
   whatever their specificity, so hiding has to be restated here. */
[hidden] { display: none !important; }

html, body {
	margin: 0;
	padding: 0;
	min-height: 100%;
}

body {
	background: var(--bg);
	color: var(--text);
	font: 15px/1.45 var(--font);
	/* Stops a drag inside the widget from scrolling the page behind the game. */
	overscroll-behavior: contain;
}

body[data-bg="transparent"] { background: transparent; }
body[data-bg="transparent"] .board { background: rgba(14, 17, 22, 0.86); backdrop-filter: blur(6px); }
body[data-bg="transparent"]:where([data-theme="light"]) .board { background: rgba(255, 255, 255, 0.9); }

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.board {
	max-width: 900px;
	margin: 0 auto;
	padding: var(--pad);
	background: var(--panel);
	border-radius: var(--radius);
	display: flex;
	flex-direction: column;
	gap: 12px;
	min-height: 100vh;
}

@media (min-width: 640px) {
	.board {
		min-height: 0;
		margin: 12px auto;
		border: 1px solid var(--border);
	}
}

.board__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.board__title {
	margin: 0;
	font-size: 19px;
	font-weight: 650;
	letter-spacing: 0.01em;
}

.board__meta {
	font-family: var(--font-light);
	margin: 0;
	color: var(--text-dim);
	font-size: 13px;
}

/* The table is wider than a phone. It scrolls inside this box so the page itself
   never scrolls sideways under the game. */
.board__scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	margin: 0 calc(var(--pad) * -1);
	padding: 0 var(--pad);
}

.table {
	width: 100%;
	border-collapse: collapse;
	font-family: var(--font-numeric);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.table th {
	text-align: right;
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--text-dim);
	padding: 6px 8px;
	border-bottom: 1px solid var(--border);
}

.table th.col-rank,
.table th.col-name { text-align: left; }

.table td {
	padding: 7px 8px;
	border-bottom: 1px solid var(--border);
	text-align: right;
}

/* Every entry appends a row plus a hidden detail row, so `tr:last-child` is the
   detail and the last visible row would keep its rule - doubling up against the
   footer's. The class is applied in renderTable instead. */
.table tbody tr.row--last td { border-bottom: none; }

/* Qualified with `.table` so these beat the right-aligned `.table td` default. */
.table .col-rank, .table .cell-rank { width: 3.2em; text-align: left; }
.table .col-name, .table .cell-name { text-align: left; }
.table .col-score, .table .cell-score { font-weight: 650; }

.row { cursor: pointer; }
.row:hover { background: var(--panel-alt); }
.row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.row--highlight {
	background: var(--accent-soft);
	box-shadow: inset 3px 0 0 var(--accent);
}

/* The player's own row is the one they are reading, so its stat cells drop the
   dimmed treatment - dim text over the highlight tint is hard to read. */
.row--highlight .stat,
.row--highlight .rank { color: var(--text); }

.row--context-head td {
	padding-top: 14px;
	color: var(--text-dim);
	font-size: 12px;
	text-align: center;
	letter-spacing: 0.08em;
}

.rank { font-weight: 650; color: var(--text-dim); }
.rank--1 { color: var(--gold); }
.rank--2 { color: var(--silver); }
.rank--3 { color: var(--bronze); }

.name {
	display: inline-block;
	max-width: 16ch;
	overflow: hidden;
	text-overflow: ellipsis;
	vertical-align: bottom;
}

.side {
	display: inline-block;
	margin-left: 6px;
	padding: 0 5px;
	border: 1px solid var(--border);
	border-radius: 4px;
	font-size: 10px;
	line-height: 16px;
	color: var(--text-dim);
	vertical-align: middle;
}

.stat { color: var(--text-dim); }

/* Expanded score breakdown */
.detail td {
	padding: 0 8px 12px;
	text-align: left;
	white-space: normal;
}

.breakdown {
	list-style: none;
	margin: 0;
	padding: 10px 12px;
	background: var(--panel-alt);
	border-radius: 8px;
	display: grid;
	grid-template-columns: 1fr auto auto;
	gap: 4px 12px;
	font-size: 13px;
}

.breakdown__label { color: var(--text-dim); font-family: var(--font-light); }
.breakdown__factor { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.breakdown__points { text-align: right; font-variant-numeric: tabular-nums; }

.breakdown__total {
	grid-column: 1 / -1;
	display: grid;
	grid-template-columns: subgrid;
	padding-top: 6px;
	margin-top: 2px;
	border-top: 1px solid var(--border);
	font-weight: 650;
}

/* Submit panel */
.submit {
	background: var(--panel-alt);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 14px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.submit__title {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--text-dim);
}

.submit__score { margin: 0; display: flex; align-items: baseline; gap: 8px; }

.submit__score-value {
	font-size: 34px;
	font-weight: 700;
	line-height: 1;
	font-variant-numeric: tabular-nums;
	color: var(--accent);
}

.submit__score-label { color: var(--text-dim); font-size: 13px; }

.submit .breakdown { background: transparent; padding: 0; }

.submit__form { display: flex; flex-direction: column; gap: 6px; }

.submit__label {
	font-family: var(--font-light);
	font-size: 12px;
	color: var(--text-dim);
}

.submit__row { display: flex; gap: 8px; flex-wrap: wrap; }

.submit__input {
	flex: 1 1 12ch;
	min-width: 0;
	padding: 9px 10px;
	font: inherit;
	color: var(--text);
	background: var(--panel);
	border: 1px solid var(--border);
	border-radius: 8px;
}

.submit__input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 1px;
}

.submit__error { margin: 0; color: var(--danger); font-size: 13px; }

.button {
	padding: 9px 16px;
	font: inherit;
	font-weight: 600;
	color: var(--text);
	background: var(--panel-alt);
	border: 1px solid var(--border);
	border-radius: 8px;
	cursor: pointer;
}

.button:hover:not(:disabled) { border-color: var(--accent); }
.button:disabled { opacity: 0.55; cursor: default; }
.button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.button--primary {
	background: var(--accent);
	border-color: var(--accent);
	color: #fff;
}

:root[data-theme="light"] .button--primary { color: #fff; }

.status { margin: 0; color: var(--text-dim); font-size: 13px; font-family: var(--font-light); }
.status--error { color: var(--danger); }
.status[hidden] { display: none; }

.board__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	flex-wrap: wrap;
}

.board__total { color: var(--text-dim); font-size: 13px; font-family: var(--font-light); }

/* Compact mode drops the per-stat columns for narrow overlays. */
body[data-compact="1"] .col-stat,
body[data-compact="1"] .cell-stat { display: none; }

/*
 * Docked down one side of the screen the board is tall and narrow, so the stat
 * columns are dropped from the right as space runs out rather than left to
 * scroll off. Rank, player and score always survive - they are the leaderboard;
 * the rest is detail, and the expanded row still shows every figure.
 *
 * These are iframe viewport widths: the widget sees the panel's own width, not
 * the game's.
 */
@media (max-width: 780px) {
	.col-bullets, .cell-bullets { display: none; }
}

@media (max-width: 660px) {
	.col-deaths, .cell-deaths { display: none; }
}

@media (max-width: 540px) {
	.col-creations, .cell-creations { display: none; }
}

@media (max-width: 430px) {
	.col-strikes, .cell-strikes { display: none; }
}

@media (max-width: 340px) {
	.col-time, .cell-time { display: none; }
}

@media (prefers-reduced-motion: no-preference) {
	.row--highlight { animation: flash 1.4s ease-out 1; }
	/* Tint only. Animating the text colour as well left the stat cells briefly
	   unreadable against a saturated fill. */
	@keyframes flash {
		0%, 30% { background: var(--accent-flash); }
		100% { background: var(--accent-soft); }
	}
}
