@charset "UTF-8";

/*
	app.css -- the site's stylesheet. Replaces skel.css, style.css and the three
	breakpoint sheets, which remain only for the static pages still on the old
	chrome.

	Two rules hold throughout. No `px` except hairlines and image dimensions, so
	the text-size control scales the layout with the text. No colour outside the
	token blocks below, so a theme is a change in one place.

	See development/CHROME-REDESIGN.md for the design this implements.
*/

/* ===========================================================================
	0. Open Sans, served from this origin

	Google Fonts is blocked in parts of the world, and it was the shell's only
	external dependency. One VARIABLE face covers 400-700, so the three weights
	the site uses are two files: `latin` and the accents in `latin-ext`.
   =========================================================================== */

@font-face {
	font-family: 'Open Sans';
	font-style: normal;
	font-weight: 400 700;
	font-stretch: 100%;
	font-display: swap;
	src: url('/fonts/open-sans-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: 'Open Sans';
	font-style: normal;
	font-weight: 400 700;
	font-stretch: 100%;
	font-display: swap;
	src: url('/fonts/open-sans-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-20C0, U+2113, U+2C60-2C7F,
		U+A720-A7FF;
}

/* ===========================================================================
	1. Tokens -- light is the default and lives on bare :root
   =========================================================================== */

:root {
	color-scheme: light;

	--bg: #f2f3f4;
	--panel: #ffffff;
	--rule: #e2e4e6;
	--ink: #1c1c1c;
	--ink-strong: #333333;
	--ink-dim: #5f6469;
	/* The award blue. A page of an index is mostly links, and the old cyan-ish
	   #0077a8 buzzed at that density; this reads calmer at 6.8:1 on the panel. */
	--link: #1857b8;
	--link-hover: #0f3c86;
	--link-underline: rgba(24, 87, 184, 0.35);
	--brand: #880000;
	--brand-ink: #ffffff;
	--award-win: #1857b8;
	--award-nom: #c2261c;
	--focus: #0077a8;

	/* `index.html`'s three button roles. The blue is a step darker than the
	   template's #0090c5, which carried 3.6:1 against its own white label. */
	--btn-bg: #0077a8;
	--btn-bg-hover: #005a80;
	--btn-ink: #ffffff;
	--btn-alt-bg: #ececec;
	--btn-alt-bg-hover: #dedede;
	--btn-alt-ink: #444444;
	--btn-alt2-bg: #ffff00;
	--btn-alt2-bg-hover: #ffff66;
	--btn-alt2-ink: #444444;

	--font-body: 'Open Sans', -apple-system, 'Segoe UI', sans-serif;
	--font-logo: 'Times New Roman', Times, serif;

	--scale: 1;
	--gutter: 1.25rem;
	--radius: 6px;

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

	--shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

/*
	The system's preference, unless the reader has explicitly asked for light.
	This block and the next are identical; plain CSS has no way to share them, and
	splitting the selectors would lose the `:not()` that makes `light` win.
*/
@media (prefers-color-scheme: dark) {
	:root:not([data-theme='light']) {
		color-scheme: dark;

		--bg: #0e0f12;
		--panel: #16181d;
		--rule: #2a2e35;
		--ink: #e6e7e9;
		--ink-strong: #f4f5f6;
		--ink-dim: #a3a8af;
		--link: #8db4ff;
		--link-hover: #b6cfff;
		--link-underline: rgba(141, 180, 255, 0.4);
		--award-win: #7aa9ff;
		--award-nom: #ff8a80;
		--focus: #6cc4ec;

		--btn-alt-bg: #2a2e35;
		--btn-alt-bg-hover: #363b44;
		--btn-alt-ink: #e6e7e9;
		--btn-alt2-bg: #e0cc00;
		--btn-alt2-bg-hover: #f0dc20;
		--btn-alt2-ink: #1c1c1c;

		--shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
	}
}

:root[data-theme='dark'] {
	color-scheme: dark;

	--bg: #0e0f12;
	--panel: #16181d;
	--rule: #2a2e35;
	--ink: #e6e7e9;
	--ink-strong: #f4f5f6;
	--ink-dim: #a3a8af;
	--link: #8db4ff;
	--link-hover: #b6cfff;
	--link-underline: rgba(141, 180, 255, 0.4);
	--award-win: #7aa9ff;
	--award-nom: #ff8a80;
	--focus: #6cc4ec;

	--btn-alt-bg: #2a2e35;
	--btn-alt-bg-hover: #363b44;
	--btn-alt-ink: #e6e7e9;
	--btn-alt2-bg: #e0cc00;
	--btn-alt2-bg-hover: #f0dc20;
	--btn-alt2-ink: #1c1c1c;

	--shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

/* The seven-step text ladder, reproducing the old 9pt-15pt from a 12pt base. */
:root[data-font='-3'] { --scale: 0.75; }
:root[data-font='-2'] { --scale: 0.833; }
:root[data-font='-1'] { --scale: 0.917; }
:root[data-font='1'] { --scale: 1.083; }
:root[data-font='2'] { --scale: 1.167; }
:root[data-font='3'] { --scale: 1.25; }

/* ===========================================================================
	2. Reset -- margins and the box model only

	Typography is left to the UA sheet and to section 3, so `em`, `cite` and
	`strong` need no restoration. `[role="list"]` is what stops Safari dropping
	list semantics when the marker is removed.
   =========================================================================== */

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

body {
	margin: 0;
}

/* `[hidden]` is the UA's own rule and any author `display` outranks it, so the
   sheet has to say it again to mean it. */
[hidden] {
	display: none !important;
}

h1, h2, h3, h4, h5, h6, p, dl, dd, figure, blockquote {
	margin: 0;
}

ul[role='list'],
ol[role='list'] {
	list-style: none;
	padding: 0;
	margin: 0;
}

img, picture, video, audio {
	max-width: 100%;
}

input, button, textarea, select {
	font: inherit;
	color: inherit;
}

table {
	border-collapse: collapse;
}

/* ===========================================================================
	3. Base typography
   =========================================================================== */

html {
	font-size: calc(100% * var(--scale));
	scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
}

body {
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font-body);
	font-weight: 400;
	line-height: 1.5;
}

h1, h2, h3, h4, h5, h6 {
	color: var(--ink-strong);
	font-weight: 700;
	line-height: 1.2;
}

/* Smaller on a phone, where a full-size heading costs four lines. Section 6
   hands the wide size back. */
h1 { font-size: 1.35rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.15rem; }
h4 { font-size: 1rem; }

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

/* The underline is drawn back, so a list that is almost all links does not read
   as a solid rule; hovering firms it up rather than jumping colour. */
a {
	color: var(--link);
	text-decoration: underline;
	text-decoration-color: var(--link-underline);
	text-underline-offset: 0.15em;
	transition: color 0.12s ease-in-out, text-decoration-color 0.12s ease-in-out;
}

a:hover {
	color: var(--link-hover);
	text-decoration-color: currentColor;
}

/*
	Emphasis TOGGLES: italic inside upright, upright inside italic. The first rule
	duplicates the UA sheet and is kept so the set reads as one block -- do not
	remove these as redundant, they are what the story pages rely on.
*/
:is(em, cite, i) {
	font-style: italic;
}

:is(em, cite, i) :is(em, cite, i) {
	font-style: normal;
}

:is(em, cite, i) :is(em, cite, i) :is(em, cite, i) {
	font-style: italic;
}

b, strong {
	font-weight: 600;
	color: var(--ink-strong);
}

hr {
	border: 0;
	border-block-start: 1px solid var(--rule);
	margin-block: var(--space-3);
}

:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 2px;
}

/* ===========================================================================
	4. Utilities
   =========================================================================== */

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

/* Visible only once focused, which is the whole point of a skip link. */
.skip {
	position: absolute;
	inset-inline-start: var(--space-2);
	inset-block-start: -4rem;
	z-index: 20;
	padding: var(--space-2) var(--space-3);
	background: var(--panel);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	transition: inset-block-start 0.15s ease-in-out;
}

.skip:focus {
	inset-block-start: var(--space-2);
}

.loading {
	color: var(--ink-dim);
}

/* ===========================================================================
	5. Layout

	Only `main` needs the full-bleed treatment, because only `main` paints a
	panel: the three-column grid lets the background reach the window edges while
	its children stay on the measure. A child spans it with `grid-column: 1/-1`.
   =========================================================================== */

.site-header,
.site-footer {
	max-width: 75rem;
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.site-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
	padding-block: var(--space-3);
}

main {
	display: grid;
	grid-template-columns: 1fr min(75rem, 100% - 2 * var(--gutter)) 1fr;
	background: var(--panel);
	padding-block: var(--space-5);
	box-shadow: var(--shadow);
	/* A hub, a random link or a not-found is shorter than the window, and the
	   footer should not sit halfway up it. */
	min-height: 50vh;
	/* WITHOUT THIS the min-height above stretches every row to fill it, so a
	   short page pads the gaps between its own headings instead of ending. */
	align-content: start;
}

main > * {
	grid-column: 2;
	/* A grid item is min-content wide by default, so one wide child would push
	   the whole document sideways instead of scrolling itself. */
	min-width: 0;
}

/* `index.html` paints nothing behind its banner and news row, so the page's own
   gray shows around and between the white boxes rather than one panel holding
   both. */
body[data-page='home'] main {
	background: none;
	box-shadow: none;
	padding-block: var(--space-4);
}

/* Home has no panel: the gap under the menu is the page's own gray, the same
   gap as between the white boxes below. `main` spends it, so the header does
   not spend it too. */
body[data-page='home'] .site-header {
	padding-block-end: 0;
}

/* Narrow, the menu stacks under the logo at `--space-2`, and `main` is the next
   thing down that stack. Two rules because home's header pays nothing below
   itself while every other page's `main` pays inside its panel. */
@media screen and (max-width: 47.99rem) {
	.site-header {
		padding-block-end: var(--space-2);
	}

	body[data-page='home'] main {
		padding-block-start: var(--space-2);
	}
}

/* --- Logo ---------------------------------------------------------------- */

.site-logo {
	margin: 0;
	background: var(--brand);
	border-radius: var(--radius);
	padding: 0.15em 0.4em;
	font-family: var(--font-logo);
	/* Smaller on a phone, where the archive's name would wrap inside its red
	   box. Section 6 restores it. */
	font-size: 1.45rem;
	line-height: 1.25;
}

.site-logo a {
	color: var(--brand-ink);
	text-decoration: none;
}

.site-logo img {
	vertical-align: text-top;
}

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

/* FOUR COLUMNS AT MOST, and the count is decided here rather than in the data:
   the track floor is a quarter of the width, so the groups `footer.json` names
   and the display controls that follow them wrap into four, three, two or one
   as the space allows. Four rather than three is what leaves the controls --
   the footer's last child -- in the right-most column beside the groups, not
   stranded on a row of their own below them. */
.site-footer {
	display: grid;
	grid-template-columns: repeat(
		auto-fit,
		minmax(max(14rem, calc((100% - 3 * var(--space-4)) / 4)), 1fr)
	);
	gap: var(--space-4);
	padding-block: var(--space-5) var(--space-6);
	color: var(--ink-dim);
}

.site-footer h2 {
	font-size: 1rem;
	margin-block-end: var(--space-2);
}

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

.site-footer li {
	margin-block-end: var(--space-1);
}

.site-footer a {
	color: inherit;
}

.site-colophon {
	grid-column: 1 / -1;
	border-block-start: 1px solid var(--rule);
	padding-block-start: var(--space-3);
	text-align: center;
	font-size: 0.85em;
}

/* --- Display controls ---------------------------------------------------- */

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

.display-controls button {
	background: var(--panel);
	color: var(--ink-strong);
	border: 1px solid var(--rule);
	border-radius: var(--radius);
	padding: 0.3em 0.7em;
	cursor: pointer;
}

.display-controls button[aria-pressed='true'] {
	background: var(--ink-strong);
	color: var(--panel);
	border-color: var(--ink-strong);
}

/* --- Back to top --------------------------------------------------------- */

.to-top {
	position: fixed;
	inset-block-end: var(--space-3);
	inset-inline-end: var(--space-3);
	z-index: 15;
	background: var(--panel);
	color: var(--ink-strong);
	border: 1px solid var(--rule);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	padding: var(--space-2) var(--space-3);
	text-decoration: none;
	font-size: 0.85em;
}

.to-top:hover {
	color: var(--ink-strong);
	border-color: var(--ink-dim);
}

/* --- Buttons ------------------------------------------------------------- */

/* A bare button takes the archive's blue: on a white panel a white-on-white
   control is something a reader has to go looking for. */
button {
	background: var(--btn-bg);
	color: var(--btn-ink);
	border: 0;
	border-radius: var(--radius);
	padding: 0.35em 0.9em;
	font-weight: 600;
	cursor: pointer;
	transition: background-color 0.15s ease-in-out;
}

button:hover {
	background: var(--btn-bg-hover);
}

.button,
input[type='submit'],
input[type='button'],
button.button {
	display: inline-block;
	background: var(--btn-bg);
	color: var(--btn-ink);
	border: 0;
	border-radius: var(--radius);
	padding: 0.5em 1.2em;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.15s ease-in-out;
}

.button:hover,
input[type='submit']:hover {
	background: var(--btn-bg-hover);
	color: var(--btn-ink);
}

/* `index.html`'s other two roles: a quiet one and the archive's yellow. */
.button.alt {
	background: var(--btn-alt-bg);
	color: var(--btn-alt-ink);
}

.button.alt:hover {
	background: var(--btn-alt-bg-hover);
	color: var(--btn-alt-ink);
}

.button.alt2 {
	background: var(--btn-alt2-bg);
	color: var(--btn-alt2-ink);
}

.button.alt2:hover {
	background: var(--btn-alt2-bg-hover);
	color: var(--btn-alt2-ink);
}

/* ===========================================================================
	6. Wide screens
   =========================================================================== */

@media screen and (min-width: 48rem) {
	:root {
		--gutter: 2rem;
	}

	/* The full sizes; sections 3 and 5 hold the narrow ones. */
	h1 {
		font-size: 1.9rem;
	}

	.site-logo {
		font-size: 2.1rem;
	}
}

/* ===========================================================================
	7. The criteria form (/browse/filter and /browse/database, from views/criteriaform.js)
   =========================================================================== */

.criteria-form {
	margin: 0 0 var(--space-4) 0;
}

.criteria-form fieldset {
	border: 0;
	margin: 0 0 1.25em 0;
	padding: 0;
	min-width: 0; /* a fieldset defaults to min-content, which breaks grid children */
}

.criteria-form legend {
	padding: 0;
	font-weight: bold;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: 0.85em;
	color: var(--ink-dim);
}

.criteria-row {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.35em 0.75em;
	align-items: baseline;
	margin: 0 0 0.5em 0;
}

.criteria-row > label:first-child,
.criteria-row > .criteria-label {
	grid-column: 1;
	font-weight: bold;
}

.criteria-row > .criteria-control {
	min-width: 0;
}

.criteria-form input[type='search'],
.criteria-form input[type='text'],
.criteria-form select {
	max-width: 100%;
	background: var(--panel);
	color: var(--ink);
	border: 1px solid var(--rule);
	border-radius: var(--radius);
	padding: 0.35em 0.5em;
}

.criteria-form input[type='search'],
.criteria-form input[type='text'] {
	width: 100%;
}

.criteria-note {
	margin: 0;
	font-size: 0.85em;
	color: var(--ink-dim);
}

/* The year pair is ONE criterion, so it is one row: `Uploaded [from] to [to]`. */
.criteria-range {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5em;
}

/* Checkbox groups wrap inline instead of stacking: five tiers are one question. */
.criteria-checks {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35em 1.25em;
}

.criteria-checks label {
	display: inline-flex;
	align-items: baseline;
	gap: 0.35em;
	font-weight: normal;
	white-space: nowrap;
}

.criteria-footer {
	margin: 0.5em 0 0 0;
}

@media screen and (min-width: 48rem) {
	.criteria-row {
		grid-template-columns: 11em 1fr;
	}

	.criteria-row > .criteria-control {
		grid-column: 2;
	}

	.criteria-note {
		grid-column: 2;
	}

	.criteria-form input[type='search'],
	.criteria-form input[type='text'] {
		width: 22em;
	}
}

@media screen and (min-width: 75rem) {
	.criteria-groups {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 0 var(--space-5);
		align-items: start;
	}

	.criteria-row {
		grid-template-columns: 9em 1fr;
	}

	.criteria-form input[type='search'],
	.criteria-form input[type='text'] {
		width: 100%;
	}
}

/* ===========================================================================
	8. The datagrid's scroll container
   =========================================================================== */

/* Fourteen columns are wider than any measure, so the TABLE scrolls and the
   page does not: full width, and its own scroll container. */
.datagrid-wrap {
	grid-column: 1 / -1;
	overflow-x: auto;
	padding-inline: var(--gutter);
}

.datagrid th,
.datagrid td {
	padding: 0.3em 0.6em;
	border-block-end: 1px solid var(--rule);
	text-align: start;
	vertical-align: top;
	white-space: nowrap;
}

/* ===========================================================================
	9. The story row

	An <article> per story: a heading, a <dl> of what the archive records, and
	the author's summary. The heading level is its container's, so the size is
	set by structure rather than by level.
   =========================================================================== */

.story + .story {
	margin-block-start: var(--space-3);
}

.story > :is(h2, h3, h4, h5) {
	font-size: 1.1rem;
	font-weight: 600;
	margin: 0;
	line-height: 1.35;
}

.story-meta {
	margin: 0;
	line-height: 1.55;
}

/* A visible term floats so its description sits beside it; a hidden one is out
   of flow, so its description starts at the left edge as it always did. */
.story-meta dt {
	float: left;
	clear: left;
	margin-inline-end: 0.35em;
}

.story-meta dd {
	margin: 0;
}

/* A hidden description may hold a real link -- the recording's. Focusing it
   must show it, or a keyboard reader lands somewhere invisible. */
.story-meta dd.sr-only:focus-within {
	position: static;
	width: auto;
	height: auto;
	clip-path: none;
}

.story-blurb {
	margin-block: 0.35em 0;
}

.story-note {
	margin-block: 0.35em 0;
	font-size: 0.9em;
}

/* --- Row icons ----------------------------------------------------------- */

/* One gutter for the whole run, where each builder used to gutter its first. */
.story-icons {
	margin-inline-start: 0.6em;
	white-space: nowrap;
}

.story-icon,
.story-language,
.award-badge {
	margin-inline-start: 0.25em;
}

/* The two person glyphs are one icon showing two people, so nothing separates
   them — only the first of the pair takes the gap. */
.story-icon--author + .story-icon--author {
	margin-inline-start: 0;
}

.award-badge--winner { color: var(--award-win); }
.award-badge--nominee { color: var(--award-nom); }
.award-badge--gold { color: #b8860b; }
.award-badge--silver { color: #8a8a8a; }
.award-badge--bronze { color: #8c5a2b; }
.award-badge--mention { color: #3f7d3f; }

/* The one badge that PRECEDES what it labels, on an award year page. */
.award-badge--leading {
	margin-inline: 0 0.5em;
}

.audiofic-link {
	margin-inline-start: 0.5em;
	text-decoration: none;
}

/* --- The sample player, on #/audiofic ------------------------------------ */

audio {
	display: block;
	width: 100%;
	max-width: 28rem;
	margin-block: 0.35em 0;
}

/* The player sits BETWEEN two rows, which is why `.story + .story` cannot
   reach them: it is a sibling of both, not a line inside one. */
audio + .story {
	margin-block-start: var(--space-3);
}

/* --- What an owner states about ITSELF ----------------------------------- */

/* A series' or an author's own facts. Every TERM is `sr-only` and so out of
   flow, which is why there is no label column to lay out. */
.owner-meta {
	margin-block-end: var(--space-3);
	display: grid;
	gap: 0.4em;
}

.owner-meta dd {
	margin: 0;
}

.owner-meta .award-badge {
	margin-inline: 0 0.5em;
}

/* --- The way back up ----------------------------------------------------- */

/* Above the `h1`, so it reads as the step out of this page rather than as
   something the page says. */
.back-link {
	margin-block-end: var(--space-2);
	font-size: 0.9em;
}

.back-link a {
	text-decoration: none;
}

.back-link a:hover {
	text-decoration: underline;
}

/* ===========================================================================
	10. Listings, entries and rules
   =========================================================================== */

/* Fewer, wider columns than the old 200px float: most entries carry a count or
   a byline as well as a name. One column, full width, on a phone. */
.cell-list {
	columns: 1;
	column-gap: 1.5rem;
	list-style: none;
	margin: 0 0 var(--space-3) 0;
	padding: 0;
}

/* The grid's row gap, and the guarantee that a cell that wraps to two lines is
   not split across the column break. */
.cell-list li {
	break-inside: avoid;
	margin-block-end: 0.1rem;
}

@media screen and (min-width: 48rem) {
	.cell-list {
		columns: 18rem;
	}

	/* A series cell reads as a sentence -- a name, a count and sometimes a
	   co-author -- so it takes a line. The roster above them is names. */
	body[data-route='series'] .group .cell-list {
		columns: 1;
	}
}

/* The cell for the page you are already on, marked the way the link bar marks
   its own — a listing that includes itself has to say which one is itself. */
.cell-list a[aria-current='page'] {
	font-weight: 700;
	text-decoration: none;
}

.jump-list {
	margin-block-end: var(--space-3);
}

/* Thirty-eight entries, each a link and a sentence about it. As one paragraph
   of line breaks they read as a blob, so each is its own item. */
.sitemap-list {
	margin: 0 0 var(--space-3) 0;
	padding: 0;
}

.sitemap-list li {
	margin-block-end: var(--space-2);
}

/* One line naming a thing, on the award pages. */
.entry {
	margin-block-end: 0.2em;
}

.arrow-heading {
	margin-block: var(--space-3) 0.25em;
}

/* The arrow is the only thing marking these as links, so hovering has to say
   so the way every other link does. */
.arrow-heading a {
	text-decoration: none;
}

.arrow-heading a:hover {
	text-decoration: underline;
}

/* The rule sits BEFORE a group, not between two -- so the first one is parted
   from the page's own jump list as well, which the author index needed. */
.group {
	border-block-start: 1px solid var(--rule);
	margin-block-start: var(--space-4);
	padding-block-start: var(--space-4);
}

/* NOT REDUNDANT with the margin above. `.story + .story` is two classes to that
   rule's one, so a group that is ALSO a row -- `#/news` -- took the row spacing
   and sat 16px from its rule instead of 24. Same value, enough weight to hold. */
.group + .group {
	margin-block-start: var(--space-4);
}

/* The author view's `Series`/`Stories` sub-headings (CHROME-REDESIGN §2.2). */
.section-label {
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--ink-dim);
	margin-block: var(--space-3) var(--space-1);
}

.series-list {
	margin: 0 0 var(--space-3) 0;
	padding: 0;
}

/* A Kerth category's runs (CHROME-REDESIGN §2.7). The term is all that divides
   two lists of entries, so it takes `.section-label`'s treatment, not an entry's. */
.award-run dt {
	margin-block-start: var(--space-2);
	font-size: 0.85em;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--ink-dim);
}

.award-run dt:first-child {
	margin-block-start: 0;
}

.award-run dd {
	margin-inline-start: 0;
}

/* ===========================================================================
	11. The link bar -- letters, years and the month jump list

	One component, because they are one kind of navigation: a row of
	destinations with the current one marked. The separators are drawn here
	rather than being text nodes between the links.
   =========================================================================== */

.link-bar {
	margin-block-end: var(--space-3);
}

.link-bar ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.15em 0.5em;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* At the END of an item, so a wrapped row starts flush with the one above it
   instead of stepping in and out by the width of a pipe. */
.link-bar li:not(:last-child)::after {
	content: '|';
	margin-inline-start: 0.5em;
	color: var(--rule);
}

.link-bar a[aria-current='page'] {
	font-weight: 700;
	text-decoration: none;
}

.link-bar--large {
	font-size: 1.5rem;
}

/* The sortable column headings: controls, not destinations, so they carry a
   role rather than an href -- and the pointer comes from here, not inline. */
.datagrid-sort {
	cursor: pointer;
}

/* ===========================================================================
	12. #/home -- the banner and the news row

	Two white boxes on the page's own gray, as `index.html` has them. No skel
	grid: the banner is a three-area grid and the news row auto-fits.
   =========================================================================== */

.banner,
.news-item {
	background: var(--panel);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}

.banner {
	display: grid;
	gap: var(--space-4);
	padding: var(--space-4);
	margin-block-end: var(--space-4);
}

/* Its own size, so its own narrow value; the 48rem block below restores it. */
.banner h1 {
	font-size: 1.05rem;
	margin-block-end: var(--space-2);
}

.home-total {
	font-size: 1.3rem;
	color: var(--ink-strong);
}

.home-lede {
	margin-block: var(--space-3) var(--space-2);
}

.upload-group {
	margin-block-end: var(--space-3);
}

.upload-group h2 {
	font-size: 1rem;
	font-weight: 600;
}

.upload-group ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.memoriam {
	margin-block-start: var(--space-4);
	border-block-start: 1px solid var(--rule);
	padding-block-start: var(--space-3);
}

.memoriam h2 {
	font-size: 1rem;
	margin-block-end: var(--space-2);
}

/* --- The banner's quick links and site search ---------------------------- */

.banner-actions ul {
	display: grid;
	gap: var(--space-2);
	list-style: none;
	margin: 0;
	padding: 0;
}

.banner-actions .button {
	display: block;
	text-align: center;
}

.site-search {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.site-search input[type='text'] {
	flex: 1 1 14rem;
	min-width: 0;
	background: var(--panel);
	color: var(--ink);
	border: 1px solid var(--rule);
	border-radius: var(--radius);
	padding: 0.45em 0.6em;
}

/* The archive's dark red, because this searches GOOGLE and not the index. */
.site-search input[type='submit'] {
	background: var(--brand);
	color: var(--brand-ink);
}

.site-search input[type='submit']:hover {
	background: #a80000;
}

/* --- The news row -------------------------------------------------------- */

/* The ROW is the grid and the section is not. `.news-more` spanning every column
   kept the last track from collapsing, so three items sat in four tracks and the
   row stopped three quarters of the way across. */
.news-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
	gap: var(--space-4);
}

.news-item {
	padding: var(--space-4);
}

.news-item :is(h2, h3) {
	font-size: 1.15rem;
}

/* The way OUT of the row, under it — not one more card in it. */
.news-more {
	margin: var(--space-4) 0 0 0;
}

.news-summary {
	color: var(--ink-dim);
	margin-block-end: var(--space-2);
}

.news-date {
	margin: 0;
	font-size: 0.85em;
	color: var(--ink-dim);
}

@media screen and (min-width: 48rem) {
	.banner {
		/* The buttons need only their own width; the column stops growing once
		   they have it, and the stories take everything left over. */
		grid-template-columns: minmax(0, 1fr) minmax(12rem, 16rem);
		padding: var(--space-5);
	}

	.banner h1 {
		font-size: 1.6rem;
	}

	.banner-main {
		grid-column: 1;
	}

	.banner-actions {
		grid-column: 2;
	}

	/* Full width under both columns, as `index.html` has it. */
	.site-search {
		grid-column: 1 / -1;
	}
}

/* ===========================================================================
	13. Markdown content pages (/browse/faq, /browse/misc), from js/app/content.js

	The only place in the app where elements arrive as a block of markup rather
	than one at a time, so they are styled by descent instead of by class.
   =========================================================================== */

/* A prose page is hand-written and quotes readers verbatim, so it can carry a
   run with no space in it -- a long url, or one commenter's eighty-six
   characters of "please......". Break it rather than scroll the page. */
.content-body {
	overflow-wrap: break-word;
}

.content-body > :first-child {
	margin-block-start: 0;
}

.content-body :is(h2, h3, h4) {
	margin-block: var(--space-4) var(--space-2);
}

.content-body :is(ul, ol) {
	margin-block-end: var(--space-3);
	padding-inline-start: var(--space-4);
}

.content-body li {
	margin-block-end: var(--space-1);
}

/* A quoted passage: the rule carries it, not a box, so it stays prose. */
.content-body blockquote {
	margin-block-end: var(--space-3);
	padding-inline-start: var(--space-3);
	border-inline-start: 3px solid var(--rule);
	color: var(--ink-dim);
}

/* `display: block` is what makes a wide table scroll INSIDE itself. A markdown
   table has no wrapper to put the overflow on, and 87 airdates would otherwise
   scroll the whole page sideways on a phone. */
.content-body table {
	display: block;
	overflow-x: auto;
	max-width: 100%;
	margin-block-end: var(--space-3);
}

.content-body :is(th, td) {
	padding: var(--space-1) var(--space-3) var(--space-1) 0;
	border-block-end: 1px solid var(--rule);
	text-align: start;
	vertical-align: top;
}

.content-body th {
	color: var(--ink-strong);
	font-weight: 700;
}

.content-body :is(code, kbd, samp) {
	padding: 0.1em 0.35em;
	border-radius: var(--radius);
	background: var(--bg);
	font-family: ui-monospace, Menlo, Consolas, "Courier New", monospace;
	font-size: 0.9em;
}

.content-body pre {
	overflow-x: auto;
	margin-block-end: var(--space-3);
}

.content-body pre code {
	padding: var(--space-3);
	display: block;
}

/* --- The widgets a content page can ask for (js/app/widgets.js) ----------- */

/* A `<label>` is inline and a `<textarea>` inline-block, so the box sat BESIDE
   its instruction. Every control here takes its own line. */
.formatter-form label,
.formatter-form textarea,
.formatter-form p {
	display: block;
}

.formatter-form textarea {
	width: 100%;
	margin-block: var(--space-2);
	padding: var(--space-2);
	border: 1px solid var(--rule);
	border-radius: var(--radius);
	background: var(--panel);
	resize: vertical;
}

.formatter-choices li {
	margin-block-end: var(--space-2);
}

/* The radio and its sentence, aligned on the first line rather than centred on
   a label that wraps to three. */
.formatter-choices label {
	display: flex;
	gap: 0.5em;
	align-items: baseline;
}

/* The converted text is READ, then taken away, so it is a box a reader can
   select from and not prose. Monospace, because one of the three counts columns. */
.formatter-output {
	font-family: ui-monospace, Menlo, Consolas, "Courier New", monospace;
}

/* ===========================================================================
	14. The main menu, from js/app/navigation-menu.js

	An APG menubar: a row of roots at every width, each with its own dropdown.

	Two rules explain most of what follows. THE UNDERLINE IS THE POINTER'S: only
	`:hover` draws one, and it stands down while the bar holds focus, so the
	focus ring is left alone to say where the keyboard is. And FOCUS IS WHAT
	EXPANDS: the module writes `aria-expanded` whenever focus shifts to a parent,
	so click, tap, Tab and the arrows all open a panel by one path.
   =========================================================================== */

/* A row at every width that wraps rather than stacking: no hamburger, and no
   disclosure of the whole nav. */
.navigation-menu {
	position: relative;
}

.navigation-menu__bar {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Positioned at EVERY width: this is what keeps a panel under the item it
   belongs to rather than under the whole bar. See the narrow block below. */
.navigation-menu__item {
	position: relative;
}

/* --- A root: the link, and the parent button that reads like one ---------- */

/* Square, and no background in any state -- the marker is the rule underneath,
   so the panel below meets the item flush. */
.navigation-menu__link {
	appearance: none;
	border: 0;
	background: none;
	cursor: pointer;
	display: block;
	padding: 0.4em 0.9em;
	border-radius: 0;
	font: inherit;
	font-weight: 600;
	color: var(--ink-dim);
	text-decoration: none;
	user-select: none;
	transition: color 0.12s ease-in-out, box-shadow 0.12s ease-in-out;
}

/* The caret goes INSIDE the button, so it can never be left alone on a line. */
.navigation-menu__link--parent::after {
	content: '';
	display: inline-block;
	margin-inline-start: 0.45em;
	vertical-align: 0.15em;
	border-inline: 0.3em solid transparent;
	border-block-start: 0.35em solid currentColor;
}

/* `background: none` is LOAD-BEARING and ungated: section 8 gives a bare
   `button` the archive's blue, and `button:hover` outranks the rule above. */
.navigation-menu__item:hover > .navigation-menu__link {
	background: none;
}

/* The hover marker, off while the bar holds focus so it cannot compete with the
   focus ring. On the `<li>`, so hovering the panel keeps its root underlined. */
.navigation-menu:not(:focus-within) .navigation-menu__item:hover > .navigation-menu__link {
	color: var(--ink-strong);
	box-shadow: inset 0 -2px 0 var(--link);
}

/* There is deliberately no `:focus-visible` rule: section 3's global focus ring
   is what marks the focused item, and the underline is the pointer's alone. */

.navigation-menu__link--parent[aria-expanded='true']::after {
	border-block-start: 0;
	border-block-end: 0.35em solid currentColor;
}

/* ...and when hover alone is holding a panel open, which writes no attribute. */
@media (hover: hover) {
	.navigation-menu:not(:focus-within)
		.navigation-menu__item:hover
		> .navigation-menu__link--parent::after {
		border-block-start: 0;
		border-block-end: 0.35em solid currentColor;
	}
}

/* --- The panel ----------------------------------------------------------- */

/* Anchored to its OWN root, square on top to sit flush under the item. */
.navigation-menu__submenu {
	position: absolute;
	inset-block-start: 100%;
	inset-inline-start: 0;
	z-index: 10;
	display: none;
	list-style: none;
	margin: 0;
	min-inline-size: 15em;
	padding: var(--space-2) 0;
	background: var(--panel);
	border-radius: 0 0 var(--radius) var(--radius);
	box-shadow: var(--shadow), 0 0 0 1px var(--rule);
}

/* Focus's answer, written by the module, and the only one an assistive
   technology can read. Never suppressed. */
.navigation-menu__link[aria-expanded='true'] + .navigation-menu__submenu {
	display: block;
}

/* The pointer's, and only while the bar holds no focus -- the APG example's
   `hasFocus()` gate in CSS. Two panels could otherwise stand open at once. */
@media (hover: hover) {
	.navigation-menu:not(:focus-within) .navigation-menu__item:hover > .navigation-menu__submenu {
		display: block;
	}
}

.navigation-menu__sublink {
	display: block;
	padding: 0.45em 1.2em;
	border-radius: 0;
	color: var(--ink-dim);
	font-weight: 600;
	text-decoration: none;
	transition: color 0.12s ease-in-out, box-shadow 0.12s ease-in-out;
}

.navigation-menu:not(:focus-within) .navigation-menu__sublink:hover {
	color: var(--ink-strong);
	box-shadow: inset 0 -2px 0 var(--link);
}

/* Section 3's ring sits 2px OUTSIDE the element, which the panel's edge clips. */
.navigation-menu__sublink:focus-visible {
	outline-offset: -2px;
}

/* --- The current page ---------------------------------------------------- */

/* ENTRIES ONLY, and the one filled background the menu draws -- it says where
   you ARE. A root standing up for the page you are on reads as an error. */
.navigation-menu__submenu a[aria-current='page'] {
	background: var(--brand);
	color: var(--brand-ink);
}

/* The hover underline is invisible against the brand red. */
.navigation-menu:not(:focus-within) .navigation-menu__submenu a[aria-current='page']:hover {
	color: var(--brand-ink);
	box-shadow: inset 0 -2px 0 var(--brand-ink);
}

/* --- Narrow -------------------------------------------------------------- */

@media screen and (max-width: 47.99rem) {
	.navigation-menu {
		inline-size: 100%;
	}

	/* The panel stays under its OWN item -- `.navigation-menu__item` keeps
	   `position: relative` here. The clamp is what a panel under a right-hand
	   root gives up instead of pushing the page sideways. */
	.navigation-menu__submenu {
		min-inline-size: 12em;
		max-inline-size: calc(100vw - 2 * var(--gutter));
	}
}
