/* DSEG14 Modern, the segment face the admin console sets its readouts in
   (OFL; fonts/DSEG-LICENSE.txt), for the machine table's scores: a pinball
   score, set the way a machine displays one. Regular only. */
@font-face {
	font-family: 'DSEG14 Modern';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url(../fonts/DSEG14Modern-Regular.woff2) format('woff2'),
	     url(../fonts/DSEG14Modern-Regular.woff) format('woff');
}
@font-face {
	font-family: 'DSEG14 Modern';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url(../fonts/DSEG14Modern-Bold.woff2) format('woff2'),
	     url(../fonts/DSEG14Modern-Bold.woff) format('woff');
}

/* The public player page, player.html (src/player.njk, js/player.js).
 * The tables are the league pages' standings look — each a white card with a
 * red-tinted head, amber for a result the player took — so a name clicked in
 * the standings opens onto the same kind of table. */

.player-eyebrow {
	font-family: var(--ccpl-font-display);
	text-transform: uppercase;
	letter-spacing: 3px;
	font-size: 12px;
	color: var(--ccpl-red);
	margin: 0 0 2px;
}

/* The three bands alternate light, dark, light — the player, then Season
   History, then Machines History — each under a gold rule, so the two
   history sections read as separate rather than one run of tables. Gold,
   the site's amber, not red: red is already the navbar's rule, every
   heading's underline and every link, and a section edge in it read as one
   more of those. The
   player's band is the lighter ground, the other way round from the
   site's usual dark-first rhythm. */
.page-band.player-band,
.page-band.machines-band {
	background-color: var(--ccpl-ground);
}
.page-band.history-band,
.page-band.machines-band {
	border-top: 3px solid rgb(var(--ccpl-amber-rgb));
}
.page-band.machines-band {
	padding-top: 36px;
}

/* The player's own band, kept slim: the name and its line, then the
   career strip, with less air around them than a page band carries. */
.navbar + .page-band.player-band {
	padding-top: calc(var(--ccpl-navbar-offset) + 10px);
	padding-bottom: 16px;
}

/* The name with the IFPA link beside it, on one baseline; the link drops
   under the name only when the two do not fit. */
.player-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 16px;
	margin: 0 0 10px;
}

#playerName {
	font-size: clamp(26px, 3.6vw, 36px);
	line-height: 1;
	margin: 0;
}

.player-meta {
	color: var(--ccpl-muted);
	margin: 0;
}
.player-meta:empty { display: none; }

.player-note {
	color: var(--ccpl-muted);
	margin: 8px 0;
}

/* The tiles at the top of a page's body — the player's career strip, the
   machine's scores, the location's hosting — on the player, machine and
   location pages: the space under them is a section's. Empty while they
   load, and then they take none. */
.band-tiles:not(:empty) {
	margin-bottom: 36px;
}

/* --- the career strip ---------------------------------------------------
 * Three labelled groups — Career, Personal bests, Won — side by side while
 * they fit, and wrapping whole when they do not: a group never breaks across
 * lines. Inside a group the tiles are one row of equal widths. On a phone each
 * group is the full width, its tiles a grid of two. */
.career-stats {
	display: flex;
	flex-wrap: wrap;
	gap: 18px 28px;
}

.stat-group {
	flex: 0 0 auto;
}

.stat-group-title {
	font-family: var(--ccpl-font-display);
	text-transform: uppercase;
	letter-spacing: 2px;
	font-size: 12.5px;
	color: var(--ccpl-muted);
	margin: 0 0 6px;
	padding-bottom: 4px;
	border-bottom: 1px solid var(--ccpl-rule);
}

.stat-row {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(104px, 1fr);
	gap: 8px;
}

@media (max-width: 575.98px) {
	.career-stats { gap: 16px; }
	.stat-group { flex: 1 1 100%; }
	/* Three to a row for a group of three, two for four: never one left
	   on a line of its own. */
	.stat-row {
		grid-auto-flow: row;
		grid-template-columns: 1fr 1fr;
	}
	.stat-row[data-count="1"] { grid-template-columns: 1fr; }
	.stat-row[data-count="3"] { grid-template-columns: 1fr 1fr 1fr; }
	.stat-row[data-count="3"] .stat { padding-left: 10px; padding-right: 10px; }
}

.stat {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	/* Centred, as the admin player page's tiles are: a short value over a
	   short label sat in the left of a wide tile with a void beside it. */
	align-items: center;
	text-align: center;
	padding: 9px 13px 10px;
	background-color: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-radius: 6px;
	box-shadow: 0 1px 2px rgba(var(--ccpl-ink-rgb), .04), 0 4px 12px rgba(var(--ccpl-ink-rgb), .06);
	color: var(--ccpl-text);
	text-decoration: none;
	white-space: nowrap;
}

.stat-value {
	font-family: var(--ccpl-font-display);
	font-weight: 700;
	font-size: 30px;
	line-height: 1.05;
	font-variant-numeric: tabular-nums;
}

.stat-word .stat-value {
	font-size: 22px;
	line-height: 1.4;
}

.stat-unit {
	font-size: .6em;
	margin-left: 1px;
}

/* How many times a best finish happened, beside it: "1st ×7". */
.stat-times {
	font-size: .62em;
	font-weight: 600;
	margin-left: 4px;
	color: var(--ccpl-muted);
}

.stat-label {
	font-size: 13px;
	color: var(--ccpl-muted);
}

/* A mark: the best night and the best season. Red, and a link to the row it
   came from. */
.stat.is-record .stat-value { color: var(--ccpl-red); }

/* A result they took: amber, as the standings mark a high score. */
.stat.is-won {
	background-color: rgba(var(--ccpl-amber-rgb), .18);
	border-color: rgba(var(--ccpl-amber-rgb), .55);
}
.stat.is-won .stat-value { color: var(--ccpl-amber-deep); }

a.stat .stat-label {
	text-decoration: underline;
	text-decoration-color: rgba(var(--ccpl-red-rgb), .45);
	text-underline-offset: 2px;
}

a.stat:hover,
a.stat:focus-visible {
	border-color: var(--ccpl-red);
	color: var(--ccpl-text);
}

/* --- tables, both sections ---------------------------------------------- */
.league-history + .league-history { margin-top: 28px; }

.league-history-head,
.location-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 2px 12px;
	font-size: 22px;
	margin: 0 0 10px;
	color: var(--ccpl-text);
}

.league-history-head small,
.location-head small {
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .3px;
	color: var(--ccpl-muted);
}

.page-band .table-responsive {
	background-color: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-radius: 6px;
	box-shadow: 0 1px 2px rgba(var(--ccpl-ink-rgb), .05), 0 8px 20px rgba(var(--ccpl-ink-rgb), .06);
}

.history-table,
.machine-table {
	--bs-table-striped-bg: rgba(var(--ccpl-ink-rgb), .025);
	margin: 0;
	background-color: var(--ccpl-surface);
	font-variant-numeric: tabular-nums;
}

.history-table th,
.history-table td,
.machine-table th,
.machine-table td {
	white-space: nowrap;
	padding: 6px 10px;
	vertical-align: middle;
}

/* site.css stripes odd rows with a background of its own as well. */
.history-table.table-striped > tbody > tr:nth-child(2n+1),
.machine-table.table-striped > tbody > tr:nth-child(2n+1) {
	background-color: transparent;
}

.history-table > thead > tr > th,
.machine-table > thead > tr > th {
	background-color: rgba(var(--ccpl-red-rgb), .08);
	color: var(--ccpl-red-dark);
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .5px;
	border-bottom: 2px solid rgba(var(--ccpl-red-rgb), .45);
}

.history-table > :not(:first-child),
.machine-table > :not(:first-child) {
	border-top: 0;
}

.history-table > tbody > tr:last-child > *,
.machine-table > tbody > tr:last-child > * {
	border-bottom: 0;
}

.history-table .num,
.machine-table .num {
	text-align: right;
}

/* Season, Finish and Points shrink to their contents and the weekly finishes
   take the rest, so the figures sit beside the season's name rather than
   across a gap the width of the page. */
.history-table th:not(.col-weeks) {
	width: 1%;
}
.history-table .num {
	padding-left: 28px;
}
.history-table .col-weeks,
.history-table > * > tr > :last-child {
	padding-left: 28px;
}

/* A season won: an amber badge, as the weekly finishes mark a night won. A
   best season by points: red. */
.finish-won {
	display: inline-block;
	padding: 0 6px;
	border: 1px solid rgba(var(--ccpl-amber-rgb), .8);
	border-radius: 4px;
	background-color: rgba(var(--ccpl-amber-rgb), .30);
	color: var(--ccpl-amber-deep);
	font-weight: 700;
	line-height: 1.5;
	/* Its padding and border hang past the column's edge, so "1st" lines up
	   with the finishes above and below it. */
	margin-right: -7px;
}
.history-table td.is-record {
	color: var(--ccpl-red);
	font-weight: 700;
}

.season-badge {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 7px;
	border-radius: 999px;
	font-size: 12px;
	background-color: rgba(var(--ccpl-red-rgb), .10);
	color: var(--ccpl-red-dark);
	vertical-align: 1px;
}

/* --- weekly finishes: one chip per week ----------------------------------- */
.week-ranks {
	display: inline-flex;
	flex-wrap: nowrap;
	gap: 4px;
}

.week-rank {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 28px;
	height: 24px;
	padding: 0 5px;
	border: 1px solid var(--ccpl-rule);
	border-radius: 4px;
	background-color: var(--ccpl-surface);
	color: var(--ccpl-text);
	font-family: var(--ccpl-font-display);
	font-weight: 700;
	font-size: 15px;
	text-decoration: none;
	scroll-margin: 40vh 0;
}

/* A played week links to that night on its league page: underlined, and
   red on hover. A missed week is not a link and is not underlined. */
a.week-rank {
	text-decoration: underline;
	text-decoration-color: rgba(var(--ccpl-red-rgb), .5);
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
}
a.week-rank:hover,
a.week-rank:focus-visible {
	border-color: var(--ccpl-red);
	background-color: rgba(var(--ccpl-red-rgb), .08);
	color: var(--ccpl-red);
	text-decoration-color: var(--ccpl-red);
}

.week-rank.won {
	background-color: rgba(var(--ccpl-amber-rgb), .30);
	border-color: rgba(var(--ccpl-amber-rgb), .8);
	color: var(--ccpl-amber-deep);
}

.week-rank.missed {
	color: var(--ccpl-muted);
	background-color: transparent;
	font-weight: 400;
}

.week-rank.pending {
	color: var(--ccpl-muted);
	background-color: transparent;
	border-style: dashed;
	font-weight: 400;
}

/* The best night: a red ring. */
.week-rank.is-record {
	box-shadow: 0 0 0 2px var(--ccpl-red);
}

/* A row or chip jumped to from the career strip: flashed once the scroll
   has stopped (jumpTo, src/player.njk). */
.is-flash,
tr.is-flash > td {
	animation: player-flash 2s ease-out;
}
@keyframes player-flash {
	0%, 30% { background-color: rgba(var(--ccpl-red-rgb), .28); }
}
tr[id^="season-"],
.week-rank { scroll-margin: 40vh 0; }

/* --- machines ------------------------------------------------------------- */
/* The Machines heading with its tools at the right: the section label's
   rule and type, on a row the heading shares with the key, the count and
   the search. On a narrow screen the tools drop under the heading. */
.machines-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 8px 20px;
	border-bottom: 2px solid var(--ccpl-red);
	padding-bottom: 8px;
	margin: 0 0 16px;
}
.machines-head > h2 {
	margin: 0;
	font-size: 22px;
	text-transform: uppercase;
	color: var(--ccpl-text);
}
.machines-toolbar {
	display: flex;
	flex: 0 0 auto;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: flex-end;
	gap: 8px 16px;
}
.machines-toolbar .machine-filter { flex: 0 0 18rem; }
.machines-toolbar[hidden] { display: none; }

/* The search: a white field with its icon inside, the red of the page's
   links around it when focused, and a ✕ at its right to clear it
   (playerFilterClear, js/player.js) — the browser's own ✕ on
   type="search" is hidden, or Chrome and Safari would show a second one. */
.machine-filter input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}
.machine-filter .filter-clear {
	position: absolute;
	top: 50%;
	right: 6px;
	transform: translateY(-50%);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 4px;
	border: 0;
	background: none;
	line-height: 1;
	color: var(--ccpl-muted);
	cursor: pointer;
}
.machine-filter .filter-clear[hidden] { display: none; }
.machine-filter .filter-clear:hover,
.machine-filter .filter-clear:focus-visible {
	color: var(--ccpl-red);
}
/* Room at the right for it, so a long term does not run under it. */
.machine-filter input { padding-right: 32px; }
.machine-filter {
	position: relative;
	flex: 0 1 20rem;
}

.machine-filter-icon {
	position: absolute;
	left: 12px;
	top: 50%;
	transform: translateY(-50%);
	color: var(--ccpl-muted);
	pointer-events: none;
}

.machine-filter input {
	width: 100%;
	height: 38px;
	padding: 0 12px 0 36px;
	border: 1px solid var(--ccpl-rule);
	border-radius: 6px;
	background-color: var(--ccpl-surface);
	color: var(--ccpl-text);
	font-size: 15px;
	box-shadow: inset 0 1px 2px rgba(var(--ccpl-ink-rgb), .05);
}

.machine-filter input::placeholder {
	color: var(--ccpl-muted);
	opacity: .8;
}

.machine-filter input:focus {
	outline: none;
	border-color: var(--ccpl-red);
	box-shadow: 0 0 0 3px rgba(var(--ccpl-red-rgb), .15);
}

.machine-count {
	color: var(--ccpl-muted);
	font-size: 14px;
	white-space: nowrap;
}

/* The Diff column's key, at the right of the toolbar. */
.diff-key {
	display: flex;
	flex-wrap: nowrap;
	white-space: nowrap;
	align-items: center;
	gap: 6px;
	margin: 0;
	font-size: 13px;
}

.location-block + .location-block { margin-top: 24px; }

/* The location in the text colour; its league is the section's heading. */
.location-name {
	color: var(--ccpl-text);
}

/* A location the league no longer plays at, and a machine retired: a small
   grey pill, set apart from the text beside it. */
.status-badge {
	display: inline-block;
	align-self: center;
	padding: 2px 8px;
	border-radius: 999px;
	background-color: rgba(var(--ccpl-ink-rgb), .08);
	border: 1px solid rgba(var(--ccpl-ink-rgb), .12);
	color: var(--ccpl-text);
	font-family: var(--ccpl-font-display);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	line-height: 1.3;
	vertical-align: 1px;
}
td > .status-badge {
	margin-left: 8px;
	padding: 1px 7px;
	font-size: 11px;
}


.machine-table { table-layout: fixed; min-width: 900px; }
.machine-table .col-machine { width: auto; }
.machine-table .col-era { width: 110px; }
.machine-table .col-plays { width: 70px; }
.machine-table .col-score { width: 150px; }
.machine-table .col-diff { width: 104px; }

/* The scores, in the segment face. It runs wide, so a size under the
   table's text keeps a nine-digit score inside its column. */
.machine-table td.score {
	font-family: 'DSEG14 Modern', ui-monospace, monospace;
	font-weight: 700;
	font-size: 12.5px;
	letter-spacing: .02em;
}

/* Diff: centred, head and value, and every badge one width — wide enough
   for +999% with room either side — so the column reads as one line of
   pills rather than a ragged edge against the card. */
.machine-table .diff-col {
	text-align: center;
}
.machine-table .diff-col .diff {
	min-width: 4.4em;
	text-align: center;
	font-variant-numeric: tabular-nums;
}
.machine-table td:first-child {
	overflow: hidden;
	text-overflow: ellipsis;
}

.diff {
	display: inline-block;
	padding: 0 6px;
	border-radius: 4px;
	font-weight: 700;
	white-space: nowrap;
}
.diff.is-above { background-color: rgba(46, 125, 50, .14); color: #1E5E22; }
.diff.is-level { background-color: rgba(var(--ccpl-ink-rgb), .06); color: var(--ccpl-muted); }
.diff.is-below { background-color: rgba(var(--ccpl-red-rgb), .10); color: var(--ccpl-red-dark); }


/* On a phone the search takes the width and the key sits under it, at the
   left with everything else. */
@media (max-width: 991.98px) {
	.machines-toolbar { flex-wrap: wrap; justify-content: flex-start; flex: 1 1 100%; }
	.machines-toolbar .machine-filter { flex: 1 1 100%; }
}

/* --- collapsible sections: a league's seasons, a location's machines -----
 * Each is a <details> whose <summary> holds its heading, with a chevron that
 * turns when it opens. The whole heading line is the target. */
.league-history > summary,
.location-block > summary {
	display: flex;
	align-items: baseline;
	gap: 10px;
	list-style: none;
	cursor: pointer;
	margin-bottom: 10px;
}
.league-history > summary::-webkit-details-marker,
.location-block > summary::-webkit-details-marker {
	display: none;
}
.league-history > summary::before,
.location-block > summary::before {
	content: "";
	flex: none;
	width: 9px;
	height: 9px;
	border-right: 2.5px solid var(--ccpl-red);
	border-bottom: 2.5px solid var(--ccpl-red);
	transform: translateY(-3px) rotate(-45deg);
	transition: transform .15s ease;
}
.league-history[open] > summary::before,
.location-block[open] > summary::before {
	transform: translateY(-5px) rotate(45deg);
}
.league-history > summary .league-history-head,
.location-block > summary .location-head {
	margin: 0;
}
.league-history > summary:hover .league-history-head,
.location-block > summary:hover .location-head,
.location-block > summary:hover .location-name {
	color: var(--ccpl-red);
}
.league-history > summary:focus-visible,
.location-block > summary:focus-visible {
	outline: 2px solid var(--ccpl-red);
	outline-offset: 3px;
	border-radius: 2px;
}
.league-history:not([open]) + .league-history,
.location-block:not([open]) + .location-block {
	margin-top: 14px;
}
@media (prefers-reduced-motion: reduce) {
	.league-history > summary::before,
	.location-block > summary::before { transition: none; }
}

/* site.css underlines every link on hover, which put a second line under
   the value. On a stat only the label's own underline answers. */
a.stat:hover,
a.stat:focus,
a.stat:focus-visible {
	text-decoration: none;
}
a.stat:hover .stat-label,
a.stat:focus-visible .stat-label {
	color: var(--ccpl-red);
	text-decoration-color: var(--ccpl-red);
}

/* --- a league's stats panel ---------------------------------------------
 * Beside the season table on a wide screen, under it on a narrow one. The
 * table keeps its natural width and the panel takes the rest, so neither is
 * a strip of white with the data at one edge. */
.league-body {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 16px;
	align-items: start;
}
@media (min-width: 992px) {
	.league-body {
		grid-template-columns: minmax(0, max-content) minmax(300px, 1fr);
		gap: 24px;
	}
	/* A long career's table runs several screens; the tiles and the panel
	   stay in view beside it rather than being left at the top. */
	.league-side {
		position: sticky;
		top: calc(var(--ccpl-navbar-offset) + 12px);
	}
}

/* The league's stats panel, and the card the machine page's chart sits in
   (css/machines.css): one surface, so the two pages' charts match. */
.league-stats,
.chart-card {
	background-color: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-radius: 6px;
	box-shadow: 0 1px 2px rgba(var(--ccpl-ink-rgb), .05), 0 8px 20px rgba(var(--ccpl-ink-rgb), .06);
	padding: 14px 16px 12px;
}

.league-figures {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
	gap: 12px 16px;
	margin: 0;
}
.league-figures > div {
	border-left: 3px solid rgba(var(--ccpl-red-rgb), .25);
	padding-left: 10px;
}
.league-figures dt {
	font-weight: 400;
	font-size: 13px;
	color: var(--ccpl-muted);
}
.league-figures dd {
	margin: 0;
	font-family: var(--ccpl-font-display);
	font-weight: 700;
	font-size: 24px;
	line-height: 1.15;
	font-variant-numeric: tabular-nums;
}

.finish-chart {
	margin: 16px 0 0;
	padding-top: 12px;
	border-top: 1px solid var(--ccpl-rule);
}
.finish-chart svg {
	display: block;
	width: 100%;
	max-width: 560px;
	height: auto;
	overflow: visible;
}
.finish-chart figcaption {
	font-size: 13px;
	color: var(--ccpl-muted);
	margin-top: 2px;
}
.chart-rule {
	stroke: var(--ccpl-rule);
	stroke-dasharray: 3 3;
}
.chart-axis {
	font-size: 12px;
	fill: var(--ccpl-muted);
}
.chart-line {
	fill: none;
	stroke: var(--ccpl-red);
	stroke-width: 1.75;
	stroke-linejoin: round;
}
.chart-point {
	fill: var(--ccpl-surface);
	stroke: var(--ccpl-red);
	stroke-width: 1.5;
}
.chart-point.won {
	fill: rgb(var(--ccpl-amber-rgb));
	stroke: var(--ccpl-amber-deep);
}

/* A chart's tooltip, over the point hovered, focused or tapped
   (playerChartTips): the player page's finish charts and the machine page's
   scores chart. The targets are invisible circles over the points, a
   finger's width. */
.finish-chart {
	position: relative;
}
.chart-hit {
	fill: transparent;
	cursor: pointer;
}
.chart-hit:focus {
	outline: none;
}
.chart-hit:focus-visible {
	stroke: var(--ccpl-red);
	stroke-width: 1.5;
}
.chart-tip {
	position: absolute;
	z-index: 2;
	min-width: 190px;
	padding: 8px 10px;
	background: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-top: 3px solid var(--ccpl-red);
	border-radius: 6px;
	box-shadow: 0 6px 18px rgba(var(--ccpl-ink-rgb), .16);
	font-size: 13px;
	line-height: 1.3;
	pointer-events: none;
	white-space: nowrap;
}
.chart-tip-head {
	margin: 0 0 6px;
	font-weight: 700;
}
.chart-tip small {
	font-weight: 400;
	color: var(--ccpl-muted);
	margin-left: 4px;
}
.chart-tip dl {
	display: grid;
	grid-template-columns: auto auto;
	gap: 2px 12px;
	margin: 0;
}
.chart-tip dt {
	font-weight: 400;
	color: var(--ccpl-muted);
}
.chart-tip dd {
	margin: 0;
	text-align: right;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}
.chart-tip-foot {
	margin: 6px 0 0;
	color: var(--ccpl-muted);
}
.chart-tip-foot + .chart-tip-foot {
	margin-top: 2px;
}

/* Below 992px the panel is above its table rather than under it, so a
   league's figures are read before its rows. */
@media (max-width: 991.98px) {
	.league-side { order: -1; }
}

/* The summary tiles above the panel, grouped and built as the career
   strip's are (.career-stats): shown only while the league is open and
   fitLeagueTiles (player.njk) has found room for them, and then the line of
   text in the heading goes. */
.league-tiles.career-stats {
	display: none;
	margin-bottom: 14px;
}
.league-history.has-tiles[open] .league-tiles { display: flex; }
.league-history.has-tiles[open] .league-facts { display: none; }

/* --- machine history: a section per league --------------------------------
 * Each league is headed like the season history's leagues, with a gold rule
 * under it, and its locations are the level below: smaller headings,
 * indented under it. */
.machine-league + .machine-league {
	margin-top: 36px;
}
.machine-league[hidden] { display: none; }

.machine-league-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 2px 12px;
	font-size: 24px;
	color: var(--ccpl-text);
	margin: 0 0 14px;
	padding-bottom: 6px;
	border-bottom: 2px solid rgb(var(--ccpl-amber-rgb));
}
.machine-league-head small {
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .3px;
	color: var(--ccpl-muted);
}

.machine-league .location-block {
	margin-left: 14px;
}
.machine-league .location-head {
	font-size: 19px;
}
@media (max-width: 575.98px) {
	.machine-league .location-block { margin-left: 0; }
}

/* --- the first column stays put when a table scrolls sideways ------------
 * The season's name in the season tables, the machine's in the machine
 * tables: on a narrow screen the rest scrolls under it. A pinned cell needs
 * an opaque background or the scrolled cells show through; Bootstrap paints
 * the stripe as an inset box-shadow, which still lands on top of this. The
 * head's red tint is translucent, so it is laid over white as an image. The
 * rule at the pinned edge is a 1px background image too: with collapsed
 * borders the cell's own border belongs to the table and scrolls away, and
 * a pseudo-element is clipped by the machine table's overflow: hidden (its
 * ellipsis), which left the rule on the head and off every row. */
.history-table > * > tr > :first-child,
.machine-table > * > tr > :first-child {
	position: sticky;
	left: 0;
	z-index: 1;
	background-color: var(--ccpl-surface);
}
.history-table > * > tr > :first-child,
.machine-table > * > tr > :first-child {
	background-image: linear-gradient(to left, var(--ccpl-rule) 1px, transparent 1px);
}
.history-table > thead > tr > :first-child,
.machine-table > thead > tr > :first-child {
	z-index: 2;
	background-image: linear-gradient(to left, var(--ccpl-rule) 1px, transparent 1px),
		linear-gradient(rgba(var(--ccpl-red-rgb), .08), rgba(var(--ccpl-red-rgb), .08));
}

/* The link to a location's page (location.html) at the top of an open
   location block, on the player page and the machine index: small, above the
   table, at its right. */
.location-link {
	margin: -4px 0 8px;
	font-size: 14px;
	text-align: right;
}

/* A machine's name, linking to its page (machine.html): in the text colour
   with a faint red underline, red on hover. Here rather than in
   machines.css because the player page's machine tables use it too. */
.machine-link {
	color: var(--ccpl-text);
	text-decoration: underline;
	text-decoration-color: rgba(var(--ccpl-red-rgb), .45);
	text-underline-offset: 2px;
}
.machine-link:hover,
.machine-link:focus-visible {
	color: var(--ccpl-red);
	text-decoration-color: var(--ccpl-red);
}


/* --- guest nights ----------------------------------------------------------
 * The nights played in seasons the player was not registered for, under the
 * season history (renderPlayerGuestNights). A collapsible section like a
 * league's, holding one white card per night under an amber edge: a head of
 * its five facts, each over a small label, on a faint band, then its games as
 * tiles — the machine, the score in the machine table's segment face, and
 * the Diff pill against the league's average. */
#guestNights:not(:empty) { margin-top: 28px; }

.guest-night-list {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.guest-night {
	overflow: hidden;
	background-color: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-left: 4px solid rgb(var(--ccpl-amber-rgb));
	border-radius: 6px;
	box-shadow: 0 1px 2px rgba(var(--ccpl-ink-rgb), .05), 0 8px 20px rgba(var(--ccpl-ink-rgb), .06);
}

.guest-night-head {
	display: grid;
	grid-template-columns: minmax(120px, 1fr) minmax(110px, 1fr) minmax(170px, 1.6fr) 56px minmax(140px, 1.2fr);
	gap: 10px 18px;
	align-items: start;
	padding: 10px 14px;
	background-color: rgba(var(--ccpl-red-rgb), .05);
	border-bottom: 1px solid rgba(var(--ccpl-red-rgb), .2);
}
@media (max-width: 767.98px) {
	.guest-night-head { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
}

.guest-fact {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 3px;
	min-width: 0;
}

.guest-label {
	font-family: var(--ccpl-font-display);
	font-size: 12px;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--ccpl-red-dark);
}

.guest-value { font-weight: 600; color: var(--ccpl-text); }
a.guest-value { color: var(--ccpl-red); }

.guest-fact .week-ranks { margin: 0; }

.guest-games {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
	gap: 8px;
	margin: 0;
	padding: 12px 14px 14px;
	list-style: none;
}

.guest-game {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
	padding: 8px 10px;
	border: 1px solid var(--ccpl-rule);
	border-radius: 5px;
	background-color: rgba(var(--ccpl-ink-rgb), .02);
}

.guest-game > a {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-weight: 600;
}

.guest-score {
	display: flex;
	align-items: center;
	gap: 8px;
}

.guest-points {
	font-family: 'DSEG14 Modern', ui-monospace, monospace;
	font-weight: 700;
	font-size: 12.5px;
	letter-spacing: .02em;
	color: var(--ccpl-text);
}

.guest-score .diff { font-size: 13px; }

/* --- IFPA ------------------------------------------------------------------
 * The fourth band, after Machines History and on the history band's ground,
 * under the same gold rule: the IFPA's figures in the career strip's tiles,
 * the world rank as a chart in the league's stats card, and two tables in
 * the machine table's look — head-to-head with league players, and the
 * events counting now. */
.page-band.ifpa-band {
	border-top: 3px solid rgb(var(--ccpl-amber-rgb));
	/* The header's "IFPA #…" scrolls here; clear of the fixed navbar. */
	scroll-margin-top: var(--ccpl-navbar-offset);
}

.ifpa-profile {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .3px;
}

/* The band's head: the heading with the profile's flags beside it, and the
   Matchplay and IFPA links at the right. */
.ifpa-title,
.ifpa-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 18px;
}
.ifpa-title { gap: 6px 12px; }
/* The heading is inside .ifpa-title, not a child of .machines-head, so it
   takes .machines-head > h2's look here — without it, the browser's margin
   under an h2 stood between the text and the rule. */
.ifpa-title > h2 {
	margin: 0;
	font-size: 22px;
	text-transform: uppercase;
	color: var(--ccpl-text);
}
.ifpa-flags {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 6px;
}
.ifpa-flag.is-warn {
	background-color: rgba(var(--ccpl-red-rgb), .10);
	border-color: rgba(var(--ccpl-red-rgb), .45);
	color: var(--ccpl-red-dark);
}

.ifpa-stats { margin-bottom: 8px; align-items: stretch; }

/* THE IFPA TILES LINE UP ACROSS A LINE. Some carry a second line and some do
   not, so tiles bottom-aligned as the career strip's are put their values at
   different heights. Here every group on a line stretches to the tallest,
   every tile to its group, and each tile's value starts at the top. */
.ifpa-stats .stat-group {
	display: flex;
	flex-direction: column;
}
.ifpa-stats .stat-row { flex: 1 1 auto; }
.ifpa-stats .stat { justify-content: flex-start; }

/* A line break in the IFPA tiles before Finishes, at the widest breakpoint
   only: there rank, points and events fill a line and finishes would too,
   leaving the state series alone on the next. Narrower, the groups wrap as
   they fit. The break is a line of its own, which would take a row gap on
   each side, so there the gap goes and the second line's groups carry it. */
.ifpa-stats .stat-break { display: none; }
@media (min-width: 1200px) {
	.ifpa-stats { row-gap: 0; }
	.ifpa-stats .stat-break {
		display: block;
		flex: 0 0 100%;
		height: 0;
	}
	.ifpa-stats .stat-break ~ .stat-group { margin-top: 18px; }
}
.stat.is-ifpa .stat-value { color: var(--ccpl-red); }

/* An IFPA tile's one line, green or red for the year's movement under the
   current rank. */
.stat-label.is-up { color: #1E5E22; font-weight: 600; }
.stat-label.is-down { color: var(--ccpl-red-dark); font-weight: 600; }

/* AN IFPA TILE'S TOOLTIP (renderPlayerStatTip()): the charts' tooltip — white,
   under a red rule — below the tile, shown AT ONCE on hover or keyboard
   focus rather than after a title's delay. A tile is one value and one
   line; this is where the rest goes. Over the tiles below, so the tile is
   lifted while it shows. Centred on the tile, but held to the row's edge
   by the first and last tiles, or it would leave the page on a phone. A
   tile that has one says so with a small ⓘ in its top right corner. */
.ifpa-stats .stat.has-tip { position: relative; cursor: help; }
.ifpa-stats .stat.has-tip:hover,
.ifpa-stats .stat.has-tip:focus-visible { z-index: 5; }
.ifpa-stats .stat.has-tip:focus-visible { outline: 2px solid var(--ccpl-red); outline-offset: 2px; }
.ifpa-stats .stat.has-tip::after {
	content: "i";
	position: absolute;
	top: 4px;
	right: 4px;
	width: 12px;
	height: 12px;
	border: 1.25px solid currentColor;
	border-radius: 50%;
	font: italic 700 8.5px/9.5px Georgia, serif;
	text-align: center;
	color: var(--ccpl-muted);
	opacity: .7;
}
.ifpa-stats .stat.has-tip:hover::after,
.ifpa-stats .stat.has-tip:focus-visible::after { color: var(--ccpl-red); opacity: 1; }
.stat-tip {
	position: absolute;
	top: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	z-index: 5;
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 180px;
	max-width: 260px;
	padding: 8px 10px;
	background: var(--ccpl-surface);
	border: 1px solid var(--ccpl-rule);
	border-top: 3px solid var(--ccpl-red);
	border-radius: 6px;
	box-shadow: 0 6px 18px rgba(var(--ccpl-ink-rgb), .16);
	font-size: 13px;
	line-height: 1.3;
	text-align: left;
	white-space: normal;
	color: var(--ccpl-text);
	visibility: hidden;
	opacity: 0;
	pointer-events: none;
}
.stat-row > .stat:first-child .stat-tip { left: 0; transform: none; }
.stat-row > .stat:last-child:not(:first-child) .stat-tip { left: auto; right: 0; transform: none; }
.ifpa-stats .stat:hover .stat-tip,
.ifpa-stats .stat:focus-visible .stat-tip { visibility: visible; opacity: 1; }
.stat-tip-head { font-weight: 700; }
.stat-tip-row {
	display: flex;
	justify-content: space-between;
	gap: 14px;
}
.stat-tip-row > :first-child { color: var(--ccpl-muted); }
.stat-tip-row > :last-child { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stat-tip-note { color: var(--ccpl-muted); }

.ifpa-sub {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 2px 12px;
	font-size: 20px;
	margin: 28px 0 10px;
	color: var(--ccpl-text);
}
.ifpa-sub small {
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .3px;
	color: var(--ccpl-muted);
}

/* The rank chart in the stats card's surface, at the full width: a career
   of monthly ranks wants more room than a league's finishes. */
#ifpaChart .ifpa-chart {
	margin: 0;
	padding: 14px 16px 10px;
	border: 1px solid var(--ccpl-rule);
	border-radius: 6px;
	background-color: var(--ccpl-surface);
	box-shadow: 0 1px 2px rgba(var(--ccpl-ink-rgb), .05), 0 8px 20px rgba(var(--ccpl-ink-rgb), .06);
}
#ifpaChart .ifpa-chart svg { max-width: none; width: auto; }

/* The rating, a second line on its own scale at the right: amber, the
   site's other accent, thinner than the rank's red so the rank stays the
   chart's subject; its axis text and its swatch in the key amber too. */
#ifpaChart .chart-rating {
	fill: none;
	stroke: rgb(var(--ccpl-amber-rgb));
	stroke-width: 1.5;
	stroke-linejoin: round;
}
#ifpaChart .chart-axis.is-rating { fill: var(--ccpl-amber-deep); }
#ifpaChart .chart-key {
	display: flex;
	gap: 18px;
	margin: 0 0 6px;
	font-size: 13px;
	color: var(--ccpl-muted);
}
#ifpaChart .chart-key span::before {
	content: "";
	display: inline-block;
	width: 16px;
	height: 2px;
	margin-right: 6px;
	vertical-align: middle;
	background: var(--ccpl-red);
}
#ifpaChart .chart-key .is-rating::before { background: rgb(var(--ccpl-amber-rgb)); }

/* Events counting now: the original points muted beside the current ones,
   which are what count, and the country of an event abroad. */
.ifpa-table .ifpa-original { color: var(--ccpl-muted); }

.ifpa-tables .ifpa-sub { margin-top: 28px; }

/* The IFPA's tables: the machine table's card and head, at their contents'
   width rather than its fixed columns. */
.ifpa-table {
	--bs-table-striped-bg: rgba(var(--ccpl-ink-rgb), .025);
	margin: 0;
	background-color: var(--ccpl-surface);
	font-variant-numeric: tabular-nums;
}
.ifpa-table th,
.ifpa-table td {
	white-space: nowrap;
	padding: 6px 10px;
	vertical-align: middle;
}
.ifpa-table.table-striped > tbody > tr:nth-child(2n+1) { background-color: transparent; }
.ifpa-table > thead > tr > th {
	background-color: rgba(var(--ccpl-red-rgb), .08);
	color: var(--ccpl-red-dark);
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .5px;
	border-bottom: 2px solid rgba(var(--ccpl-red-rgb), .45);
}
.ifpa-table > :not(:first-child) { border-top: 0; }
.ifpa-table > tbody > tr:last-child > * { border-bottom: 0; }
.ifpa-table .num { text-align: right; }

/* The sort, on tablesorter's classes, as the location page's: a faint ↕ on a
   sortable heading, ▲ or ▼ on the one sorted by. */
.ifpa-table thead .tablesorter-header { cursor: pointer; }
.ifpa-table thead .tablesorter-header:focus-visible {
	outline: 2px solid var(--ccpl-red);
	outline-offset: -2px;
}
.ifpa-table thead .tablesorter-header-inner::after {
	content: "\2195";
	margin-left: .35em;
	opacity: .35;
}
.ifpa-table thead .tablesorter-headerAsc .tablesorter-header-inner::after {
	content: "\25B2";
	opacity: 1;
}
.ifpa-table thead .tablesorter-headerDesc .tablesorter-header-inner::after {
	content: "\25BC";
	opacity: 1;
}

.ifpa-show-all {
	margin-top: 10px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--ccpl-red);
	font-family: var(--ccpl-font-display);
	font-size: 15px;
	letter-spacing: .3px;
	text-decoration: underline;
	text-decoration-color: rgba(var(--ccpl-red-rgb), .45);
	text-underline-offset: 3px;
}

/* An event's row is one line, like head-to-head's, so fifteen of each end
   level: a long name ends in an ellipsis. */
.ifpa-table td.ifpa-event {
	max-width: 0;
	width: 100%;
	min-width: 160px;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ifpa-table td.ifpa-event small {
	color: var(--ccpl-muted);
}

/* The gold 1st in the events table takes no more height than a line of text,
   or its rows stand taller than head-to-head's and the tables end apart. */
.ifpa-table .finish-won {
	line-height: 1.25;
}

/* --- IFPA dialogs ----------------------------------------------------------
 * A head-to-head row's Games opens the two players' events together; the
 * state series tile opens its player card. Both in #ifpaDialog. */
.ifpa-pair {
	padding: 0;
	border: 0;
	background: none;
	color: var(--ccpl-red);
	font: inherit;
	text-decoration: underline;
	text-decoration-color: rgba(var(--ccpl-red-rgb), .45);
	text-underline-offset: 3px;
	cursor: pointer;
}
.ifpa-pair:hover,
.ifpa-pair:focus-visible { text-decoration-color: var(--ccpl-red); }

.ifpa-stats .stat.ifpa-card-open { cursor: pointer; }
.ifpa-stats .stat.ifpa-card-open:hover { border-color: rgba(var(--ccpl-red-rgb), .45); }

.ifpa-dialog .modal-header { border-bottom: 2px solid var(--ccpl-red); }
.ifpa-dialog .modal-title {
	margin: 0;
	font-size: 20px;
	text-transform: uppercase;
	color: var(--ccpl-text);
}
.ifpa-dialog-sum {
	margin: 0 0 10px;
	color: var(--ccpl-muted);
}
.ifpa-dialog-year {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 10px;
	font-weight: 600;
}
.ifpa-dialog-year select {
	padding: 2px 6px;
	border: 1px solid var(--ccpl-rule);
	border-radius: 4px;
	background: var(--ccpl-surface);
}
.ifpa-dialog .table-responsive { box-shadow: none; }
