/* ==========================================================================
   The Free Town of Blindheim — 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. The page is a warm near-black lit by two soft red
	   glows at the top; panels are the town's red, deepening diagonally.
	   The glows and the fade are placed in rem, not %, so they look the
	   same on every page however long it is. */
	--page-bg:
		radial-gradient(70rem 36rem at 12% -6rem, rgba(160, 32, 40, 0.38), transparent 62%),
		radial-gradient(56rem 30rem at 100% 0, rgba(120, 22, 34, 0.30), transparent 58%),
		linear-gradient(180deg, #170d0e 0%, #0f0a0b 100%) top / 100% 75rem no-repeat,
		#0f0a0b;
	--panel-bg: linear-gradient(145deg, #6a1d21 0%, #521419 48%, #3d0f14 100%);
	--panel-solid-bg: #231315;
	--panel-border: transparent;
	--panel-border-width: 0px;
	/* A hairline of light along a panel's top edge, so it reads as raised. */
	--panel-highlight: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 0 0 1px rgba(255, 255, 255, 0.04);

	/* Text */
	--color-text: #fff8f5;
	--color-text-muted: rgba(255, 238, 232, 0.78);
	/* Sub-headings (h3): a warm coral so they stand apart from the prose. */
	--color-heading: #ffb8aa;

	/* The call-to-action colour (Join us on Discord, the current page). */
	--accent: #d63a44;
	--accent-fg: #ffffff;
	--accent-hover: #e8525b;
	--accent-hover-fg: #ffffff;
	--accent-border: transparent;
	--cta-shadow: 0 10px 24px rgba(214, 58, 68, 0.35);
	--cta-shadow-hover: 0 14px 30px rgba(214, 58, 68, 0.45);

	/* Chips, badges and the navigation bar: glass over the panel or page. */
	--chip-bg: rgba(255, 255, 255, 0.08);
	--chip-border: rgba(255, 255, 255, 0.14);
	--nav-bg: rgba(255, 255, 255, 0.05);

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

	/* Buttons: glass pills like the menu's, filling with the town's red on
	   hover and when pressed, like the current page in the menu. Solid
	   colours only: the browser can fade one colour into another, but not
	   one gradient into another, so a gradient hover would snap. The border
	   is bright enough to show the button's edge on a red panel (3:1). */
	--btn-bg: rgba(255, 255, 255, 0.1);
	--btn-fg: #fff8f5;
	--btn-border: rgba(255, 255, 255, 0.34);
	--btn-border-width: 1px;
	--btn-hover-bg: #d63a44;
	--btn-hover-fg: #ffffff;
	--btn-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);

	/* Form controls: dark fields with light coral text. --control-scheme
	   tells the browser to draw the field's own parts (the dropdown arrow,
	   the open list, the date picker) dark or light to match. */
	--control-bg: #1c0f11;
	--control-fg: #ffd9d0;
	--control-border: rgba(255, 184, 170, 0.55);
	--control-border-width: 1px;
	--control-scheme: dark;

	/* Footer */
	--footer-bg: linear-gradient(180deg, rgba(42, 14, 17, 0.9) 0%, rgba(26, 11, 13, 0.95) 100%);
	--footer-fg: rgba(255, 238, 232, 0.82);

	--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: 8px;
	--radius-md: 14px;
	--radius-lg: 22px;
	--radius-xl: 30px;

	--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.25);
	--shadow-md: 0 10px 28px rgba(0, 0, 0, 0.32);
	--shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.42);

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

	/* The main site's content column and its side gutter. The settings button
	   lines up with the column's right edge using the same two numbers. */
	--content-max: 76rem;
	--gutter: clamp(1rem, 3vw, 2rem);

	/* Body text is Atkinson Hyperlegible Next, drawn by the Braille Institute
	   for low-vision readers: every letter is distinct (no l/I/1 or O/0 mix-
	   ups). Headings are Fraunces in its soft, rounded cut, for the town's
	   warmth. Both are served from assets/fonts/, so no outside service is
	   involved; the system fonts after them cover the moment before they load. */
	--font-sans: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", Roboto,
		"Helvetica Neue", Arial, sans-serif;
	--font-display: "Fraunces", Georgia, "Times New Roman", serif;
}

/* Self-hosted fonts (SIL Open Font License; see assets/fonts/). Latin and
   Latin Extended, so names from across the world still render in them. */
@font-face {
	font-family: "Atkinson Hyperlegible Next";
	font-style: normal;
	font-weight: 200 800;
	font-display: swap;
	src: url("../fonts/atkinson-hyperlegible-next-normal-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Atkinson Hyperlegible Next";
	font-style: normal;
	font-weight: 200 800;
	font-display: swap;
	src: url("../fonts/atkinson-hyperlegible-next-normal-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Atkinson Hyperlegible Next";
	font-style: italic;
	font-weight: 200 800;
	font-display: swap;
	src: url("../fonts/atkinson-hyperlegible-next-italic-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Atkinson Hyperlegible Next";
	font-style: italic;
	font-weight: 200 800;
	font-display: swap;
	src: url("../fonts/atkinson-hyperlegible-next-italic-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Fraunces";
	font-style: normal;
	font-weight: 500 800;
	font-display: swap;
	src: url("../fonts/fraunces-normal-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Fraunces";
	font-style: normal;
	font-weight: 500 800;
	font-display: swap;
	src: url("../fonts/fraunces-normal-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ==========================================================================
   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, text-decoration-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;
}

h1,
h2 {
	font-family: var(--font-display);
	/* Fraunces' soft, rounded cut; ignored where the font isn't loaded. */
	font-variation-settings: "SOFT" 100, "WONK" 0;
}

/* Headings break into even lines, so a last word is never left alone. */
h1,
h2,
h3,
.eyebrow {
	text-wrap: balance;
}

h2 {
	margin: 0 0 var(--space-2);
	font-size: var(--fs-h2);
	font-weight: 650;
	letter-spacing: -0.015em;
	line-height: 1.2;
}

h3 {
	margin: 0 0 var(--space-1);
	font-size: var(--fs-h3);
	font-weight: 700;
	letter-spacing: -0.005em;
	line-height: 1.3;
	color: var(--color-heading);
}

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,
town-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,
.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);
	color-scheme: var(--control-scheme);
	font-family: inherit;
	transition: border-color .2s ease, box-shadow .2s ease;
}

::placeholder {
	color: var(--control-fg);
	opacity: 0.7;
}

/* Checkboxes and radio buttons take the field colour for their tick. */
input[type="checkbox"],
input[type="radio"] {
	accent-color: var(--control-fg);
}

/* 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. The button sits at
   the top right of the content column (the header's right end on the main
   site), and the panel drops down beneath it as a card. */

#accessibility-button {
	position: absolute;
	top: var(--space-3);
	/* The content column's right edge, however wide the window. */
	right: max(var(--gutter), calc((100% - var(--content-max)) / 2 + var(--gutter)));
	z-index: 1001;
	background: var(--chip-bg);
	color: var(--color-text);
	border: max(1px, var(--btn-border-width)) solid var(--chip-border);
	box-shadow: none;
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

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

/* 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 .35s ease;
}

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

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

/* site.js shows and hides the panel with display. Where the browser can,
   it fades and settles into place as it opens. */
#accessibility-panel {
	position: absolute;
	top: calc(var(--space-3) + 56px);
	right: max(var(--gutter), calc((100% - var(--content-max)) / 2 + var(--gutter)));
	z-index: 1000;
	display: none;
	width: min(22rem, calc(100% - 2 * var(--gutter)));
	padding: var(--space-3);
	background: var(--panel-solid-bg);
	color: var(--color-text);
	box-shadow: var(--shadow-lg), var(--panel-highlight);
	text-align: left;
	opacity: 1;
	transform: translateY(0);
	transition: opacity .2s ease, transform .2s ease, display .2s allow-discrete;
}

@starting-style {
	#accessibility-panel {
		opacity: 0;
		transform: translateY(-6px);
	}
}

.panel-title {
	margin: 0 0 var(--space-2);
	padding-bottom: var(--space-2);
	border-bottom: 1px solid var(--border-subtle);
	font-family: var(--font-display);
	font-variation-settings: "SOFT" 100, "WONK" 0;
	font-size: var(--fs-body);
	font-weight: 650;
}

.panel-row {
	margin-bottom: var(--space-3);
}

.panel-heading {
	display: block;
	margin-bottom: var(--space-1);
	font-size: var(--fs-ui);
	font-weight: 700;
	letter-spacing: 0.02em;
	color: var(--color-text-muted);
}

/* The text size stepper: minus, the current size, plus, on one track. */
.text-size-controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 4px;
	padding: 4px;
	border: 1px solid var(--border-subtle);
	/* Rounded, not a pill: on a phone the options stack. */
	border-radius: calc(var(--radius-md) + 4px);
	background: var(--surface-1);
}

/* 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 is interface chrome, not content. */
#text-size-label {
	flex: 1;
	font-size: var(--fs-ui);
	font-weight: 700;
	text-align: center;
}

.theme-picker label {
	padding: 0;
}

#theme-select {
	display: block;
	width: 100%;
	min-height: 44px;
	padding: var(--space-1) var(--space-2);
	font-size: var(--fs-ui);
	border-radius: var(--radius-md);
}

/* 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);
}

/* A checkbox and its label, the whole row a 44px target. */
.panel-check {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.panel-check input {
	flex-shrink: 0;
	width: 1.2em;
	height: 1.2em;
	margin: 0;
}

.panel-check label,
.page-main .panel-check label {
	flex: 1;
	min-height: 44px;
	display: flex;
	align-items: center;
	padding: 0;
	font-size: var(--fs-ui);
	font-weight: 600;
	cursor: pointer;
}

.reset {
	text-align: center;
}

/* A secondary action: an outline instead of the filled pill. */
.button-quiet {
	width: 100%;
	background: transparent;
	color: var(--color-text);
	border: max(1px, var(--btn-border-width)) solid var(--border-subtle);
	box-shadow: none;
}


/* --- Footer -------------------------------------------------------------
   The town's name and Braille signature, three columns of links, then the
   fine print. On every page, game pages included. */

.site-footer {
	margin-top: var(--space-5);
	padding: var(--space-5) var(--gutter) var(--space-3);
	background: var(--footer-bg);
	color: var(--footer-fg);
	border-top: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
	font-size: var(--fs-ui);
	text-align: left;
}

.footer-inner {
	display: grid;
	grid-template-columns: minmax(16rem, 1.2fr) 2fr;
	gap: var(--space-5);
	max-width: var(--content-max);
	margin: 0 auto;
}

.site-footer p {
	margin: 0;
}

.footer-home,
.page-main .footer-home {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-2);
	color: var(--color-text);
	text-decoration: none;
}

.footer-logo {
	display: block;
	width: 56px;
	height: 56px;
	transition: transform .35s ease;
}

.footer-home:hover .footer-logo,
.footer-home:focus-visible .footer-logo {
	transform: rotate(-8deg) scale(1.04);
}

.footer-name {
	font-family: var(--font-display);
	font-variation-settings: "SOFT" 100, "WONK" 0;
	font-size: var(--fs-h3);
	font-weight: 650;
	text-decoration: underline;
	text-decoration-color: transparent;
	text-underline-offset: 0.2em;
	transition: text-decoration-color .2s ease;
}

.footer-home:hover .footer-name,
.footer-home:focus-visible .footer-name {
	text-decoration-color: currentColor;
}

.site-footer .footer-tagline {
	max-width: 26rem;
	margin: var(--space-1) 0 var(--space-3);
	line-height: 1.5;
}

/* The banner is a white image; rounded so it sits in the design like a
   name plate rather than a pasted strip. */
.footer-braille {
	display: block;
	width: 100%;
	max-width: 18rem;
	height: auto;
	border-radius: var(--radius-sm);
	border: var(--panel-border-width) solid var(--panel-border);
	opacity: 0.92;
}

.footer-links {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-4);
}

.footer-heading {
	margin: 0 0 var(--space-2);
	font-family: var(--font-sans);
	font-variation-settings: normal;
	font-size: var(--fs-ui);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-heading);
}

.footer-links ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer-links li,
.page-main .footer-links li {
	margin: 0;
}

.footer-links a,
.page-main .footer-links a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--footer-fg);
	text-decoration: none;
	transition: color .2s ease, transform .2s ease;
}

.footer-links a:hover,
.footer-links a:focus-visible {
	color: var(--color-link-hover);
	transform: translateX(3px);
}

/* The page being shown is bold and underlined in both menus; screen readers
   hear "current page" from aria-current. */
.footer-links a[aria-current="page"] {
	color: var(--color-text);
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.footer-fine-print {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--space-1) var(--space-3);
	max-width: var(--content-max);
	margin: var(--space-5) auto 0;
	padding-top: var(--space-3);
	border-top: 1px solid var(--border-subtle);
	font-size: var(--fs-small);
}

@media (max-width: 900px) {
	.footer-inner {
		grid-template-columns: 1fr;
		gap: var(--space-4);
	}
}

@media (max-width: 600px) {
	.footer-links {
		grid-template-columns: 1fr 1fr;
	}
}


/* --- 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: 0;
}

/* The header, the page and the footer's contents share one centred column. */
.page-main main {
	width: 100%;
	max-width: var(--content-max);
	margin: 0 auto;
	padding: 0 var(--gutter);
}

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

/* Links inside prose are underlined, so they never rely on colour alone. */
.page-main main p a:not(.button-link):not(.cta),
.page-main main li a:not(.button-link):not(.cta) {
	text-decoration: underline;
	text-decoration-thickness: 0.08em;
	text-underline-offset: 0.18em;
}

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

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


/* --- Header ------------------------------------------------------------
   Two rows: the town's name and logo (with Settings at the right end, from
   <site-settings>), then the menu as a bar of pills. Not pinned to the top
   of the screen: at high zoom a pinned header would cover the content. */

.site-header {
	width: 100%;
	max-width: var(--content-max);
	margin: 0 auto var(--space-4);
	padding: var(--space-3) var(--gutter) 0;
}

.brand {
	margin: 0 0 var(--space-3);
	/* Room for the Settings button at the same height on the right. */
	padding-right: 9.5rem;
	font-size: clamp(var(--fs-body), 3.4vw, var(--fs-h2));
	text-align: left;
}

.brand-link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-text);
	text-decoration: none;
	border-radius: var(--radius-md);
	transition: color .2s ease;
}

.brand-link:hover,
.brand-link:focus-visible {
	color: var(--color-text);
}

.brand-logo {
	display: block;
	flex-shrink: 0;
	width: 64px;
	height: 64px;
	filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.45));
	transition: transform .35s ease;
}

.brand-link:hover .brand-logo,
.brand-link:focus-visible .brand-logo {
	transform: rotate(-8deg) scale(1.04);
}

.brand-name {
	line-height: 1.1;
}

/* The menu: every link always visible, wrapping onto a second line on a
   narrow screen rather than hiding behind a button. */
.site-nav ul {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px;
	margin: 0;
	padding: 6px;
	list-style: none;
	background: var(--nav-bg);
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--chip-border));
	border-color: var(--chip-border);
	border-radius: 999px;
	box-shadow: var(--panel-highlight);
}

.page-main .site-nav li {
	margin: 0;
}

.site-nav a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 1.1em;
	border-radius: 999px;
	color: var(--color-text);
	font-size: var(--fs-ui);
	font-weight: 600;
	text-decoration: none;
	transition: background-color .2s ease, color .2s ease;
}

.site-nav a:hover,
.site-nav a:focus-visible {
	background: var(--surface-2);
	color: var(--color-text);
}

/* The page being shown is a filled pill; screen readers hear "current
   page" from aria-current. Same weight as the others: a bolder pill is
   wider, and the centred menu would shift a little on every page change. */
.site-nav a[aria-current="page"] {
	background: var(--accent);
	color: var(--accent-fg);
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.28);
}


/* --- Panels -------------------------------------------------------------- */

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

.page-main .normalsection {
	border-radius: var(--radius-xl);
}

.podcastsection h2 {
	text-align: center;
}

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

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

/* Sub-headings get room above them, so each reads as the start of a part. */
.page-main main * + h3 {
	margin-top: var(--space-4);
}

/* Prose holds a comfortable line length, even in a wide panel. */
.page-main main p,
.page-main main li {
	max-width: 46em;
}

/* An eyebrow: a small label above a heading. */
.eyebrow {
	margin: 0 0 var(--space-2);
	font-size: var(--fs-ui);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-heading);
}

/* A section's opening paragraph, a size up from the rest. */
.lead {
	font-size: 1.08em;
	line-height: 1.55;
}


/* --- Calls to action ------------------------------------------------------
   Pill links: the filled one is the main thing to do, the outlined one
   the next step. They're links, so a screen reader hears links. */

.cta-row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin: var(--space-4) 0 0;
}

.cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-1);
	min-height: 52px;
	padding: 0 1.6em;
	border-radius: 999px;
	font-size: var(--fs-ui);
	font-weight: 700;
	text-decoration: none;
	transition: background-color .2s ease, color .2s ease, border-color .2s ease,
		transform .2s ease, box-shadow .2s ease;
}

.cta-primary {
	background: var(--accent);
	color: var(--accent-fg);
	border: max(1px, var(--btn-border-width)) solid var(--accent-border);
	box-shadow: var(--cta-shadow);
}

.cta-primary:hover,
.cta-primary:focus-visible {
	background: var(--accent-hover);
	color: var(--accent-hover-fg);
	transform: translateY(-2px);
	box-shadow: var(--cta-shadow-hover);
}

.cta-secondary {
	background: var(--chip-bg);
	color: var(--color-text);
	border: max(1px, var(--btn-border-width)) solid var(--chip-border);
}

.cta-secondary:hover,
.cta-secondary:focus-visible {
	background: var(--surface-2);
	color: var(--color-text);
	transform: translateY(-2px);
}

/* The arrow after a call to action or a card's title; decorative. */
.arrow {
	display: inline-block;
	transition: transform .2s ease;
}

.cta:hover .arrow,
.cta:focus-visible .arrow,
.card-link:hover .arrow,
.card-link:focus-visible .arrow {
	transform: translateX(4px);
}


/* --- Home: the opening panel ---------------------------------------------- */

.hero {
	position: relative;
	overflow: hidden;
}

/* A soft glow behind the heading (every page's opening panel), and on the
   home page the logo as a large watermark. */
.page-main .hero,
.page-main .page-intro {
	background:
		radial-gradient(40rem 22rem at 88% 8%, rgba(255, 120, 110, 0.22), transparent 70%),
		var(--panel-bg);
}

.hero-mark {
	position: absolute;
	right: -3rem;
	bottom: -3rem;
	width: 22rem;
	height: 22rem;
	opacity: 0.09;
	pointer-events: none;
}

.hero > *:not(.hero-mark) {
	position: relative;
}

.page-intro h2 {
	font-size: clamp(1.45em, 3.4vw, 1.9em);
	letter-spacing: -0.02em;
}

.hero-title {
	max-width: 15em;
	margin-bottom: var(--space-3);
	font-size: clamp(1.6em, 4.2vw, 2.3em);
	font-weight: 700;
	letter-spacing: -0.025em;
	line-height: 1.05;
}

/* At-a-glance facts under the opening. Plain list items, so a screen reader
   reads each one in full. */
.stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin: var(--space-4) 0 0;
	padding: 0;
	list-style: none;
}

.page-main .stats li {
	margin: 0;
	padding: var(--space-1) var(--space-2);
	border: 1px solid var(--chip-border);
	border-radius: var(--radius-lg);
	background: var(--chip-bg);
	font-size: var(--fs-ui);
}

.stats strong {
	color: var(--color-text);
	font-weight: 800;
}


/* --- Cards -----------------------------------------------------------------
   Smaller boxes inside or beside panels: a grid that settles into as many
   columns as fit. */

.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
	gap: var(--space-3);
	margin-bottom: var(--space-4);
	padding: 0;
	list-style: none;
}

.card-grid.two-up {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
}

.page-main .card-grid > li {
	max-width: none;
	margin: 0;
}

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

.card > :last-child {
	margin-bottom: 0;
}

.page-main main .card h3,
.page-main main .card > h3:first-child {
	margin-top: 0;
}

/* A card that is one big link: the link is its title, and its ::after
   covers the card so all of it is a target, while a screen reader hears
   just the title as the link. */
.card-link-card {
	position: relative;
	background: var(--panel-bg);
	box-shadow: var(--shadow-md), var(--panel-highlight);
	transition: transform .2s ease, box-shadow .2s ease;
}

.card-link-card:hover,
.card-link-card:focus-within {
	transform: translateY(-3px);
	box-shadow: var(--shadow-lg), var(--panel-highlight), 0 0 0 3px var(--color-focus);
}

.card-link {
	color: var(--color-text);
	text-decoration: none;
}

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

.card-link::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--radius-lg);
}

.card-link:focus-visible {
	outline: none;
}

.card-link-card p {
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
}

/* Games (games.html): each group is a panel, and its games are cards a
   shade lighter than the panel rather than panels inside a panel. */
.game-group .card-grid {
	margin: var(--space-3) 0 0;
}

.game-group h2 + .card-grid {
	margin-top: 0;
}

.game-group .card-link-card {
	background: var(--surface-1);
	box-shadow: none;
	transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.game-group .card-link-card:hover,
.game-group .card-link-card:focus-within {
	background: var(--surface-2);
	box-shadow: var(--shadow-md), 0 0 0 3px var(--color-focus);
}

/* Panels set side by side (Who We Are / What We Offer on the home page). */
.panel-pair {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 28rem), 1fr));
	align-items: start;
	gap: var(--space-4);
	margin-bottom: var(--space-4);
}

.panel-pair > .normalsection {
	margin-bottom: 0;
}


/* --- Events: the schedule (made by npm run events) -------------------------- */

.schedule {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
	gap: var(--space-3);
}

.page-main main .schedule h3 {
	margin: 0 0 var(--space-2);
}

.event-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.page-main .event-list li {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-1);
	margin: 0;
	padding: var(--space-2) 0;
	border-top: 1px solid var(--border-subtle);
}

.page-main .event-list li:first-child {
	padding-top: 0;
	border-top: 0;
}

.event-time {
	padding: 0.25em 0.7em;
	border: 1px solid var(--chip-border);
	border-radius: 999px;
	background: var(--chip-bg);
	font-size: var(--fs-small);
	font-weight: 800;
	white-space: nowrap;
}

.event-name {
	display: block;
	font-weight: 700;
}

.event-desc {
	display: block;
	color: var(--color-text-muted);
	font-size: var(--fs-ui);
}

.event-when {
	display: block;
	margin-bottom: 0.2em;
	font-size: var(--fs-small);
	font-weight: 700;
	letter-spacing: 0.04em;
	color: var(--color-heading);
}


/* --- How to Join: numbered steps ------------------------------------------ */

.steps {
	display: grid;
	gap: var(--space-3);
	margin-top: var(--space-4);
}

.step {
	padding: var(--space-3);
	border: max(1px, var(--panel-border-width)) solid var(--panel-border, var(--border-subtle));
	border-color: var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-1);
}

.page-main main .step h3 {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-1) var(--space-2);
	margin: 0 0 var(--space-2);
	color: var(--color-text);
}

.step-num {
	display: inline-flex;
	align-items: center;
	min-height: 2em;
	padding: 0 0.8em;
	border: max(1px, var(--btn-border-width)) solid var(--accent-border);
	border-radius: 999px;
	background: var(--accent);
	color: var(--accent-fg);
	font-size: var(--fs-small);
	font-weight: 800;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.step > :last-child {
	margin-bottom: 0;
}


/* --- FAQ ------------------------------------------------------------------- */

.faq-list {
	display: grid;
	gap: var(--space-2);
	margin-top: var(--space-3);
}

.faq-item {
	padding: var(--space-3);
	border-left: 4px solid var(--color-heading);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

.page-main main .faq-item h3 {
	margin: 0 0 var(--space-1);
	color: var(--color-text);
}

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


/* --- Link panels (Join Us / Our Affiliates / Resources) ---------------------
   Cards side by side, each a list of links with a logo on a white tile, so
   every organisation's logo shows on its own colours. */

.link-panels {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
	gap: var(--space-4);
	margin-bottom: var(--space-4);
}

.link-panel {
	margin-bottom: 0;
}

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

.page-main .link-list li {
	max-width: none;
	margin: 0;
}

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

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

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

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

/* Every icon renders in the same size tile, regardless of its native
   aspect ratio, so labels line up beside them consistently. */
.social-icon,
.affiliate-logo,
.resource-logo {
	display: block;
	flex-shrink: 0;
	width: 44px;
	height: 44px;
	padding: 6px;
	object-fit: contain;
	border-radius: var(--radius-sm);
	background: #ffffff;
}

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


/* Intake form (feedback.html). One column of fields,
   each a label, its control, then its hint and error, in that reading order.
   The panel spans the page like every other section; only the form and its
   problem list are held to a readable line length. */

.intake-form,
.form-problems {
	max-width: 42rem;
}

.intake-form {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	margin-top: var(--space-3);
}

/* `display: flex` above outranks the browser's [hidden] rule; the form is
   hidden once it has been sent. */
.intake-form[hidden] {
	display: none;
}

/* The part of the form that changes with the category. Laid out like the
   form itself, so switching sections never changes the spacing. */
.intake-section {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	width: 100%;
}

.intake-section[hidden] {
	display: none;
}

.intake-section > p,
.intake-form > p {
	margin: 0;
}

/* The confidentiality and emergency note shown with Report a Concern. The
   bar is the theme's highlight colour; the text needs no colour to read. */
.intake-note {
	padding: var(--space-1) 0 var(--space-1) var(--space-2);
	border-left: 4px solid var(--color-active);
}

/* In the page intro (report.html), spaced like the paragraphs around it. */
.intake > .intake-note {
	margin-bottom: var(--space-2);
}

.intake-note p {
	margin: 0 0 var(--space-1);
}

.intake-note p:last-child {
	margin-bottom: 0;
}

/* The community guidelines, collapsed until opened. The summary is the
   control, so it gets the same 44px target as a button. */
.intake-guidelines {
	width: 100%;
	padding: var(--space-1) var(--space-2);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

/* Stays a list-item (the default) so it keeps its open/closed triangle. */
.intake-guidelines summary {
	min-height: 44px;
	padding: var(--space-1) 0;
	font-weight: 700;
	cursor: pointer;
}

/* The guidelines as written in Markdown (guidelines.js). Headings arrive two
   levels down (# is an h3), so they are sized here rather than by the page's
   heading scale. */
.guideline-text {
	padding-bottom: var(--space-1);
}

.guideline-text h3,
.guideline-text h4,
.guideline-text h5,
.guideline-text h6 {
	margin: var(--space-2) 0 var(--space-1);
	color: var(--color-text);
	line-height: 1.3;
}

.guideline-text h3 { font-size: 1.15em; }
.guideline-text h4 { font-size: 1.05em; }
.guideline-text h5,
.guideline-text h6 { font-size: 1em; }

.guideline-text p {
	margin: 0 0 var(--space-1);
}

.guideline-text ol,
.guideline-text ul {
	margin: 0 0 var(--space-1);
	padding-left: var(--space-3);
}

.guideline-text li {
	margin: 0 0 var(--space-1);
}

.guideline-text li > ol,
.guideline-text li > ul {
	margin-top: var(--space-1);
}

.guideline-text blockquote {
	margin: 0 0 var(--space-1);
	padding-left: var(--space-2);
	border-left: 4px solid var(--border-subtle);
}

.guideline-text code {
	padding: 0 0.25em;
	border-radius: var(--radius-sm);
	background: var(--surface-1);
	font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
	font-size: 0.9em;
}

.guideline-text pre {
	overflow-x: auto;
	margin: 0 0 var(--space-1);
	padding: var(--space-1) var(--space-2);
	border-radius: var(--radius-sm);
	background: var(--surface-1);
}

.guideline-text pre code {
	padding: 0;
	background: none;
}

.guideline-text hr {
	margin: var(--space-2) 0;
	border: 0;
	border-top: 1px solid var(--border-subtle);
}

/* Discord's "-#" subtext. */
.guideline-subtext {
	font-size: var(--fs-small);
	color: var(--color-text-muted);
}

.intake-field {
	width: 100%;
}

.intake input:not([type="checkbox"]),
.intake select,
.intake textarea {
	width: 100%;
	min-height: 44px;
	margin: 0;
	padding: var(--space-1);
	font-size: var(--fs-ui);
	line-height: 1.4;
}

.intake textarea {
	min-height: 10rem;
}

.intake .hint,
.intake .form-error {
	margin: var(--space-1) 0 0;
}

.intake .small-button {
	margin-top: var(--space-1);
}

/* The chosen attachments, one per row with its Remove button. */
.attachment-list {
	margin: var(--space-1) 0 0;
	padding: 0;
	list-style: none;
}

.attachment-list[hidden] {
	display: none;
}

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

.page-main .attachment-list li:last-child {
	border-bottom: 1px solid var(--border-subtle);
}

.attachment-name {
	min-width: 0;
	overflow-wrap: anywhere;
}

.attachment-list .small-button {
	margin-top: 0;
}

/* The Reminders Tool's view switch: three real radio buttons, shown as one
   row of pills like the site menu. The buttons themselves are hidden from
   sight only, so screen readers and keyboards use them as radio buttons,
   and the focus ring shows on the pill. */
/* fieldset.view-switch: not the framed, centred box other fieldsets get. */
fieldset.view-switch {
	max-width: none;
	margin: var(--space-2) 0 var(--space-3);
	padding: 0;
	border: 0;
	background: none;
	text-align: left;
}

fieldset.view-switch legend {
	margin: 0 0 var(--space-1);
	padding: 0;
	border: 0;
	color: var(--color-text);
	text-align: left;
}

.view-switch-options {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	padding: 4px;
	border: 1px solid var(--border-subtle);
	/* Rounded, not a pill: on a phone the options stack. */
	border-radius: calc(var(--radius-md) + 4px);
	background: var(--surface-1);
}

.view-switch input[type="radio"] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.view-switch label {
	display: inline-flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 1em;
	border-radius: var(--radius-md);
	color: var(--color-text);
	font-size: var(--fs-ui);
	font-weight: 600;
	text-align: center;
	cursor: pointer;
}

.view-switch label:hover {
	background: var(--surface-2);
}

.view-switch input:checked + label {
	background: var(--accent);
	color: var(--accent-fg);
	border: max(1px, var(--btn-border-width)) solid var(--accent-border);
}

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

/* The Events page's join button: a small Discord icon on a white tile
   (as in the Join Us links), inside the site's own button. */
.cta-icon {
	display: block;
	flex-shrink: 0;
	width: 28px;
	height: 28px;
	padding: 3px;
	border-radius: var(--radius-sm);
	background: #ffffff;
	object-fit: contain;
}

/* Coming Up: the next five events as tiles in a row that scrolls
   sideways, three showing at a time on a wide screen (two on a tablet,
   one and a bit of the next on a phone), each snapping into place. A
   thin scrollbar stays visible so it's clear there's more. */
.coming-up-row {
	--tile-gap: var(--space-2);
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	scroll-padding-inline: 2px;
	padding: 2px 2px var(--space-2);
	border-radius: var(--radius-lg);
	scrollbar-width: thin;
	scrollbar-color: var(--accent) transparent;
}

.coming-up-row:focus-visible {
	outline: 3px solid var(--color-focus);
	outline-offset: 2px;
}

.coming-up-tiles {
	display: flex;
	gap: var(--tile-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

.page-main .coming-up-tiles > li {
	display: flex;
	flex: 0 0 calc((100% - 2 * var(--tile-gap)) / 3);
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-1);
	max-width: none;
	margin: 0;
	padding: var(--space-3);
	border: max(1px, var(--panel-border-width)) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-1);
	scroll-snap-align: start;
}

.coming-up-tiles .event-name {
	font-size: 1.15em;
	line-height: 1.3;
}

/* "Live now." on a tile is a small chip. */
.coming-up-tiles .live-now {
	padding: 0.2em 0.7em;
	border: 1px solid currentColor;
	border-radius: 999px;
	font-size: var(--fs-small);
}

@media (max-width: 900px) {
	.page-main .coming-up-tiles > li {
		flex-basis: calc((100% - var(--tile-gap)) / 2);
	}
}

@media (max-width: 560px) {
	.page-main .coming-up-tiles > li {
		flex-basis: 85%;
	}
}

/* The join button is Discord's own blue (#5865F2), lightening on hover
   the way the site's red buttons do. The other themes keep their own
   button colours, for contrast (see .flat-theme). */
.cta-discord {
	--accent: #5865f2;
	--accent-hover: #6e7af4;
	--accent-fg: #ffffff;
	--accent-hover-fg: #ffffff;
	--cta-shadow: 0 10px 24px rgba(88, 101, 242, 0.35);
	--cta-shadow-hover: 0 14px 30px rgba(88, 101, 242, 0.45);
}

.flat-theme .cta-discord {
	--accent: var(--btn-bg);
	--accent-fg: var(--btn-fg);
	--accent-hover: var(--btn-hover-bg);
	--accent-hover-fg: var(--btn-hover-fg);
	--cta-shadow: none;
	--cta-shadow-hover: none;
}

/* The join button takes the panel's whole width, under the tiles. */
.cta-wide {
	display: flex;
	width: 100%;
}

#coming-up:not([hidden]) + .cta-wide {
	margin-top: var(--space-3);
}

#coming-up .hint {
	margin-bottom: var(--space-2);
}

/* "Live now." on an event a host has started: the word says it, the theme's
   green (the same as "Copied!") only adds to it. */
.live-now {
	font-weight: 700;
	color: var(--color-correct);
}

#events-part[hidden],
#others-part[hidden] {
	display: none;
}

/* A Meeting's own post in the Reminders Tool: its ping choice and extra
   line take a whole row, so the line isn't squeezed beside Remove. */
.attachment-list .post-meeting {
	flex: 1 1 100%;
}

.attachment-list .post-meeting input[type="text"] {
	width: 100%;
}

/* Grouped fields (each resource, "About you"). The base fieldset is built
   for the centred game setup panels; here it is full width and left-aligned
   like the rest of the form. */
.intake-groups {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	width: 100%;
}

.intake fieldset {
	max-width: none;
	text-align: left;
}

.intake legend {
	color: var(--color-text);
	text-align: left;
}

.intake fieldset > div {
	margin-bottom: var(--space-3);
	text-align: left;
}

.intake fieldset > div:last-of-type {
	margin-bottom: 0;
}

/* The bot trap. Off-screen rather than display:none, which some bots skip. */
.hp-field {
	position: absolute;
	left: -10000px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Listed problems after a failed send. The thick border in the theme's
   highlight colour marks it without relying on colour alone. */
.form-problems {
	margin-top: var(--space-3);
	padding: var(--space-2) var(--space-3);
	border: 3px solid var(--color-active);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

.form-problems h3 {
	margin-bottom: var(--space-1);
	color: var(--color-text);
}

.form-problems ul {
	margin: 0;
	padding-left: var(--space-3);
}

/* The thank-you is the only thing left in the panel after a send. */
.form-done {
	margin-top: 0;
}

/* The reference code after a send, set apart so it's easy to find again. */
.form-reference {
	margin: var(--space-2) 0;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

.form-reference p {
	margin: 0 0 var(--space-1);
}

/* "Copied!" beside the Copy button for two seconds: styled like an error
   message, but in the theme's green. */
.copy-flash {
	margin-left: var(--space-2);
	font-weight: 700;
	color: var(--color-correct);
}

.copy-flash[hidden] {
	display: none;
}

.reference-code {
	font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
	letter-spacing: 0.08em;
}

/* Sending: still focusable (a disabled button drops focus), just inert. */
button[aria-disabled="true"] {
	opacity: 0.55;
	cursor: progress;
}

/* A required set of radio buttons (leadership.html). The fieldset is the
   field: its legend is the label, and it carries the hint and error. Laid
   out like the other fields rather than as a game setup panel. */
.intake fieldset.intake-choice {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
}

.intake .intake-choice legend {
	float: none;
	margin: 0;
	padding: var(--space-1) 0;
	border: 0;
	font-size: var(--fs-label);
	font-weight: bold;
	color: var(--color-text);
}

.intake .intake-choice > div {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	margin: 0 0 var(--space-1);
}

.intake .intake-choice input[type="radio"] {
	width: 1.3em;
	min-width: 1.3em;
	height: 1.3em;
	min-height: 0;
	margin: 0;
}

.intake .intake-choice > div label {
	padding: var(--space-1) 0;
	font-size: var(--fs-ui);
	font-weight: 600;
}

/* The chosen role's description (leadership.html), shown open: the
   applicant reads it before agreeing to it. */
.role-description {
	width: 100%;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

.role-description[hidden] {
	display: none;
}

.role-description > h3 {
	margin: 0 0 var(--space-1);
	font-size: var(--fs-h3);
	font-weight: 700;
	color: var(--color-text);
}


/* Contact Us (contact.html). Three equal panels in a row inside the
   Contact Us panel, one column on a phone. They are boxed like the other
   boxes inside a panel (a light fill and a hairline), so every theme shows
   their edges. Each panel's title is its link; the link's ::after stretches
   over the whole panel, so the panel is one large target while a screen
   reader hears only the title as the link. */
.contact-panels {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-3);
	margin-top: var(--space-3);
}

.contact-panel {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: var(--space-3) var(--space-2);
	border: max(1px, var(--panel-border-width)) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-1);
	text-align: center;
	transition: transform .2s ease, box-shadow .2s ease;
}

.contact-panel:hover,
.contact-panel:focus-within {
	transform: translateY(-2px);
	box-shadow: var(--shadow-md), 0 0 0 3px var(--color-focus);
}

.contact-icon {
	width: 64px;
	height: 64px;
	margin-bottom: var(--space-2);
	color: var(--color-link);
}

.contact-panel h3 {
	margin: 0 0 var(--space-1);
	font-size: var(--fs-h3);
	text-align: center;
}

.contact-panel h3 a {
	color: var(--color-text);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

/* A title split over two lines on purpose ("Join the" / "Leadership
   Team"). Spans rather than a <br>, so a screen reader hears one title. */
.contact-panel .title-line {
	display: block;
}

.contact-panel h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--radius-lg);
}

/* The panel shows the focus ring (above), so the link needn't. */
.contact-panel h3 a:focus-visible {
	outline: none;
}

.contact-panel p {
	margin: 0;
	font-size: var(--fs-ui);
	color: var(--color-text-muted);
}

@media (max-width: 760px) {
	.contact-panels {
		grid-template-columns: 1fr;
	}
}


/* ==========================================================================
   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;
}

/* On a game page the footer is only its fine print: no menu, so a host
   mid-game can't swipe or tap onto another page by mistake. Hidden with
   display, so screen readers skip it too. The way out is All Games at the
   top. */
.page-game .footer-inner {
	display: none;
}

.page-game .site-footer {
	padding-top: var(--space-3);
}

.page-game .footer-fine-print {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.container {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	width: 100%;
	max-width: 60rem;
	margin: 0 auto;
	padding: var(--space-3) 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%;
}

/* The way back to Games, at the top left on the Settings button's row and
   drawn like it, since the game pages have no header. */
.game-bar {
	width: min(100%, var(--content-max));
	margin: 0 auto;
	padding: var(--space-3) var(--gutter) 0;
	text-align: left;
}

.page-game .game-back {
	background: var(--chip-bg);
	color: var(--color-text);
	border: max(1px, var(--btn-border-width)) solid var(--chip-border);
	box-shadow: none;
	text-decoration: none;
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

.page-game .game-back:hover,
.page-game .game-back:focus-visible {
	background: var(--btn-hover-bg);
	color: var(--btn-hover-fg);
	border-color: var(--btn-hover-bg);
}

.game-column > h1 {
	margin-bottom: 0;
}

/* A game's opening line for the host (Password, Tri-Bond). */
.game-column > h1 + .hint {
	max-width: 36rem;
	margin-top: calc(-1 * var(--space-2));
	font-size: var(--fs-ui);
}

/* Before the game the question box is empty but still in the column (it
   must stay focusable); this takes back the gap it would add. */
#question-container:has(#question:empty) {
	margin-top: calc(-1 * var(--space-4));
}

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

/* --- Setup panel ----------------------------------------------------------
   A game's setup (#game-selector) and the Repeater's controls are one panel,
   coloured like the main site's: the options top to bottom, each under a
   small label, and Start Game at the foot, so the page reads in one
   direction: choose, then start. */
#game-selector,
.game-panel {
	width: 100%;
	max-width: 36rem;
	padding: var(--space-4);
	background: var(--panel-bg);
	border: var(--panel-border-width) solid var(--panel-border);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md), var(--panel-highlight);
	text-align: left;
}

#game-selector > legend {
	margin: 0 0 var(--space-3);
	padding: 0;
	border: 0;
	font-family: var(--font-display);
	font-variation-settings: "SOFT" 100, "WONK" 0;
	font-size: var(--fs-h2);
	font-weight: 650;
	letter-spacing: -0.015em;
	color: var(--color-text);
	text-align: left;
}

/* One gap between groups, whatever each group is made of. */
#game-selector > *,
#game-selector > div,
game-options > * {
	margin: 0;
	text-align: left;
}

#game-selector .radio-group > div:last-child,
#game-selector .setup-check {
	margin-bottom: 0;
}

#game-selector > :not(legend) + *,
game-options > * + * {
	margin-top: var(--space-3);
}

/* A group's label: Game Type, Question Set, Categories, Timer. Trivia's two
   are headings, the rest legends; they look alike. */
#game-selector h2,
fieldset.setup-option legend {
	margin: 0 0 var(--space-1);
	font-family: inherit;
	font-variation-settings: normal;
	font-size: var(--fs-label);
	font-weight: 700;
	letter-spacing: 0;
	color: var(--color-heading);
	text-align: left;
}

#game-selector .radio-group {
	display: block;
	margin: 0;
}

#game-selector select {
	width: min(100%, 24rem);
}

#game-selector .picker-panel {
	margin-inline: 0;
}

#game-selector .form-error {
	margin-inline: 0;
}

/* Start Game: the panel's last step, full width and filled, like the main
   site's main call to action. */
#game-selector > #start-game,
.game-panel #startButton {
	width: 100%;
	min-height: 52px;
	margin-top: var(--space-4);
	background: var(--accent);
	color: var(--accent-fg);
	border: max(1px, var(--btn-border-width)) solid var(--accent-border);
	box-shadow: var(--cta-shadow);
	font-size: var(--fs-label);
	font-weight: 700;
}

#game-selector > #start-game:hover,
#game-selector > #start-game:focus-visible,
.game-panel #startButton:hover,
.game-panel #startButton:focus-visible {
	background: var(--accent-hover);
	color: var(--accent-hover-fg);
	box-shadow: var(--cta-shadow-hover);
}

.game-panel .field {
	align-items: stretch;
	width: 100%;
	margin-bottom: var(--space-3);
}

.page-game .game-panel textarea,
.page-game .game-panel input[type="number"] {
	width: 100%;
}

.page-game .game-panel input[type="number"] {
	max-width: 12rem;
}

.game-panel #button-container {
	margin: var(--space-4) 0 0;
}

.game-panel #startButton {
	margin-top: 0;
}

.game-panel #stopButton {
	width: 100%;
	min-height: 52px;
	font-size: var(--fs-label);
}

/* --- 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);
}

/* The line above the question: its category, or "Tri-Bond 3 of 40". */
#question-category,
#question-progress {
	margin: 0 0 var(--space-2);
	font-size: var(--fs-small);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-heading);
}

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

/* #question takes focus each time it changes (see question-game.js), so it
   is never hidden: a hidden element cannot take focus. Like #timer, it
   simply carries no panel styling until it holds 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);
	background: var(--panel-bg);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md), var(--panel-highlight);
}

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

/* The choices as tiles: two to a row where they fit, one on a phone. */
#choices {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, max(14rem, 40%)), 1fr));
	gap: var(--space-2);
	margin: var(--space-4) 0 0;
	font-size: var(--fs-body);
	font-weight: 600;
	line-height: 1.35;
	text-align: left;
}

#choices:empty {
	display: none;
}

#choices p,
#clues li {
	margin: 0;
	padding: var(--space-2) var(--space-3);
	background: var(--surface-1);
	border: max(1px, var(--panel-border-width)) solid var(--border-subtle);
	border-radius: var(--radius-md);
}

/* Password's clues: each item carries its own "Clue 2:" text for screen
   readers, so the list's own numbers are switched off. */
#clues {
	display: grid;
	gap: var(--space-1);
	margin: var(--space-4) 0 0;
	padding: 0;
	list-style: none;
	font-size: var(--fs-body);
	font-weight: 600;
	line-height: 1.35;
	text-align: left;
}

#clues:empty {
	margin: 0;
}

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

#clue-worth {
	margin-top: var(--space-1);
}

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

/* Empty before the game and with the timer Off; left in the column it would
   still add a gap. */
#timer:empty {
	display: none;
}

/* --- 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. */
town-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(--panel-bg);
	border: var(--panel-border-width) solid var(--panel-border);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md), var(--panel-highlight);
	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;
	transition: background .2s ease, color .2s ease;
}

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

/* A game's setup options (<game-options>, drawn by question-game.js): the
   timer choice, shaped like the scoreboard's, and the scoreboard checkbox.
   The inner fieldset is only a group, not another panel. */
game-options {
	display: block;
}

fieldset.setup-option {
	width: auto;
	max-width: none;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
}

fieldset.setup-option legend {
	float: none;
	width: 100%;
	margin: 0 0 var(--space-1);
	padding: 0;
	border: 0;
}

fieldset.setup-option .segmented-options:has(> input[type="radio"]) {
	display: inline-flex;
	margin: 0;
}

/* The checkbox sits right beside its label, even when the label wraps on a
   phone. */
.setup-check {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}

.setup-check input {
	flex-shrink: 0;
	margin: 0;
}

.setup-check label {
	text-align: left;
}

.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-team-tools {
	margin-top: var(--space-1);
}

.sb-team-tools:empty {
	display: none;
}

.sb-manage-random {
	margin: 0 0 var(--space-3);
}

.team-card [data-action="random-spokesperson"] {
	margin-bottom: var(--space-1);
}

.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-post[hidden],
.sb-post [hidden],
.sb-ot[hidden] {
	display: none;
}

/* Share the Results: the game list (Scoreboard page only), then Copy
   Results with its "Copied!", and the text to copy by hand if the browser
   wouldn't. */
.sb-post {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-2);
	text-align: center;
}

.sb-post h3,
.sb-post .hint {
	margin: 0;
}

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

.sb-post-name select {
	width: 100%;
}

.sb-copy-row {
	display: flex;
	align-items: center;
	justify-content: center;
}

.sb-copy-fallback {
	width: 100%;
	text-align: left;
}

.sb-copy-fallback textarea {
	display: block;
	width: 100%;
	margin-top: var(--space-1);
}

/* 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; on anything narrower they stack, with the board folded
   under a button. On a wide screen the board stays in view and scrolls in
   its own box, with that box's scrollbar hidden: beside the page's own it
   was redundant and confusing. The wheel, touch and keyboard still scroll
   it. */
.game-column {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	width: 100%;
	min-width: 0;
}

.sb-embed {
	width: 100%;
}

/* The fold's own top margin (as a disclosure) would double the column's gap. */
.sb-embed > .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;
		scrollbar-width: none;
	}

	.with-scoreboard .sb-embed::-webkit-scrollbar {
		display: none;
	}
}

.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 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;
	transition: background .2s ease, color .2s ease, border-color .2s ease;
}

.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) {
	/* A smaller Settings button and name, so the name keeps to two lines
	   beside it on a phone. */
	#accessibility-button {
		top: var(--space-2);
		padding: 0 var(--space-2);
		font-size: var(--fs-small);
	}

	#accessibility-panel {
		top: calc(var(--space-2) + 52px);
	}

	/* All Games matches the Settings button opposite it. */
	.game-bar {
		padding-top: var(--space-2);
	}

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

	.site-header {
		padding-top: var(--space-2);
	}

	.brand {
		padding-right: 8rem;
		font-size: var(--fs-label);
	}

	.brand-link {
		gap: var(--space-1);
	}

	.brand-logo {
		width: 40px;
		height: 40px;
	}

	.site-nav ul {
		border-radius: var(--radius-lg);
	}

	.site-nav a {
		padding: 0 0.85em;
	}

	.lead {
		font-size: 1em;
	}

	.normalsection,
	.podcastsection {
		padding: var(--space-3) var(--space-2);
	}

	.card,
	.step,
	.faq-item {
		padding: var(--space-2);
	}
}

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

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

	#game-selector,
	.game-panel,
	#question-container:has(#question:not(:empty)) {
		padding: 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);
	}
}

/* ==========================================================================
   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.
   ========================================================================== */

/* Every theme but the default also gets the flat-theme class (site.js).
   It drops the redesign's glows, glass and highlights in favour of each
   theme's own text, button and border colours, so the themes stay flat and
   high in contrast. It comes before the themes, so a theme can still set
   any of these itself. */
.flat-theme {
	--panel-highlight: 0 0 0 0 transparent;
	--color-heading: var(--color-text);
	--accent: var(--btn-bg);
	--accent-fg: var(--btn-fg);
	--accent-hover: var(--btn-hover-bg);
	--accent-hover-fg: var(--btn-hover-fg);
	--accent-border: var(--btn-border);
	--chip-bg: var(--surface-1);
	--chip-border: var(--border-subtle);
	--nav-bg: var(--panel-bg);
	--shadow-md: none;
	--shadow-lg: none;
	--cta-shadow: none;
	--cta-shadow-hover: none;
}

/* The opening panels' glow and the home page's logo watermark go too. */
.flat-theme .page-main .hero,
.flat-theme .page-main .page-intro {
	background: var(--panel-bg);
}

.flat-theme .hero-mark {
	display: none;
}

/* With flat fills the current page's pill matches the bar around it, so it
   gets a thick outline in the theme's text colour instead. */
.flat-theme .site-nav a[aria-current="page"] {
	box-shadow: inset 0 0 0 3px var(--color-text);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.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; --control-scheme: light;
	--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; --control-scheme: light;
	--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; --control-scheme: light;
	--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 Spokesperson/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%;
	}
}

/* Control Panel pages (manage-agenda.html, manage-reminders.html), opened
   from the control panel channel in Discord. Built on the intake form styles; these
   add the lists of items and reminders, each with a row of small action
   buttons under it. */

.manage-list {
	max-width: 42rem;
	margin: var(--space-2) 0 0;
	padding: 0;
	list-style: none;
}

ol.manage-list {
	padding-left: var(--space-3);
	list-style: decimal;
}

.page-main .manage-list > li {
	margin: 0;
	padding: var(--space-2) 0;
	border-top: 1px solid var(--border-subtle);
}

.page-main .manage-list > li:last-child {
	border-bottom: 1px solid var(--border-subtle);
}

.manage-list h4,
.manage-list p {
	margin: 0 0 var(--space-1);
}

.manage-list h4 {
	color: var(--color-text);
}

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

.manage-actions[hidden] {
	display: none;
}

/* "Paused" and a reminder's problems: bold in the highlight colour, and
   said in words, so colour is never the only sign. */
.manage-flag {
	font-weight: 700;
	color: var(--color-active);
}

/* A short note after a change, with a button to undo it or confirm. */
.manage-notice {
	max-width: 42rem;
	margin: var(--space-2) 0;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-1);
}

.manage-notice[hidden] {
	display: none;
}

.manage-notice p {
	margin: 0 0 var(--space-1);
}

/* A label, its control and a button side by side (Add a person, Add a
   date), wrapping on a phone. */
.manage-row {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--space-1) var(--space-2);
	width: 100%;
}

.manage-row > div {
	flex: 1 1 14rem;
	min-width: 0;
}

.manage-section[hidden],
.manage-body[hidden] {
	display: none;
}

/* The Reminders Tool's list: a tile for each reminder, in a grid that
   becomes one column on a phone. Each tile is one button. */
.manage-view {
	margin: var(--space-2) 0;
}

.manage-check {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	min-height: 44px;
}

.reminder-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: var(--space-2);
	margin: var(--space-2) 0 var(--space-3);
	padding: 0;
	list-style: none;
}

.page-main .reminder-tiles > li {
	margin: 0;
	padding: 0;
}

.reminder-tile {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-start;
	gap: var(--space-1);
	width: 100%;
	height: 100%;
	min-height: 6rem;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	background: var(--surface-1);
	color: var(--color-text);
	box-shadow: none;
	font-weight: 400;
	line-height: 1.4;
	text-align: left;
}

.reminder-tile-name {
	font-weight: 700;
}

/* A reminder's message, with its line breaks. */
.manage-message {
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}
