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

/* ===========================================================================
	0. The two faces, served from this origin

	Google Fonts is blocked in parts of the world, and it was the shell's only
	external dependency. Both families are VARIABLE, one face covering 400-700,
	so each is two files: `latin` and the accents in `latin-ext`.

	Open Sans is the site. Libre Baskerville is story prose and nothing else --
	a reader who never opens a story never fetches it.
   =========================================================================== */

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

@font-face {
	font-family: 'Libre Baskerville';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('/fonts/libre-baskerville-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: 'Libre Baskerville';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('/fonts/libre-baskerville-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;
}

/* A real italic, not a slanted roman. The production site loads the regular
   alone, so every one of a story's italics is synthesised there today. */
@font-face {
	font-family: 'Libre Baskerville';
	font-style: italic;
	font-weight: 400 700;
	font-display: swap;
	src: url('/fonts/libre-baskerville-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: 'Libre Baskerville';
	font-style: italic;
	font-weight: 400 700;
	font-display: swap;
	src: url('/fonts/libre-baskerville-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-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;
	--font-story: 'Libre Baskerville', Georgia, '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;
}

/* The column is centred in what the scrollbar leaves, so without a reserved
   gutter a short page sits half a scrollbar to the right of a long one, and a
   page whose content arrives late jumps left when it grows one. */
html {
	scrollbar-gutter: stable;
}

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

/* Bottom only: the space ABOVE a heading is its container's -- `.group` and
   `.content-body` pad it, and a base top margin would add to that, not collapse. */
h1, h2, h3, h4 {
	margin-block-end: var(--space-2);
}

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

/* The SAME column `main` gives its children, so the logo above and the footer
   below line up with the page's own left and right edge -- the boxes on home,
   the text on every other page. `main` spends the gutter outside its column,
   so these two cannot spend it as padding inside a 75rem box. */
.site-header,
.site-footer {
	max-width: min(75rem, 100% - 2 * var(--gutter));
	margin-inline: auto;
}

.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 {
	display: flex;
	align-items: center;
	gap: 0.3em;
	color: var(--brand-ink);
	text-decoration: none;
}

.site-logo img {
	flex: none;
}

.site-logo__name {
	flex: auto;
	text-align: center;
	text-wrap: balance;
}

/* --- 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 (/stories/filter and /stories/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;
}

/* --- 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 cell that reads as a phrase takes a line: at column width a name with a
	   count and a byline after it wraps two and three deep. */
	.cell-list--sentence {
		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. */
.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. 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;
}

/* The hub's bookmark key: the glyphs sit in the sentence that names them, so
   they take a wider gap than the quarter-em that parts two badges on a row. */
.award-legend .award-badge {
	margin-inline-start: 1em;
}

/* The certificate link at the end of a row. Smaller than the title it trails,
   because the row is about the story and this is the aside. */
.award-banner {
	font-size: 0.85em;
}

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

@media screen and (max-width: 47.99rem) {
	.link-bar {
		font-size: 1.5rem;
	}
}

/* Balance needs lines, not flex items. */
.link-bar ul {
	display: block;
	text-wrap: balance;
	list-style: none;
	margin: 0;
	padding: 0;
}

.link-bar li {
	display: inline-block;
	margin-block: 0.075em;
	margin-inline-end: 0.5em;
}

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

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

.content-body video {
	height: auto;
	margin-block-end: var(--space-3);
}

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

/* ===========================================================================
	15. Story pages -- the ~4,400 files under /stories

	A story arrives as one block of legacy markup, so it is styled by descent
	like the content pages. Every rule is scoped to `data-page="story"`, which
	story.js stamps on a story page and app.js sets per route: no story rule
	reaches the SPA, and no SPA rule knows a story exists.
   =========================================================================== */

/* The face the archive has always set fiction in, and the only place the site
   uses it. `overflow-wrap` for the reason the content pages have it: an author
   pastes a bare url and a phone scrolls sideways for the whole story. */
body[data-page='story'] main {
	font-family: var(--font-story);
	overflow-wrap: break-word;
	/* A story is one flow and nothing in it spans the panel, so the measure is
	   padding rather than a middle column: the same width, and the paragraphs
	   are block boxes whose margins collapse. */
	display: block;
	padding-inline: max(var(--gutter), (100% - 75rem) / 2);
}

/* Paragraphs are INDENTED, not spaced apart: a blank line between them is the
   web's habit, a first line set in is a story's, and the archive's prose was
   written to be read the second way. */
body[data-page='story'] main p {
	text-indent: 2em;
}

/* Centred text sets its own first line, so the indent above would push it off
   centre -- a scene break's `***` and the separator both land right of where
   they belong. */
body[data-page='story'] main p[align='center' i],
body[data-page='story'] .horizontalrule {
	text-indent: 0;
	text-align: center;
}

/* The block naming the story: byline, rating, summary, the other formats. Not
   prose, so it does not indent, and it stands off the story it introduces. */

body[data-page='story'] .lcfheader p {
	margin-block-end: var(--space-3);
	text-indent: 0;
}

body[data-page='story'] main h1 {
	margin-block-end: var(--space-4);
}
/* A chapter heading, which owes the paragraph above it more room than the one
   below. */
body[data-page='story'] main h2 {
	margin-block: var(--space-5) var(--space-3);
}

body[data-page='story'] main .horizontalrule + h2 {
	margin-block: var(--space-3) var(--space-3);
}

body[data-page='story'] .horizontalrule {
	margin-block: var(--space-4);
	color: var(--ink-dim);
}

/* --- Series and awards --------------------------------------------------- */

/* Both arrive once the index loads. The badges float on the title's first
   line, so they take no height of their own; the series line is the title's
   subtitle and sits closer to it than the byline does. */
body[data-page='story'] main h1 .story-awards {
	float: inline-end;
	margin-inline-start: var(--space-3);
	font-size: 1rem;
	line-height: inherit;
}

body[data-page='story'] main h1:has(+ .story-series) {
	margin-block-end: var(--space-2);
}

body[data-page='story'] main .story-series {
	margin-block-end: var(--space-4);
	text-indent: 0;
	font-style: italic;
}

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

/* A story is one long read, and a control fixed over it is a lost place
   waiting to happen: one stray tap and the reader is back at the header with
   forty thousand words between them and where they were. `chrome.js` marks it
   once the story has scrolled past, when returning to the top costs nothing. */
body[data-page='story'] .to-top {
	display: none;
}

body[data-page='story'] .to-top[data-past-main] {
	display: block;
}

/* --- Wide ---------------------------------------------------------------- */

@media screen and (min-width: 48rem) {
	body[data-page='story'] main p {
		text-indent: 3em;
	}
}
