/* ==========================================================================
   The Universal Blind Café — Stylesheet
   ==========================================================================

   One file, four parts:
     1. Tokens      — every colour and measurement, named
     2. Base        — reset, typography, buttons, controls, surfaces, panel
     3. Page scopes — the handful of rules that differ between the main site
                      (body.page-main) and the game pages (body.page-game)
     4. Themes      — blocks that redefine tokens, nothing else

   HOW THEMING WORKS
   A theme is only a list of variables. No component rule mentions a theme and
   nothing uses !important. The theme class is set on <html> by site.js, the
   same element :root matches, so a theme block and :root have equal
   specificity and the theme wins by coming later — hence themes last.

   Adding a theme = adding one variable block. Nothing else.

   ON BORDERS
   The default theme is the one meant to look good: its gradients separate
   panels from the page, so --panel-border-width is 0 and no border is drawn.
   Every other theme is a flat single-colour fill where a panel would be
   invisible against the page, so each sets a real border width. That is why
   borders appear "garish" only outside the default — it is the flat fills
   that need the outline, not the gradients.
   ========================================================================== */


/* ==========================================================================
   1. Tokens — default (dark) theme
   ========================================================================== */

:root {
	/* Page and panels */
	--page-bg: linear-gradient(112deg, rgba(35, 35, 35, 1) 0%, rgba(20, 20, 20, 1) 100%);
	--panel-bg: linear-gradient(112deg, rgba(90, 25, 25, 1) 0%, rgba(65, 15, 15, 1) 100%);
	--panel-solid-bg: #262626;
	--panel-border: transparent;
	--panel-border-width: 0px;

	/* Text */
	--color-text: #ffffff;
	--color-text-muted: rgba(255, 255, 255, 0.72);

	/* Links */
	--color-link: #ffaaaa;
	--color-link-hover: #ff6666;

	/* Buttons */
	--btn-bg: linear-gradient(180deg, #ffffff 0%, #e9e6e6 100%);
	--btn-fg: #1a1313;
	--btn-border: rgba(0, 0, 0, 0.2);
	--btn-border-width: 1px;
	--btn-hover-bg: linear-gradient(180deg, #ffd4d4 0%, #ffaaaa 100%);
	--btn-hover-fg: #1a1313;
	--btn-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 2px 6px rgba(0, 0, 0, 0.25);

	/* Form controls */
	--control-bg: #ffffff;
	--control-fg: #14100f;
	--control-border: rgba(255, 255, 255, 0.16);
	--control-border-width: 1px;

	/* Footer */
	--footer-bg: rgba(45, 15, 15, 0.85);
	--footer-fg: #dddddd;

	--color-focus: #ff6666;

	/* Status colours, softened from pure RGB so they sit in the palette while
	   still clearing WCAG AA against the dark background. */
	--color-correct: #4ade80;
	--color-active: #fde047;

	--surface-1: rgba(255, 255, 255, 0.06);
	--surface-2: rgba(255, 255, 255, 0.10);
	--border-subtle: rgba(255, 255, 255, 0.16);

	/* Text scale. site.js changes only this number; the body sizes off it, so
	   one value rescales the whole site. It must not go on the root font size:
	   the space tokens are in rem, so scaling the root would inflate padding
	   and gaps at the same rate and the layout would grow instead of the
	   words getting bigger inside it. */
	--text-scale: 1;
	--font-size-base: 150%;

	/* Type scale.
	   Every font-size in this file uses one of these seven steps — no loose
	   em values, no stray px. Sizes are in em so they ride the --text-scale
	   setting; rem would be pinned to the root font size and would ignore it.
	   The steps descend by role, and the ordering is the point: a heading is
	   always larger than body text, and body text is always larger than the
	   interface chrome around it. Before this, h3 rendered *smaller* than the
	   paragraphs it introduced and h2 was within a hair of them.

	   at --text-scale 1, body = 24px
	     --fs-h1     1.6em    38px   page title
	     --fs-h2     1.3em    31px   section heading, question, timer
	     --fs-h3     1.12em   27px   sub-heading
	     --fs-body   1em      24px   prose, choices, team rows
	     --fs-label  0.9em    22px   labels, legends, group headings
	     --fs-ui     0.8em    19px   buttons, inputs, dropdowns, values
	     --fs-small  0.7em    17px   footer, captions, fine print

	   --fs-label sits one step above --fs-ui on purpose: a label names the
	   control beneath it, so it should read as the senior of the pair. At
	   equal size the control wins the eye anyway, because a filled input box
	   is heavier than the words next to it.                                */
	--fs-h1: 1.6em;
	--fs-h2: 1.3em;
	--fs-h3: 1.12em;
	--fs-body: 1em;
	--fs-label: 0.9em;
	--fs-ui: 0.8em;
	--fs-small: 0.7em;

	--radius-sm: 6px;
	--radius-md: 10px;
	--radius-lg: 16px;

	--shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.25);
	--shadow-md: 0 6px 18px rgba(0, 0, 0, 0.3);

	--space-1: 0.5rem;
	--space-2: 1rem;
	--space-3: 1.5rem;
	--space-4: 2rem;
	--space-5: 3rem;

	/* System stack: renders in the reader's own OS font, which respects their
	   font smoothing and any OS-level font substitution. */
	--font-sans: system-ui, -apple-system, "Segoe UI", Roboto,
		"Helvetica Neue", Arial, sans-serif;
}


/* ==========================================================================
   2. Base
   ========================================================================== */

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

html {
	min-height: 100%;
	background: var(--page-bg);
}

body {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	/* The settings button and panel are positioned against the body, so they
	   sit at the corners of the page content rather than the raw viewport. */
	position: relative;
	margin: 0;
	background: transparent;
	color: var(--color-text);
	font-family: var(--font-sans);
	font-size: calc(var(--font-size-base) * var(--text-scale));
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

a {
	color: var(--color-link);
	transition: color .2s ease;
}

a:hover,
a:focus-visible {
	color: var(--color-link-hover);
}

h1 {
	margin: 0 0 var(--space-2);
	color: var(--color-text);
	font-size: var(--fs-h1);
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.15;
	text-align: center;
}

h2 {
	margin: 0 0 var(--space-2);
	font-size: var(--fs-h2);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.25;
}

h3 {
	margin: 0 0 var(--space-1);
	font-size: var(--fs-h3);
	font-weight: 600;
	color: var(--color-text-muted);
}

p {
	margin: 0 0 var(--space-2);
}

p:last-child {
	margin-bottom: 0;
}

.fill-space {
	flex: 1;
}


/* --- Focus and screen-reader helpers ----------------------------------- */

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

/* Off-screen until focused, then it drops into the top-left corner. Gives
   keyboard users one Tab press to jump past the header into the content. */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 1100;
	padding: var(--space-1) var(--space-2);
	background: var(--color-text);
	color: var(--panel-solid-bg);
	border-radius: 0 0 var(--radius-sm) 0;
	font-size: var(--fs-small);
	text-decoration: none;
}

.skip-link:focus {
	left: 0;
}

/* The shared page pieces are custom tags (site.js, scoreboard.js); they lay
   out exactly like the divs they replaced. */
site-settings,
site-header,
site-footer,
cafe-scoreboard {
	display: block;
}

/* Hidden visually, still announced by screen readers. Carries the live region
   that reads out accessibility setting changes. */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}


/* --- Surfaces -----------------------------------------------------------
   Every raised or grouped box gets the same border treatment: invisible in
   the default theme, a real outline in every other. Listed together so a box
   can never be forgotten and drift out of step with the rest. */

.normalsection,
.gamesection,
.podcastsection,
#accessibility-panel,
fieldset,
#question-container:has(#question:not(:empty)),
#answer:not(:empty),
#timer:not(:empty),
.team-card {
	border: var(--panel-border-width) solid var(--panel-border);
	border-radius: var(--radius-lg);
}

/* The panel, fieldset and team cards keep a hairline even in the default
   theme, where they sit on the page rather than on a gradient of their own. */
#accessibility-panel,
fieldset,
.team-card {
	border-width: max(1px, var(--panel-border-width));
	border-color: var(--panel-border, var(--border-subtle));
}


/* --- Buttons ------------------------------------------------------------
   `.button-link` is an <a> that navigates but is styled as a button, so a
   link stays a link for screen readers, middle-click and "open in new tab".
   Minimum 44px tall to clear the WCAG target-size guidance. */

button,
.button-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-1);
	min-height: 44px;
	padding: 0 var(--space-3);
	margin: 0;
	background: var(--btn-bg);
	color: var(--btn-fg);
	border: var(--btn-border-width) solid var(--btn-border);
	border-radius: 999px;
	box-shadow: var(--btn-shadow);
	font-family: inherit;
	font-size: var(--fs-ui);
	font-weight: 600;
	line-height: 1.1;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background .2s ease, color .2s ease, border-color .2s ease,
		transform .12s ease, box-shadow .2s ease;
}

button:hover,
button:focus-visible,
.button-link:hover,
.button-link:focus-visible {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
	box-shadow: var(--btn-shadow), var(--shadow-md);
	transform: translateY(-1px);
}

button:active,
.button-link:active {
	transform: translateY(0);
	box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.22);
}

/* `display: inline-flex` above outranks the browser's [hidden] rule, so the
   attribute needs restating here or `hidden` silently does nothing. */
button[hidden],
.button-link[hidden] {
	display: none;
}

button[disabled] {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
	box-shadow: none;
}

.button-container {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: stretch;
	gap: var(--space-2);
	margin: var(--space-2) 0;
	padding: 0;
	list-style: none;
}

.button-container li {
	margin: 0;
	display: flex;
}


/* --- Form controls ----------------------------------------------------- */

select,
input,
textarea {
	background: var(--control-bg);
	color: var(--control-fg);
	border: var(--control-border-width) solid var(--control-border);
	border-radius: var(--radius-md);
	font-family: inherit;
}

/* A locked field (the repeater disables its inputs while running). The
   browser default greys these out with its own colours, which lands wrong on
   every theme. Deriving the fill from the theme's own control colours keeps
   it in palette, and the dashed border signals "locked" without relying on
   colour alone. -webkit-text-fill-color is needed because Safari and Chrome
   otherwise override `color` on a disabled control. */
select:disabled,
input:disabled,
textarea:disabled {
	/* A locked field has to be obvious at a glance, and a flat tint was far
	   too quiet on every theme. The diagonal hatch reads as "unavailable"
	   immediately, is built from a neutral translucent overlay so it works
	   over any theme's control colour, and carries the state without relying
	   on colour alone. The thick dashed edge is the second, redundant cue. */
	background-color: var(--control-bg);
	background-image: repeating-linear-gradient(45deg,
		rgba(125, 125, 125, 0.45) 0 9px,
		rgba(125, 125, 125, 0.12) 9px 18px);
	color: var(--control-fg);
	-webkit-text-fill-color: var(--control-fg);
	border-color: var(--control-fg);
	border-style: dashed;
	border-width: max(3px, var(--control-border-width));
	opacity: 1;
	cursor: not-allowed;
}


/* --- Accessibility settings panel --------------------------------------
   Injected into every page by assets/scripts/site.js. */

#accessibility-button {
	position: absolute;
	top: var(--space-2);
	right: var(--space-2);
	z-index: 1001;
}

/* The gear is decorative (aria-hidden) — the visible "Settings" word is the
   button's accessible name. An icon-only control would be a downgrade for
   low-vision members, so the label stays. */
.gear-icon {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	transition: transform .25s ease;
}

#accessibility-button.is-open {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
}

#accessibility-button.is-open .gear-icon {
	transform: rotate(60deg);
}

.button-label {
	line-height: 1;
}

#accessibility-panel {
	position: absolute;
	top: 80px;
	right: var(--space-2);
	z-index: 1000;
	display: none;
	max-width: 320px;
	padding: var(--space-3);
	background: var(--panel-solid-bg);
	color: var(--color-text);
	box-shadow: var(--shadow-md);
	text-align: left;
}

.panel-heading {
	display: block;
	padding: var(--space-1) 0;
	font-size: var(--fs-label);
	font-weight: 700;
	color: var(--color-text-muted);
}

.text-size-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-1);
	margin-bottom: var(--space-2);
}

/* Single-glyph buttons stay circular rather than being stretched into
   lozenges by the pill radius. */
.text-size-controls button {
	width: 44px;
	padding: 0;
	/* One glyph in a 44px circle: sized up so the +/- stay easy to read. */
	font-size: var(--fs-h3);
}

/* The current value sits beside the +/- buttons and is interface chrome, not
   content — it was inheriting body size and rendering larger than the
   "Text Size" heading above it. */
#text-size-label {
	font-size: var(--fs-ui);
}

.theme-picker {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-1);
	margin-top: var(--space-2);
}

.theme-picker label {
	display: inline;
	padding: 0;
	font-size: var(--fs-label);
	font-weight: bold;
	flex-shrink: 0;
}

#theme-select {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 100%;
	padding: var(--space-1);
	font-size: var(--fs-ui);
	border-radius: var(--radius-sm);
}

/* Best-effort theming of the dropdown's own options so the open menu matches
   the active theme. Firefox and most Chromium browsers honour this; Safari's
   native picker ignores it and falls back to the OS appearance. */
#theme-select option,
#theme-select optgroup {
	background-color: var(--control-bg);
	color: var(--control-fg);
}

.reset {
	margin-top: var(--space-1);
	text-align: center;
}


/* --- Footer ------------------------------------------------------------- */

footer {
	padding: var(--space-2);
	background: var(--footer-bg);
	color: var(--footer-fg);
	text-align: center;
}

footer p {
	margin: 0;
}


/* --- Reduced motion -----------------------------------------------------
   Honours the operating system setting. Vestibular triggers are an
   accessibility need, not a preference. */

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


/* ==========================================================================
   3a. Main site pages   (body.page-main)
   ========================================================================== */

.page-main {
	padding: var(--space-3);
}

.page-main a {
	text-decoration: none;
}

.page-main li {
	margin: var(--space-1) 0 var(--space-2);
}

/* List links are underlined, but a button-styled link is not a text link. */
.page-main li a:not(.button-link) {
	text-decoration: underline;
}

.page-main label {
	display: block;
	padding: var(--space-1) 0;
	font-size: var(--fs-label);
	font-weight: bold;
}

.page-main input {
	padding: var(--space-1);
	margin-bottom: var(--space-2);
	font-size: var(--fs-ui);
}

.page-main input:not([type="checkbox"]) {
	display: block;
}

.page-main footer {
	margin-top: var(--space-4);
	border-radius: var(--radius-md);
	font-size: var(--fs-small);
}

/* Header. The logo and settings button are absolutely positioned against the
   body, so they sit at the corners of the page content rather than the raw
   viewport, and stay put regardless of page length. */

.header-logo-link {
	position: absolute;
	top: var(--space-2);
	left: var(--space-2);
	z-index: 1001;
	display: inline-block;
	border-radius: var(--radius-md);
}

.header-logo {
	display: block;
	width: 70px;
	height: 70px;
}

.header-title {
	display: flex;
	justify-content: center;
}

.header-title a {
	display: inline-block;
	text-decoration: none;
}

/* The banner is a white-background image; without an edge it dissolves into
   the page on the light themes. */
.image-banner {
	display: block;
	width: 100%;
	max-width: 420px;
	height: auto;
	margin: 0 auto var(--space-1);
	border: var(--panel-border-width) solid var(--panel-border);
}

nav {
	text-align: center;
}

nav a {
	display: inline-block;
	margin: 0 var(--space-2);
	color: var(--color-text);
	text-decoration: none;
	transition: color .2s ease;
}

nav a:hover {
	color: var(--color-link-hover);
}

.nav-section {
	margin: 0 auto var(--space-3);
	max-width: 40%;
}

.normalsection,
.gamesection,
.podcastsection {
	display: block;
	padding: var(--space-3);
	margin-bottom: var(--space-3);
	background: var(--panel-bg);
	box-shadow: var(--shadow-md);
	color: var(--color-text);
}

.gamesection h2,
.gamesection h3,
.podcastsection h2 {
	text-align: center;
}

.expandedsection {
	display: block;
	flex: 1;
	margin-top: var(--space-2);
}

section h2 {
	color: var(--color-text);
	text-align: left;
}

/* Link panels (Join Us / Our Affiliates / Resources). Three cards side by
   side, each a vertical bar-list of links (small icon + label). */

.link-panels {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--space-3);
	margin-bottom: var(--space-3);
}

.link-panel {
	flex: 1 1 240px;
	margin-bottom: 0;
}

.link-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	list-style: none;
	margin: 0;
	padding: 0;
}

.link-list li {
	margin: 0;
}

.link-list a {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	min-height: 44px;
	padding: var(--space-1) var(--space-2);
	border-radius: var(--radius-sm);
	text-decoration: none;
	transition: background-color .2s ease, transform .2s ease;
}

.link-list a:hover,
.link-list a:focus-visible {
	background-color: var(--surface-2);
	transform: translateX(3px);
}

.external-links {
	font-size: var(--fs-ui);
	line-height: 1.3;
	margin: 0;
}

.link-list .external-links {
	text-align: left;
	font-size: var(--fs-body);
}

/* Every icon renders in the same size box, regardless of its native aspect
   ratio, so labels line up beside them consistently. */
.social-icon,
.affiliate-logo,
.resource-logo {
	display: block;
	object-fit: contain;
	flex-shrink: 0;
}

.social-icon {
	width: 28px;
	height: 28px;
}

.affiliate-logo,
.resource-logo {
	width: 32px;
	height: 32px;
}

.podcastcontainer {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-3);
	margin-top: var(--space-1);
	text-align: center;
}

.podcastcontainer div {
	flex: 0 1 200px;
}

.podcastcontainer .external-links {
	text-align: center;
}

.podcast-artwork {
	display: block;
	width: 100%;
	max-width: 200px;
	height: auto;
	margin: 0 auto var(--space-1);
}


/* ==========================================================================
   3b. Game pages   (body.page-game)
   ========================================================================== */

.page-game {
	text-align: center;
}

.page-game a {
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.page-game label {
	display: inline-block;
	padding: var(--space-1) 0;
	font-size: var(--fs-label);
	font-weight: 600;
}

.page-game input,
.page-game select,
.page-game textarea {
	max-width: 100%;
	padding: var(--space-1) var(--space-2);
	font-size: var(--fs-ui);
	line-height: 1.4;
}

.page-game footer {
	margin-top: auto;
	font-size: var(--fs-small);
}

.container {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	width: 100%;
	max-width: 60rem;
	margin: 0 auto;
	/* Top padding clears the absolutely-positioned settings button. */
	padding: 5rem var(--space-3) var(--space-5);
}

/* Nothing may exceed the viewport; a wide child scrolls inside its own box
   rather than stretching the document. */
.page-game > *,
.container > * {
	max-width: 100%;
}

fieldset {
	width: 100%;
	max-width: 34rem;
	margin: 0;
	padding: var(--space-4) var(--space-4) var(--space-3);
	background: var(--surface-1);
	text-align: center;
}

/* A <legend> renders inside the fieldset's top border by default, cutting a
   notch in it. Floating it drops it out of that slot and makes it an ordinary
   full-width block at the top of the panel, so the border stays unbroken and
   the label reads as a heading. It stays a <legend>, so it is still the
   group's accessible name. */
legend {
	float: left;
	width: 100%;
	margin: 0 0 var(--space-3);
	padding: 0 0 var(--space-2);
	border-bottom: 1px solid var(--border-subtle);
	font-size: var(--fs-label);
	font-weight: 600;
	color: var(--color-text-muted);
	text-align: center;
}

legend + * {
	clear: both;
}

/* Shrink-wraps to its widest row, then centres as a block, so the rows keep a
   shared left edge instead of each centring independently into a ragged
   column. max-width stops the longest label pushing it wider than the page. */
.radio-group {
	display: inline-block;
	max-width: 100%;
	margin-bottom: var(--space-3);
	text-align: left;
}

/* Radio and checkbox rows read as one line, and the whole row is clickable
   because each label is tied to its input by `for`. Scoped with :has() so a
   plain wrapper div (a heading above a <select>, say) keeps stacking. */
fieldset div:has(> input[type="radio"]),
fieldset div:has(> input[type="checkbox"]) {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin-bottom: var(--space-2);
}

/* A flex item will not shrink below its content width unless min-width is
   cleared, which would let the longest label force a horizontal scroll. */
fieldset div:has(> input[type="radio"]) label,
fieldset div:has(> input[type="checkbox"]) label {
	min-width: 0;
}

fieldset > div {
	margin-bottom: var(--space-2);
	text-align: center;
}

fieldset > div:last-child {
	margin-bottom: 0;
}

fieldset input[type="radio"],
fieldset input[type="checkbox"] {
	width: 1.1em;
	height: 1.1em;
	min-height: 0;
	margin: 0;
	accent-color: var(--control-fg);
	flex-shrink: 0;
}

.page-game fieldset label {
	padding: 0;
	font-weight: 500;
}

select,
input[type="number"],
input[type="text"] {
	min-height: 44px;
}

textarea {
	width: min(100%, 34rem);
	min-height: 6rem;
	resize: vertical;
}

/* Keeps a label welded to its own control. Without this each one is a
   separate flex item in .container and the column gap pushes them apart. */
.field {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-1);
	width: min(100%, 34rem);
}

.page-game .field label {
	padding: 0;
}

/* --- Multi-select picker (Trivia categories) -----------------------------
   A button that opens a checkbox list. The toggle borrows the form-control
   look rather than the pill button, so it reads as "a dropdown" beside the
   <select> above it. */

.category-picker {
	margin-top: var(--space-3);
}

.picker-toggle,
.picker-toggle:hover,
.picker-toggle:focus-visible,
.picker-toggle:active {
	justify-content: space-between;
	width: min(100%, 24rem);
	padding: var(--space-1) var(--space-2);
	background: var(--control-bg);
	color: var(--control-fg);
	border: var(--control-border-width) solid var(--control-border);
	border-radius: var(--radius-md);
	box-shadow: none;
	font-weight: 500;
	line-height: 1.4;
	text-align: left;
	transform: none;
}

.picker-toggle::after {
	content: "\25BE";
	flex-shrink: 0;
}

.picker-toggle[aria-expanded="true"]::after {
	content: "\25B4";
}

.picker-panel {
	width: min(100%, 30rem);
	margin: var(--space-2) auto 0;
	padding: var(--space-2);
	background: var(--panel-solid-bg);
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
	border-radius: var(--radius-md);
	box-shadow: var(--shadow-md);
}

.picker-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-1);
	margin-bottom: var(--space-2);
}

/* Two columns where there is room; one on a phone. */
.picker-options {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
	gap: 0 var(--space-2);
	text-align: left;
}

.picker-options > div {
	margin-bottom: var(--space-1);
}

.picker-options label {
	font-size: var(--fs-ui);
}

.picker-options input:disabled + label {
	opacity: 0.55;
}

.option-count {
	color: var(--color-text-muted);
	font-variant-numeric: tabular-nums;
}

#category-count {
	margin-top: var(--space-1);
}

#question-category {
	margin: 0 0 var(--space-1);
}

#button-container {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-2);
	width: 100%;
	margin: var(--space-1) 0;
}

/* #question and #timer are aria-live regions: they must stay in the
   accessibility tree at all times or a screen reader misses the announcement
   when their text changes. So they are never hidden — they simply carry no
   panel styling until they hold something, which keeps empty boxes off the
   screen before the game starts. */
#question-container {
	width: 100%;
	max-width: 46rem;
	padding: 0;
	background: none;
	box-shadow: none;
	transition: padding .2s ease, background-color .2s ease;
}

#question-container:has(#question:not(:empty)) {
	padding: var(--space-4) var(--space-3);
	background: var(--panel-bg);
	box-shadow: var(--shadow-md);
}

#question {
	margin: 0;
	font-size: var(--fs-h2);
	font-weight: 700;
	line-height: 1.35;
}

#choices {
	margin: var(--space-4) 0 0;
	font-size: var(--fs-body);
	font-weight: 600;
	line-height: 2;
}

#answer,
#timer {
	display: block;
	width: fit-content;
	margin-inline: auto;
	padding: 0;
}

#answer:not(:empty),
#timer:not(:empty) {
	padding: var(--space-1) var(--space-3);
}

/* `display: block` above outranks the browser's [hidden] rule. */
#answer[hidden] {
	display: none;
}

#answer {
	margin: var(--space-4) auto 0;
	font-size: var(--fs-body);
	font-weight: 700;
	color: var(--color-correct);
}

#timer {
	min-height: 1.4em;
	font-size: var(--fs-h2);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.02em;
}

#timer:empty {
	min-height: 0;
}

/* --- Scoreboard ----------------------------------------------------------
   Three screens (setup, game, results), one shown at a time via [hidden].
   Everything sits in one centered column; the game screen is built around
   the "Now playing" card, which carries the only large controls. */

/* The board sizes itself by its own width, not the window's: the same
   narrow layout serves a phone and the Trivia sidebar on a wide screen. */
.sb {
	container: sb / inline-size;
}

/* A size container cannot shrink to fit its content (it would measure
   zero), so the board always takes the full width it is given. */
cafe-scoreboard {
	width: 100%;
}

.sb-screen {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3);
	width: 100%;
	max-width: 40rem;
	margin: 0 auto;
	color: var(--color-text);
	text-align: center;
}

.sb-screen[hidden] {
	display: none;
}

.sb-title {
	margin: 0;
}

.sb-lead {
	margin: 0;
	color: var(--color-text-muted);
	font-size: var(--fs-label);
}

.sb-card {
	width: 100%;
	padding: var(--space-3);
	background: var(--surface-1);
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
	border-radius: var(--radius-lg);
	text-align: left;
}

/* Programmatic focus lands on these headings when a screen changes; the
   reader did not put it there, so no focus ring. */
.sb-screen [tabindex="-1"]:focus {
	outline: none;
}

.sb-primary,
.sb-primary:hover,
.sb-primary:focus-visible {
	min-height: 56px;
	padding: 0 var(--space-4);
	font-size: var(--fs-label);
	font-weight: 700;
}

.sb-start {
	width: min(100%, 22rem);
}

/* Setup ------------------------------------------------------------------ */

.sb-setup {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	width: 100%;
}

.sb-card-title,
.sb-option-label {
	display: block;
	margin-bottom: var(--space-1);
	font-size: var(--fs-label);
	font-weight: 700;
	color: var(--color-text);
}

.sb-optional {
	font-weight: 400;
	color: var(--color-text-muted);
}

.page-game .sb-card textarea {
	display: block;
	width: 100%;
	min-height: 9rem;
	margin: 0 0 var(--space-1);
}

.sb-count {
	margin: var(--space-1) 0 0;
	font-size: var(--fs-ui);
	font-weight: 600;
}

/* Card title on the left, a small action on the right. */
.sb-card-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-1) var(--space-2);
	margin-bottom: var(--space-1);
}

.sb-card-head .sb-card-title {
	margin-bottom: 0;
}

/* Teams, rounds and timer side by side, wrapping only on narrow screens. */
.sb-options {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--space-3);
}

.sb-option {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	text-align: left;
}

/* The base fieldset rule would draw a panel; this one is only a group. */
fieldset.sb-option {
	width: auto;
	max-width: none;
	padding: 0;
	border: 0;
	background: none;
}

fieldset.sb-option legend {
	float: none;
	width: auto;
	margin: 0 0 var(--space-1);
	padding: 0;
	border: 0;
	text-align: left;
}

.stepper {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.stepper button {
	width: 48px;
	min-height: 48px;
	padding: 0;
	font-size: var(--fs-h3);
}

.stepper output {
	min-width: 2ch;
	font-size: var(--fs-h3);
	font-weight: 700;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

/* Timer choice: real radio buttons, drawn as a segmented control. The
   radio stays in the accessibility tree (visually hidden, not display:none)
   so arrow keys and screen readers work as for any radio group. */
.segmented-options {
	display: inline-flex;
	flex-wrap: nowrap;
	border: max(1px, var(--btn-border-width)) solid var(--btn-border);
	border-radius: 999px;
	overflow: hidden;
}

.segmented-options input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}

.page-game .segmented-options label {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 var(--space-2);
	background: var(--btn-bg);
	color: var(--btn-fg);
	font-size: var(--fs-ui);
	font-weight: 600;
	cursor: pointer;
}

.page-game .segmented-options input:checked + label {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
	box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.22);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.segmented-options input:focus-visible + label {
	outline: 3px solid var(--color-focus);
	outline-offset: -3px;
}

.sb-preview-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
}

.sb-preview-head h2 {
	margin: 0;
	font-size: var(--fs-h3);
}

.sb-preview .hint {
	margin: var(--space-1) 0 var(--space-2);
}

.sb-preview-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.sb-preview-team {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	padding: var(--space-2);
	background: var(--surface-1);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
}

.page-game .sb-preview-team > input {
	max-width: 16rem;
}

.page-game .sb-preview-team input {
	width: 100%;
	font-weight: 700;
}

/* "Not on a Team": players waiting for a team. A dashed edge marks it as a
   holding area rather than a team. */
.sb-unassigned {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	margin-bottom: var(--space-2);
	padding: var(--space-2);
	background: var(--surface-1);
	border: 2px dashed var(--border-subtle);
	border-radius: var(--radius-md);
}

.sb-unassigned[hidden] {
	display: none;
}

.sb-unassigned h4 {
	margin: 0;
	font-size: var(--fs-label);
}

.sb-assign-tools {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin-top: var(--space-1);
}

.sb-preview .sb-unassigned .hint {
	margin: 0;
}

.sb-start-note {
	margin: var(--space-3) 0 0;
	font-size: var(--fs-ui);
	font-weight: 600;
}

.sb-preview-players {
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
}

/* Game ------------------------------------------------------------------- */

.sb-round {
	margin: 0;
	font-size: var(--fs-h3);
	color: var(--color-text-muted);
}

.sb-turn {
	width: 100%;
	padding: var(--space-3);
	background: var(--panel-bg);
	border: max(2px, var(--panel-border-width)) solid var(--color-active);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-md);
}

.sb-turn-label {
	margin: 0;
	font-size: var(--fs-small);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-active);
}

.sb-turn-team {
	margin: var(--space-1) 0 0;
	font-size: var(--fs-h1);
	line-height: 1.15;
	color: var(--color-text);
	overflow-wrap: anywhere;
}

.sb-turn-players {
	margin: var(--space-1) 0 0;
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
}

.sb-turn-players:empty {
	display: none;
}

.sb-turn-score {
	margin: var(--space-2) 0;
	font-size: var(--fs-h3);
	color: var(--color-text-muted);
}

.sb-turn-score-number {
	font-size: 2.4em;
	font-weight: 800;
	line-height: 1;
	color: var(--color-text);
	font-variant-numeric: tabular-nums;
}

.sb-pad {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.sb-pad-row {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-2);
}

/* "-1 +1 +2 +3" in one row: the -1 gets a narrower column so the plus
   buttons stay the obvious targets. */
.sb-pad-row.sb-pad-mixed {
	grid-template-columns: minmax(0, 0.7fr) repeat(3, minmax(0, 1fr));
	align-items: center;
}

/* Narrow side padding, so four buttons fit a phone-width row. */
.sb-pad button {
	min-width: 0;
	padding-inline: var(--space-1);
}

.sb-pad .sb-plus {
	min-height: 64px;
	font-size: var(--fs-h3);
	font-weight: 800;
}

.sb-pad .sb-minus {
	min-height: 44px;
	padding: 0 var(--space-1);
	font-size: var(--fs-ui);
}

/* Alone in the plus row, the -1 matches the row's height. */
.sb-pad-mixed .sb-minus {
	min-height: 64px;
}

/* Checkbox settings (-2/-3 buttons) sit on one line with their label. */
.sb-check {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.sb-check input {
	width: 1.2em;
	height: 1.2em;
	min-height: 0;
	margin: 0;
	flex-shrink: 0;
	accent-color: var(--control-fg);
}

.page-game .sb-check label {
	padding: 0;
	font-size: var(--fs-ui);
	font-weight: 600;
}

.sb-manage-option {
	justify-content: center;
	margin-bottom: var(--space-3);
}

/* Setup player list: name, Captain toggle, team picker. */
.sb-roster {
	grid-column: 1 / -1;
	margin: 0;
	padding: 0;
	list-style: none;
}

.sb-roster-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-1) var(--space-2);
	padding: var(--space-1) 0;
	border-top: 1px solid var(--border-subtle);
	font-size: var(--fs-ui);
}

.sb-roster-name {
	flex: 1 1 8rem;
	min-width: 0;
	font-weight: 600;
	overflow-wrap: anywhere;
}

.page-game .sb-roster-row select {
	max-width: 12rem;
	padding-block: 0;
	font-size: var(--fs-small);
}

/* A team's name with its member count, "(3)", pushed to the right. */
.sb-team-line {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
}

.sb-team-line h3 {
	margin: 0;
	text-align: left;
	overflow-wrap: anywhere;
}

.page-game .sb-team-line input {
	flex: 1;
	min-width: 0;
	max-width: 16rem;
	font-weight: 700;
}

.sb-member-count {
	flex-shrink: 0;
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.sb-preview-tools {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: var(--space-2);
}

.sb-sort {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.sb-sort[hidden] {
	display: none;
}

.page-game .sb-sort label {
	padding: 0;
	font-size: var(--fs-ui);
}

.page-game .sb-sort select {
	padding-block: 0;
	font-size: var(--fs-small);
}

/* Without teams: the setup list is the numbered playing order. */
.sb-preview-list[data-mode="solo"] {
	padding-left: 2em;
	list-style: decimal;
}

.sb-solo-row {
	padding: var(--space-1) 0;
	border-top: 1px solid var(--border-subtle);
	font-weight: 600;
}

.sb-team-count-note {
	margin: var(--space-1) 0 0;
}

.sb-team-count-note:empty {
	display: none;
}

.sb-solo-manage .player-row {
	flex-wrap: nowrap;
}

.page-game .sb-solo-manage input {
	flex: 1;
	min-width: 0;
}

.sb-roster-empty {
	padding: var(--space-1) 0;
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
}

.player-row .player-team {
	flex: 0 1 9rem;
	min-width: 0;
	font-size: var(--fs-small);
}

.sb-timer {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	margin-top: var(--space-3);
}

.sb-timer[hidden] {
	display: none;
}

.sb-timer .sb-timer-display {
	margin: 0;
}

.sb-timer-buttons {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-1);
}

.sb-turn-actions {
	display: flex;
	gap: var(--space-2);
	margin-top: var(--space-3);
}

.sb-turn-actions .sb-primary {
	flex: 1;
}

.sb-undo {
	min-height: 56px;
}

.sb-undo-hint {
	margin: var(--space-1) 0 0;
	font-size: var(--fs-small);
	color: var(--color-text-muted);
}

.sb-undo-hint:empty {
	display: none;
}

.sb-standings {
	width: 100%;
}

.sb-standings h2 {
	margin: 0;
	font-size: var(--fs-h3);
	text-align: left;
}

.score-table .adjust {
	width: 1%;
	white-space: nowrap;
	text-align: right;
}

.score-table .adjust button {
	min-width: 44px;
	padding: 0 var(--space-1);
}

.adjust-buttons {
	display: flex;
	gap: var(--space-1);
}

.sb-manage {
	margin-top: 0;
}

.sb-manage-forms {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
}

.sb-manage-forms .manager-form {
	margin: 0;
}

.sb-footer {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-2);
}

/* Keyboard shortcuts mean nothing on a touch screen with no keyboard. */
@media (hover: none) and (pointer: coarse) {
	.sb-shortcuts {
		display: none;
	}
}

.score-table .badge {
	white-space: nowrap;
}

.sb-shortcuts kbd {
	padding: 0 0.35em;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-sm);
	font-family: inherit;
	font-size: 0.95em;
}

/* Results ---------------------------------------------------------------- */

.sb-winner {
	margin: 0;
	padding: var(--space-2) var(--space-3);
	font-size: var(--fs-h2);
	font-weight: 800;
	color: var(--color-correct);
}

.sb-decided {
	margin: 0;
	font-size: var(--fs-label);
}

.sb-decided[hidden],
.sb-tiebreak[hidden],
.sb-ot[hidden] {
	display: none;
}

/* Tie-breaker choices: overtime, or chance. */
.sb-tiebreak {
	text-align: center;
}

.sb-tiebreak h3 {
	margin: 0;
}

.sb-tiebreak .hint {
	margin: var(--space-1) 0 var(--space-3);
}

.sb-decide {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
}

.sb-decide-label {
	flex-basis: 100%;
	font-size: var(--fs-ui);
	font-weight: 600;
}

/* During overtime: who is still in, above the turn card. */
.sb-ot {
	width: 100%;
	padding: var(--space-2) var(--space-3);
	border: 2px dashed var(--color-active);
	border-radius: var(--radius-lg);
}

.sb-ot-note {
	margin: 0 0 var(--space-2);
	font-size: var(--fs-ui);
	font-weight: 600;
}

.sb-decide-chance {
	margin-top: var(--space-2);
}

/* A coin or die on show, with its result in words underneath. */
.sb-chance {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-2);
	margin-top: var(--space-3);
	padding-top: var(--space-3);
	border-top: 1px solid var(--border-subtle);
}

.sb-chance[hidden] {
	display: none;
}

.sb-chance-figure {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-1);
	margin: 0;
}

.sb-chance-label {
	font-size: var(--fs-h3);
	font-weight: 800;
}

.sb-chance-ask {
	margin: 0;
	font-size: var(--fs-ui);
	font-weight: 600;
}

/* Coin and die keep real-world colours in every theme; the dark outline
   keeps either one clear of a light or dark background. */
.sb-coin-rim {
	fill: #b8860b;
	stroke: #3d2c00;
	stroke-width: 2;
}

.sb-coin-face {
	fill: #e8c252;
}

.sb-coin-ring {
	fill: none;
	stroke: #a07410;
	stroke-width: 2;
	stroke-dasharray: 3 3;
}

.sb-coin-letter {
	fill: #4a3400;
	font: 800 44px/1 system-ui, sans-serif;
	text-anchor: middle;
	dominant-baseline: central;
}

.sb-die-face {
	fill: #fbfbfb;
	stroke: #222;
	stroke-width: 3;
}

.sb-die-pip {
	fill: #1a1a1a;
}

/* Each throw lands with a short spin; none when motion is reduced. */
.sb-coin,
.sb-die {
	animation: sb-throw .45s ease-out;
}

@keyframes sb-throw {
	from { transform: rotate(-200deg) scale(.6); opacity: 0; }
	to   { transform: none; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	.sb-coin,
	.sb-die {
		animation: none;
	}
}

/* Final scores: the overtime round a team reached, under its place. */
.place-ot {
	display: block;
	font-size: var(--fs-small);
	font-weight: 600;
}

.sb-option-hint {
	max-width: 14rem;
	margin: var(--space-1) 0 0;
}

/* The scoreboard's own countdown (the game pages' timer is #timer). */
.sb-timer-display {
	display: block;
	width: fit-content;
	margin-inline: auto;
	font-size: var(--fs-h2);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.02em;
}

.sb-timer-display:not(:empty) {
	padding: var(--space-1) var(--space-3);
	border: var(--panel-border-width) solid var(--panel-border);
	border-radius: var(--radius-lg);
}

.sb-page-title {
	margin: 0;
}

.sb-standalone {
	width: 100%;
}

.sb-link {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-1);
	margin-top: var(--space-2);
}

.sb-link[hidden] {
	display: none;
}

.sb-link input {
	width: 1.2em;
	height: 1.2em;
	min-height: 0;
	margin: 0;
	flex-shrink: 0;
	accent-color: var(--control-fg);
}

.page-game .sb-link label {
	padding: 0;
	font-size: var(--fs-ui);
	font-weight: 500;
}

/* Game pages with the scoreboard. On a wide screen the game and the board
   sit side by side and the board stays in view while the game scrolls; on
   anything narrower they stack, with the board folded under a button. */
.game-column {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	width: 100%;
	min-width: 0;
}

.sb-embed {
	width: 100%;
}

.sb-embed-fold {
	margin-top: 0;
}

@media (min-width: 1100px) {
	.container.with-scoreboard {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(22rem, 28rem);
		align-items: start;
		max-width: 88rem;
	}

	.with-scoreboard .sb-embed {
		position: sticky;
		top: var(--space-2);
		max-height: calc(100vh - var(--space-4));
		overflow-y: auto;
		overscroll-behavior: contain;
	}
}

.sb-final-standings {
	width: 100%;
}

/* The score table. Each row reads as its own card: separate borders with
   vertical spacing, the fill on the cells, and rounded outer corners.
   Two columns (three at game over) hold up at phone width because the
   player list sits under the team name instead of in a column of its own.
   Cell display is never changed: Safari drops table semantics when it is. */
.score-table {
	width: 100%;
	border-collapse: separate;
	border-spacing: 0 var(--space-1);
	font-size: var(--fs-body);
}

.score-table thead th {
	padding: 0 var(--space-2);
	font-size: var(--fs-label);
	font-weight: 600;
	color: var(--color-text-muted);
	text-align: left;
}

.score-table thead th:last-child,
.score-table .score {
	text-align: right;
}

.score-table tbody th,
.score-table tbody td {
	padding: var(--space-2);
	background: var(--surface-1);
	border: 0 solid var(--panel-border);
	border-width: var(--panel-border-width) 0;
	vertical-align: middle;
	text-align: left;
	font-weight: 600;
	transition: background-color .2s ease, border-color .2s ease;
}

.score-table tbody tr > :first-child {
	border-left-width: var(--panel-border-width);
	border-radius: var(--radius-md) 0 0 var(--radius-md);
}

.score-table tbody tr > :last-child {
	border-right-width: var(--panel-border-width);
	border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

.score-table .score {
	width: 1%;
	white-space: nowrap;
	font-size: var(--fs-h3);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.score-table .place {
	width: 1%;
	white-space: nowrap;
}

.team-name {
	font-weight: 700;
}

.player-summary {
	display: block;
	margin-top: 0.2em;
	font-size: var(--fs-ui);
	font-weight: 400;
	color: var(--color-text-muted);
}

/* Highlights come from tokens, so a theme recolours them by redefining
   --color-active / --color-correct. The "Current turn" badge and the place
   column say the same thing in words, so colour is never the only cue. */
.score-table .is-current > *,
.score-table .is-winner > * {
	background: var(--surface-2);
	border-color: currentColor;
	border-top-width: max(2px, var(--panel-border-width));
	border-bottom-width: max(2px, var(--panel-border-width));
}

.score-table .is-current > :first-child,
.score-table .is-winner > :first-child {
	border-left-width: max(2px, var(--panel-border-width));
}

.score-table .is-current > :last-child,
.score-table .is-winner > :last-child {
	border-right-width: max(2px, var(--panel-border-width));
}

.score-table .is-current > * {
	color: var(--color-active);
}

.score-table .is-winner > * {
	color: var(--color-correct);
}

.score-table .is-current .player-summary,
.score-table .is-winner .player-summary {
	color: inherit;
}

.badge {
	display: inline-block;
	margin-left: var(--space-1);
	padding: 0.1em 0.6em;
	border: 1px solid currentColor;
	border-radius: 999px;
	font-size: var(--fs-small);
	font-weight: 600;
	vertical-align: middle;
}



/* --- Scoreboard setup and team manager ---------------------------------- */

.hint {
	margin: 0;
	font-size: var(--fs-small);
	color: var(--color-text-muted);
}

.hint:empty,
.form-error:empty {
	display: none;
}

.form-error {
	margin: 0 auto var(--space-2);
	font-weight: 700;
	color: var(--color-active);
}

.small-button {
	padding: 0 var(--space-2);
	font-size: var(--fs-small);
}

/* Pressed toggles (Captain, Inactive) take the hover fill, so the state is
   visible and not only announced as "pressed". */
.small-button[aria-pressed="true"] {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
	box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.22);
}

.team-manager {
	width: 100%;
	max-width: 40rem;
	margin: 0 auto var(--space-3);
}

.team-manager:empty {
	display: none;
}

.team-cards {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.team-card,
.manager-form {
	padding: var(--space-3);
	background: var(--surface-1);
	border-radius: var(--radius-lg);
	text-align: center;
}

.manager-form {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
}

.team-card h3,
.manager-form h3 {
	margin: 0;
	color: var(--color-text);
}

.team-card .field {
	margin: var(--space-1) auto var(--space-2);
}

.player-rows {
	margin: 0 0 var(--space-2);
	padding: 0;
	list-style: none;
	text-align: left;
}

.player-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-1) var(--space-2);
	padding: var(--space-1) 0;
	border-top: 1px solid var(--border-subtle);
	font-size: var(--fs-ui);
}

.player-row.is-empty {
	justify-content: center;
	color: var(--color-text-muted);
}

/* Struck through and badged, so "inactive" never depends on colour. */
.player-row.is-inactive .player-name {
	color: var(--color-text-muted);
	text-decoration: line-through;
}

.player-name .badge {
	text-decoration: none;
}

.player-name {
	flex: 1 1 6.5rem;
	min-width: 0;
	overflow-wrap: anywhere;
	font-weight: 600;
}

.row-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}

.sb-disclosure {
	width: 100%;
	max-width: 40rem;
	margin: var(--space-4) auto 0;
	text-align: center;
}

/* The disclosure toggle is styled as a button so it is findable at a glance;
   it stays a <summary>, so it is still announced as expandable. */
.sb-disclosure > summary {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	min-height: 44px;
	padding: 0 var(--space-3);
	background: var(--btn-bg);
	color: var(--btn-fg);
	border: var(--btn-border-width) solid var(--btn-border);
	border-radius: 999px;
	box-shadow: var(--btn-shadow);
	font-size: var(--fs-ui);
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

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

.sb-disclosure > summary::before {
	content: "\25B8";
}

.sb-disclosure[open] > summary::before {
	content: "\25BE";
}

.sb-disclosure > summary:hover,
.sb-disclosure > summary:focus-visible {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
}

.sb-disclosure[open] > summary {
	margin-bottom: var(--space-3);
}

iframe {
	width: 100%;
	max-width: 100%;
	background: #ffffff;
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
	border-radius: var(--radius-lg);
}


/* ==========================================================================
   4. Responsive
   ========================================================================== */

@media (max-width: 600px) {
	#accessibility-button {
		padding: 0 var(--space-2);
		font-size: var(--fs-small);
	}

	#accessibility-panel {
		top: 60px;
	}

	.header-logo {
		width: 45px;
		height: 45px;
	}

	/* Reserve clearance above the title so it does not sit under the
	   absolutely-positioned logo and settings button at narrow widths. */
	.header-title {
		margin-top: 56px;
	}

	.image-banner {
		max-width: 280px;
	}
}

@media (max-width: 640px) {
	.page-game {
		--font-size-base: 125%;
	}

	.container {
		gap: var(--space-2);
		padding: 4.5rem var(--space-2) var(--space-3);
	}

	/* Let buttons share a row and wrap only when they genuinely need to.
	   Forcing a column stacks the +1/-1 score buttons full-width, wasting a
	   whole row on a two-character label. */
	#button-container button {
		flex: 1 1 auto;
	}

	.team-card,
	.manager-form {
		padding: var(--space-2);
	}

	/* Scoreboard: setup cards and edit forms stack; team name boxes sit
	   above their player lists. */
	.sb-manage-forms {
		grid-template-columns: 1fr;
	}

	.sb-card,
	.sb-turn {
		padding: var(--space-2);
	}

	.score-table tbody th,
	.score-table tbody td {
		padding: var(--space-1) var(--space-2);
	}

	#question-container:has(#question:not(:empty)) {
		padding: var(--space-3) var(--space-2);
	}
}

@media (max-width: 480px) {
	.page-main {
		padding: var(--space-2);
	}

	.link-panel {
		flex-basis: 100%;
	}
}


/* ==========================================================================
   5. Themes
   Tokens only. Equal specificity to :root, so these win by source order —
   which is why they sit at the end of the file.

   Each sets a real --panel-border-width and thick control borders: the flat
   fills remove the gradient edge the default styling leans on, and without a
   border a black panel on a black page has no visible boundary at all.
   ========================================================================== */

.high-contrast-1 {
	--page-bg: #000000; --panel-bg: #000000; --panel-solid-bg: #000000;
	--panel-border: #ffffff; --panel-border-width: 2px;
	--color-text: #ffffff; --color-text-muted: #ffffff;
	--color-link: #00ffff; --color-link-hover: #ff00ff;
	--btn-bg: #000000; --btn-fg: #ffffff; --btn-border: #ffffff;
	--btn-border-width: 2px; --btn-hover-bg: #0000ff; --btn-hover-fg: #ffffff;
	--btn-shadow: none;
	--control-bg: #000000; --control-fg: #ffffff; --control-border: #ffffff;
	--control-border-width: 3px;
	--footer-bg: #000000; --footer-fg: #ffffff;
	--color-focus: #ff00ff; --color-correct: #00ff00; --color-active: #ffff00;
	--surface-1: #000000; --surface-2: #000000; --border-subtle: #ffffff;
}

.high-contrast-2 {
	--page-bg: #ffffff; --panel-bg: #ffffff; --panel-solid-bg: #ffffff;
	--panel-border: #000000; --panel-border-width: 2px;
	--color-text: #000000; --color-text-muted: #000000;
	--color-link: #0000ff; --color-link-hover: #ff0000;
	--btn-bg: #ffffff; --btn-fg: #000000; --btn-border: #000000;
	--btn-border-width: 2px; --btn-hover-bg: #ffaaaa; --btn-hover-fg: #000000;
	--btn-shadow: none;
	--control-bg: #ffffff; --control-fg: #000000; --control-border: #000000;
	--control-border-width: 3px;
	--footer-bg: #ffffff; --footer-fg: #000000;
	--color-focus: #ff0000; --color-correct: #006600; --color-active: #7a5c00;
	--surface-1: #ffffff; --surface-2: #ffffff; --border-subtle: #000000;
}

.high-contrast-3 {
	--page-bg: #000000; --panel-bg: #000000; --panel-solid-bg: #000000;
	--panel-border: #ffff00; --panel-border-width: 2px;
	--color-text: #ffff00; --color-text-muted: #ffff00;
	--color-link: #00ffff; --color-link-hover: #ff00ff;
	--btn-bg: #000000; --btn-fg: #ffff00; --btn-border: #ffff00;
	--btn-border-width: 2px; --btn-hover-bg: #0000ff; --btn-hover-fg: #ffff00;
	--btn-shadow: none;
	--control-bg: #000000; --control-fg: #ffff00; --control-border: #ffff00;
	--control-border-width: 3px;
	--footer-bg: #000000; --footer-fg: #ffff00;
	--color-focus: #ff00ff; --color-correct: #00ff00; --color-active: #ffff00;
	--surface-1: #000000; --surface-2: #000000; --border-subtle: #ffff00;
}

.high-contrast-4 {
	--page-bg: #ffff00; --panel-bg: #ffff00; --panel-solid-bg: #ffff00;
	--panel-border: #000000; --panel-border-width: 2px;
	--color-text: #000000; --color-text-muted: #000000;
	--color-link: #0000ff; --color-link-hover: #ff0000;
	--btn-bg: #ffff00; --btn-fg: #000000; --btn-border: #000000;
	--btn-border-width: 2px; --btn-hover-bg: #00ffff; --btn-hover-fg: #000000;
	--btn-shadow: none;
	--control-bg: #ffff00; --control-fg: #000000; --control-border: #000000;
	--control-border-width: 3px;
	--footer-bg: #ffff00; --footer-fg: #000000;
	--color-focus: #ff0000; --color-correct: #006600; --color-active: #000000;
	--surface-1: #ffff00; --surface-2: #ffff00; --border-subtle: #000000;
}

.high-contrast-5 {
	--page-bg: #0000ff; --panel-bg: #0000ff; --panel-solid-bg: #0000ff;
	--panel-border: #ffff00; --panel-border-width: 2px;
	--color-text: #ffff00; --color-text-muted: #ffff00;
	--color-link: #ff7f00; --color-link-hover: #00ff00;
	--btn-bg: #0000ff; --btn-fg: #ffff00; --btn-border: #ffff00;
	--btn-border-width: 2px; --btn-hover-bg: #000000; --btn-hover-fg: #ffff00;
	--btn-shadow: none;
	--control-bg: #0000ff; --control-fg: #ffff00; --control-border: #ffff00;
	--control-border-width: 3px;
	--footer-bg: #0000ff; --footer-fg: #ffff00;
	--color-focus: #00ff00; --color-correct: #00ff00; --color-active: #ffff00;
	--surface-1: #0000ff; --surface-2: #0000ff; --border-subtle: #ffff00;
}

.spooky {
	--page-bg: #000000; --panel-bg: #000000; --panel-solid-bg: #000000;
	--panel-border: #aa00aa; --panel-border-width: 2px;
	--color-text: #ff7f00; --color-text-muted: #ff7f00;
	--color-link: #ff5555; --color-link-hover: #ffffff;
	--btn-bg: #000000; --btn-fg: #ff7f00; --btn-border: #ff7f00;
	--btn-border-width: 2px; --btn-hover-bg: #aa00aa; --btn-hover-fg: #ffffff;
	--btn-shadow: none;
	--control-bg: #000000; --control-fg: #ff7f00; --control-border: #ff7f00;
	--control-border-width: 3px;
	--footer-bg: #000000; --footer-fg: #ff7f00;
	--color-focus: #ffffff; --color-correct: #00ff00; --color-active: #ffff00;
	--surface-1: #000000; --surface-2: #000000; --border-subtle: #aa00aa;
}

.holiday {
	--page-bg: #7f0000; --panel-bg: #7f0000; --panel-solid-bg: #7f0000;
	--panel-border: #ffffff; --panel-border-width: 2px;
	--color-text: #00ff00; --color-text-muted: #00ff00;
	--color-link: #ffffff; --color-link-hover: #7777ff;
	--btn-bg: #7f0000; --btn-fg: #00ff00; --btn-border: #00ff00;
	--btn-border-width: 2px; --btn-hover-bg: #ffffff; --btn-hover-fg: #ff0000;
	--btn-shadow: none;
	--control-bg: #7f0000; --control-fg: #00ff00; --control-border: #00ff00;
	--control-border-width: 3px;
	--footer-bg: #7f0000; --footer-fg: #00ff00;
	--color-focus: #ffffff; --color-correct: #00ff00; --color-active: #ffff00;
	--surface-1: #7f0000; --surface-2: #7f0000; --border-subtle: #ffffff;
}

.neon-bleach {
	--page-bg: #00ffff; --panel-bg: #00ffff; --panel-solid-bg: #00ffff;
	--panel-border: #ff00ff; --panel-border-width: 2px;
	--color-text: #ff00ff; --color-text-muted: #ff00ff;
	--color-link: #cc0000; --color-link-hover: #007700;
	--btn-bg: #00ffff; --btn-fg: #ff00ff; --btn-border: #ff00ff;
	--btn-border-width: 2px; --btn-hover-bg: #00ff00; --btn-hover-fg: #7f3f00;
	--btn-shadow: none;
	--control-bg: #00ffff; --control-fg: #ff00ff; --control-border: #ff00ff;
	--control-border-width: 3px;
	--footer-bg: #00ffff; --footer-fg: #ff00ff;
	--color-focus: #cc0000; --color-correct: #007700; --color-active: #7f3f00;
	--surface-1: #00ffff; --surface-2: #00ffff; --border-subtle: #ff00ff;
}

/* Scoreboard at phone width, or in the Trivia sidebar ----------------------
   Tighter card padding; the score list's -1/+1 stack so team names keep
   their width; the manager's Captain/Inactive/Remove drop under each name. */
@container sb (max-width: 32rem) {
	.sb-turn,
	.sb-card {
		padding: var(--space-2);
	}

	.sb-turn-team {
		font-size: var(--fs-h2);
	}

	.adjust-buttons {
		flex-direction: column;
	}

	.score-table tbody td {
		padding-inline: var(--space-1);
	}

	.sb-manage-forms {
		grid-template-columns: 1fr;
	}

	.team-card {
		padding: var(--space-2);
	}

	.player-row .row-actions {
		flex-basis: 100%;
	}
}
