/* Bloomsday — the house stylesheet.
 *
 * A NIGHT HERBARIUM: flowers printed in light on deep blue, labelled like a
 * museum sheet, moving no faster than a flower opens (the brief, "Design
 * system"). Three inks, one paper and two text tones, and nothing else in the
 * interface; the element tints exist only inside a bloom. Two faces and no
 * third: Fraunces for every sentence a reader reads, IBM Plex Mono for a
 * label, the ledger and a number. A day's name is always Fraunces italic
 * inside single quotation marks, which `dayName` in the kit writes and
 * `.day-name` below sets.
 *
 * TWO GROUNDS, CHOSEN BY THE KIND OF PAGE, NEVER BY THE READER'S SYSTEM. An
 * open day and the public site live on night; a pressed day and the console
 * live on paper, so the operator's pane is legible on a phone and never reads
 * as the public site. `layout({ ground })` pins the root, and the generated
 * block draws each ground's roles on `:root[data-ground="…"]`. Moth and
 * pollen are never set on paper: there the quiet text is print and the
 * accent pollen-deep, and the tokens refuse any role that would come to
 * either.
 *
 * EVERY VALUE IS A TOKEN, AND THE TOKENS ARE NOT WRITTEN HERE. The block
 * between `tokens:begin` and `tokens:end` is generated from
 * docs/design-system/tokens.json by tools/tokens.mjs — the faces at the
 * versions their pins name, the scales, the grounds, the modes and the ad
 * frames' reserved sizes — and a test fails the build when the two disagree.
 * Below it a rule spends roles and steps only: no raw colour, no palette
 * name, no font size off the scale, no raw spacing, no unlisted breakpoint,
 * no layer off the scale, no raw duration and no easing but `--ease`.
 *
 * NOTHING MOVES FASTER THAN A FLOWER. A colour or a border changes in
 * `--dur-small`; nothing large moves in less than `--dur-large`; nothing
 * bounces, snaps, shakes or flashes; and under reduced motion the generated
 * block makes every movement a `--dur-fade` cross-fade, stops the breath and
 * the drift, and shows the bloom open.
 *
 * ONE COLUMN, AT MOST 640PX, with 16px gutters, and nothing scrolls sideways
 * at 320px: a long word, an address or a table's cell wraps in the column.
 * Body text is 18px on a 28px line. Every control is at least `--target`
 * tall and has a focus ring in the accent, at least 3:1 on its ground. Colour
 * is never the only signal: a state says its word, a notice has a label, and
 * the page you are on is said in `aria-current` and drawn in a heavier rule.
 *
 * HERE: the rules for the classes the kit (src/platform/ui-core.mjs) prints
 * and the script adds; the named components' base styles — Label, Notice,
 * Card and the Ad frame placeholder; and the console's kit. The Bloom, Petal,
 * Bud, Dial, Board, Hours, Ledger and Press are drawn by the issues that
 * build them, which add their rules here. A rule of one or two declarations
 * is written on one line.
 */

/* tokens:begin */
/* Generated by tools/tokens.mjs from docs/design-system/tokens.json and the font pins in tools/contracts.json.
   Edit the JSON, then run `node tools/tokens.mjs --write`; tools/tokens.test.mjs fails the build when this block
   and the files disagree. */

@font-face { font-family: Fraunces; src: url("../25e420d8c154303e/Fraunces-Roman.woff2") format("woff2"); font-style: normal; font-weight: 100 900; font-display: swap; }
@font-face { font-family: Fraunces; src: url("../b02ea63758999cc1/Fraunces-Italic.woff2") format("woff2"); font-style: italic; font-weight: 100 900; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("../ba204497f16b6d33/IBMPlexMono-Regular.woff2") format("woff2"); font-style: normal; font-weight: 400; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("../33faf307fa6031fb/IBMPlexMono-Medium.woff2") format("woff2"); font-style: normal; font-weight: 500; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("../2024bf2b08027dcd/IBMPlexMono-Italic.woff2") format("woff2"); font-style: italic; font-weight: 400; font-display: swap; }

:root {
  /* type */
  --display: Fraunces, Georgia, Cambria, "Times New Roman", Times, serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", "Liberation Mono", monospace;
  --fs-label: 0.875rem;
  --fs-small: 1rem;
  --fs-body: 1.125rem;
  --fs-1: 1.4375rem;
  --fs-2: 1.8125rem;
  --fs-3: 2.25rem;
  --lh-body: 1.75rem;
  --lh-tight: 1.2;
  --lh-label: 1.5;
  --track-label: 0.08em;
  /* space */
  --sp-1: 2px;
  --sp-2: 4px;
  --sp-3: 8px;
  --sp-4: 12px;
  --sp-5: 16px;
  --sp-6: 24px;
  --sp-7: 32px;
  --sp-8: 48px;
  --sp-9: 64px;
  /* shape */
  --r-1: 2px;
  /* elevation */
  --hairline: 1px;
  --hairline-2: 2px;
  /* layout */
  --column: 640px;
  --gutter: 16px;
  /* target */
  --target: 36px;
  --focus-width: 3px;
  --focus-offset: 2px;
  /* layer */
  --z-raised: 2;
  --z-head: 30;
  --z-skip: 100;
  /* motion */
  --dur-small: 150ms;
  --dur-large: 600ms;
  --dur-open: 2400ms;
  --dur-fade: 300ms;
  --breath: 6s;
  --drift-distance: 2px;
  --drift-time: 1s;
  --ease: cubic-bezier(0.65, 0, 0.35, 1);
  --play: running;
  --bloom-start: 0;
  /* the element tints: spent only by a rule whose selector starts .bloom or [data-bloom] */
  --fire: #E4572E;
  --earth: #8A9A4B;
  --air: #A9C5E8;
  --water: #2EC4B6;
}

:root,
:root[data-ground="night"] {
  color-scheme: dark;
  --ground: #081B3A;
  --ink: #F3EEE3;
  --quiet: #AEB9CC;
  --accent: #F2C230;
  --raised: #1B4F8F;
  --rule: #AEB9CC;
}

:root[data-ground="paper"] {
  color-scheme: light;
  --ground: #F3EEE3;
  --ink: #081B3A;
  --quiet: #1B4F8F;
  --accent: #8A6400;
  --raised: #F3EEE3;
  --rule: #1B4F8F;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-large: 300ms;
    --dur-open: 300ms;
    --dur-fade: 300ms;
    --drift-distance: 0px;
    --play: paused;
    --bloom-start: 1;
  }
}

@media (pointer: coarse) {
  :root {
    --target: 44px;
  }
}

@media (prefers-contrast: more) {
  :root,
  :root[data-ground="night"] {
    --quiet: #F3EEE3;
    --rule: #F3EEE3;
  }
  :root[data-ground="paper"] {
    --quiet: #081B3A;
    --rule: #081B3A;
  }
}

@media print {
  :root,
  :root[data-ground] {
    color-scheme: light;
    --ground: #F3EEE3;
    --ink: #081B3A;
    --quiet: #081B3A;
    --accent: #8A6400;
    --raised: #F3EEE3;
    --rule: #081B3A;
  }
}

/* The ad frames: a reserved height, so an ad never shifts the page; the frame's look is the stylesheet's .ad-frame. */
.ad-frame-s, .ad-frame-m { contain: layout; }
.ad-frame-s { width: min(100%, 320px); min-height: 100px; }
.ad-frame-m { width: min(100%, 300px); min-height: 250px; }

/* tokens:end */

/* --- The ground and the page ---------------------------------------------- */

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

html {
  color: var(--ink);
  background-color: var(--ground);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  font-optical-sizing: auto;
  overflow-wrap: break-word;
}

/* THE ONE COLUMN: the body itself, the ground running to the window's edges behind it. */
.page {
  max-width: var(--column);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* The head, the sheet and the foot, one under another, the foot at the bottom of a short page. */
.surface {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.sheet {
  flex: 1 0 auto;
  width: 100%;
  padding: var(--sp-6) 0 var(--sp-9);
}

.sheet--wide { padding-bottom: var(--sp-8); }
.sheet--doc { hyphens: auto; }

img,
svg {
  max-width: 100%;
  height: auto;
}

/* The way past the chrome for a keyboard: off the page until it is focused. */
.skip {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: var(--z-skip);
  padding: 0 var(--sp-5);
  color: var(--ground);
  background-color: var(--accent);
  transform: translateY(-200%);
}

.skip:focus { transform: none; }

/* Hidden from the eye and never from a screen reader. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Type ------------------------------------------------------------------- */

h1,
h2,
h3 {
  margin: var(--sp-7) 0 var(--sp-4);
  font-family: var(--display);
  line-height: var(--lh-tight);
  text-wrap: balance;
}

h1 {
  margin-top: var(--sp-5);
  font-size: var(--fs-3);
  font-weight: 400;
}

h2 { font-size: var(--fs-1); font-weight: 500; }
h3 { margin-top: var(--sp-6); font-size: var(--fs-body); font-weight: 600; }
.surface--site .sheet { padding-top: var(--sp-7); }
.surface--console h1 { font-size: var(--fs-2); }

p,
ul,
ol,
dl {
  margin: 0 0 var(--sp-5);
}

ul,
ol {
  padding-left: var(--sp-6);
}

hr {
  margin: var(--sp-7) 0;
  border: 0;
  border-top: var(--hairline) solid var(--rule);
}

/* A title of two sentences keeps each whole on a line while it fits. */
.phrase { display: inline-block; max-width: 100%; }

/* The second text tone. */
.lede {
  color: var(--quiet);
  font-size: var(--fs-1);
  line-height: var(--lh-label);
}

.surface--console .lede { font-size: var(--fs-body); line-height: var(--lh-body); }

/* THE SMALL PRINT: the second tone, at the small step. */
.fine,
.hint,
.site-foot-fine,
.colophon,
.card-meta,
.pane p,
.notice-meta,
.notices-empty,
.notices-failed,
.notices-more,
.byline,
.article-figure figcaption {
  color: var(--quiet);
  font-size: var(--fs-small);
  line-height: var(--lh-label);
}

.hint { margin: var(--sp-2) 0 0; }

/* What a machine cares about — an address, a date in a column, a number — in
 * the label face, each figure as wide as the next; a long one breaks rather
 * than widening the page. */
.data,
.num,
.colophon-who,
.notice-title {
  font-family: var(--mono);
  font-size: 0.875em;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* A figure in a column is never broken. */
.num { text-align: right; white-space: nowrap; }

/* A DAY'S NAME: Fraunces italic, always, inside the single quotation marks
 * `dayName` writes. Nothing else sets it. */
.day-name {
  font-family: var(--display);
  font-style: italic;
}

/* THE LABEL: the mono, in tracked capitals, as a museum sheet's typed label —
 * a field's label, a table's head, a state's word, a control's verb. */
.label,
.eyebrow,
.kv-key,
.rail-label,
.notice-label,
.notices-label,
.ad-label,
.skip,
.site-nav a,
.door,
.rail-out,
.pager a,
.pager-disabled,
.move > summary,
.btn,
.chip,
.status,
.notice-new,
.notices > summary,
.crumbs,
th {
  font-family: var(--mono);
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: var(--lh-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

/* A label proper stands under a hairline, as the sheet's label is ruled off from the specimen. */
.label {
  display: block;
  margin: 0 0 var(--sp-3);
  padding: var(--sp-2) 0 0;
  border-top: var(--hairline) solid var(--rule);
  color: var(--ink);
}

.optional {
  color: var(--quiet);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.eyebrow { margin: 0 0 var(--sp-2); color: var(--quiet); }

/* --- Links, targets and the focus ring ------------------------------------------ */

a,
.linklike,
.notice-open,
.card--link .card-title {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: var(--hairline);
  text-underline-offset: 0.18em;
}

a:hover,
.linklike:hover,
.notice-open:hover,
.site-nav a[aria-current="page"],
.rail-nav a[aria-current="page"] {
  text-decoration-thickness: var(--hairline-2);
}

:focus-visible {
  outline: var(--focus-width) solid var(--accent);
  outline-offset: var(--focus-offset);
}

/* EVERYTHING PRESSED ON ITS OWN is at least a target tall; a link inside a sentence is the exception. */
.skip,
.brand,
.site-nav a,
.door,
.rail-out,
.rail-nav a,
.site-foot-group a,
.pager a,
.pager-disabled,
.move > summary,
.nav-form .linklike,
.notices-foot .linklike,
.notice-dismiss,
.notices-move,
.notices > summary,
.sort,
.tick,
.chip,
.btn {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
}

/* --- The site's head and foot ------------------------------------------------------- */

.site-head,
.rail {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-5);
  padding: var(--sp-6) 0 var(--sp-4);
  border-bottom: var(--hairline) solid var(--rule);
}

.brand { margin-right: auto; color: var(--ink); text-decoration: none; }

/* The wordmark: the name in the display face, upright (the brief, "The mark"). */
.brand-name {
  font-family: var(--display);
  font-size: var(--fs-1);
  font-weight: 400;
  line-height: var(--lh-tight);
}

.site-nav,
.site-foot-group,
.rail-group ul,
.rail-group--bare {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-foot,
.colophon {
  margin-top: auto;
  padding: var(--sp-7) 0 var(--sp-8);
  border-top: var(--hairline) solid var(--rule);
}

.site-foot-name,
.site-foot-nav {
  margin: 0 0 var(--sp-4);
}

.site-foot-fine,
.colophon p {
  margin: 0 0 var(--sp-2);
}

.site-foot-owner,
.site-foot-note {
  margin-top: var(--sp-3);
}

/* --- The console's rail and colophon ------------------------------------------------- */

.rail { padding-top: var(--sp-5); }

.rail-nav {
  display: flex;
  flex-wrap: wrap;
  flex-basis: 100%;
  gap: var(--sp-3) var(--sp-7);
}

.rail-group { min-width: 0; }
.rail-label { margin: 0; color: var(--quiet); }
.rail-foot { display: flex; }

/* --- Notice: a one-line message from the site ------------------------------------------ */

/* Its label, its words and its one link, on one line where they fit, between
 * two hairlines. Its kind is its label's word; a refusal is ruled heavier. */
.notice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-4);
  margin: 0 0 var(--sp-6);
  padding: var(--sp-3) 0;
  border-block: var(--hairline) solid var(--rule);
}

.notice-label { color: var(--ink); }

.notice--ok,
.notice--warning {
  border-block-color: var(--ink);
}

.notice--error { border-block: var(--hairline-2) solid var(--ink); }
.notice-action { margin-left: auto; }

/* --- Card ----------------------------------------------------------------------------- */

/* A thing with a title and a body, ruled round with a hairline on the ground:
 * a herbarium sheet has no shadow. Two across from the breakpoint. */
.cards {
  display: grid;
  gap: var(--sp-5);
  margin: 0 0 var(--sp-7);
}

.card {
  display: block;
  min-width: 0;
  padding: var(--sp-5);
  color: var(--ink);
  border: var(--hairline) solid var(--rule);
}

.card--link {
  text-decoration: none;
  transition: border-color var(--dur-small) var(--ease);
}

.card--link:hover { border-color: var(--accent); }
.card-art { margin: calc(-1 * var(--sp-5)) calc(-1 * var(--sp-5)) var(--sp-5); }
.card-n { display: block; margin: 0 0 var(--sp-2); color: var(--quiet); }
.card-title { margin: 0 0 var(--sp-3); font-size: var(--fs-1); font-weight: 500; }
.card-body > :last-child { margin-bottom: 0; }
.card-meta { margin: var(--sp-4) 0 0; }

/* --- Ad frame: the placeholder ---------------------------------------------------------- */

/* A hairline box of reserved height — the size class's, in the generated
 * block — with the word "Advertisement" above it in mono, so an ad never
 * shifts the page and never looks like the reading. The hairline is an
 * outline, so it takes none of the reserved box. #123 fills the frames; #74
 * fails a frame with neither size class. */
.ad-frame {
  position: relative;
  display: block;
  margin: var(--sp-8) auto var(--sp-7);
  outline: var(--hairline) solid var(--rule);
}

.ad-label {
  position: absolute;
  bottom: 100%;
  left: 0;
  margin: 0 0 var(--sp-2);
  color: var(--quiet);
}

/* --- The console's kit: forms ------------------------------------------------------------ */

form { margin: 0 0 var(--sp-6); }
.field { min-width: 0; margin: 0 0 var(--sp-6); }
.field--wide { grid-column: 1 / -1; }

input:not([type="checkbox"], [type="radio"], [type="hidden"]),
select,
textarea {
  display: block;
  width: 100%;
  min-height: var(--target);
  padding: var(--sp-3) var(--sp-4);
  color: var(--ink);
  background-color: var(--ground);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-1);
  font-family: var(--display);
  font-size: var(--fs-small);
  line-height: var(--lh-label);
  transition: border-color var(--dur-small) var(--ease);
}

input:not([type="checkbox"], [type="radio"], [type="hidden"]):hover,
select:hover,
textarea:hover {
  border-color: var(--ink);
}

textarea { resize: vertical; }

input[type="email"],
input[type="url"],
input[type="number"] {
  font-family: var(--mono);
}

/* Six digits to type, in the label face, spaced. */
.code-input { max-width: 16ch; font-family: var(--mono); letter-spacing: 0.3em; }

.field--error input,
.field--error select,
.field--error textarea {
  border: var(--hairline-2) solid var(--ink);
}

.field--attention input,
.field--attention select,
.field--attention textarea {
  border-style: dashed;
}

/* A field's error and its attention note, said in words, in ink. */
.error,
.attention {
  margin: var(--sp-2) 0 0;
  color: var(--ink);
  font-size: var(--fs-small);
  line-height: var(--lh-label);
}

.error { font-weight: 600; }

/* A box and its words, as one target. */
.tick { display: flex; gap: var(--sp-3); cursor: pointer; }

.tick input,
.pick input {
  width: 1.25em;
  height: 1.25em;
  margin: 0;
  accent-color: var(--accent);
}

.choices { padding: 0; border: 0; }

.group {
  min-width: 0;
  margin: 0 0 var(--sp-6);
  padding: var(--sp-4) 0 0;
  border: 0;
  border-top: var(--hairline-2) solid var(--rule);
}

.group > legend { padding: 0 var(--sp-3) 0 0; font-size: var(--fs-1); }
.grid { display: grid; gap: 0 var(--sp-6); }
.filters-field { margin-bottom: var(--sp-5); }

/* What stands in the way of a move, read before its button is pressed. */
.gate { margin: 0 0 var(--sp-5); color: var(--ink); }

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}

.inline-form,
.nav-form {
  display: inline;
  margin: 0;
}

/* A move a record can make, closed until wanted. */
.move { margin: 0 0 var(--sp-5); border-top: var(--hairline) solid var(--rule); }
.move > summary { display: flex; color: var(--accent); cursor: pointer; }
.move[open] > summary { margin-bottom: var(--sp-4); }

/* --- The console's kit: buttons ----------------------------------------------------------- */

.btn {
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-5);
  color: var(--ink);
  background-color: var(--raised);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-1);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-small) var(--ease), border-color var(--dur-small) var(--ease), color var(--dur-small) var(--ease);
}

.btn:hover { border-color: var(--ink); }

/* The one button a page asks you to press: the accent, filled, with the
 * ground's words; the page's own ink under the pointer. */
.btn--primary {
  color: var(--ground);
  background-color: var(--accent);
  border-color: var(--accent);
}

.btn--primary:hover { background-color: var(--ink); border-color: var(--ink); }
.btn--quiet { background-color: transparent; }

/* A removal or a revocation: its word says so, and its rule is heavier. */
.btn--danger { border: var(--hairline-2) solid var(--ink); }
.btn--big { padding: var(--sp-3) var(--sp-7); font-size: var(--fs-small); }

/* Small is the type and the padding, never the target. */
.btn--small { padding: var(--sp-1) var(--sp-4); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn.is-busy { cursor: progress; }

/* A busy button's two words, stacked in one cell: the button is as wide as
 * the wider of them, so pressing it moves nothing, and the one not showing is
 * hidden from a reader too. The script builds the layers on the press. */
.btn-face { display: inline-grid; }
.btn-face > * { grid-area: 1 / 1; }

.btn-face-busy,
.is-busy .btn-face-idle {
  visibility: hidden;
}

.is-busy .btn-face-busy { visibility: visible; }

/* What a form says when its answer is slow in coming: empty, and taking no
 * room, until there is something to say. Collapsed out of the layout, never
 * `display: none`, which would take a status region out of the
 * accessibility tree; positioned, so it adds no gap to the row it is in. */
.busy-note:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* A copy button that has just copied: its words say so, and it is ruled in the accent. */
.is-copied { border-color: var(--accent); }

/* A control that LOOKS like a link is still a control. */
.linklike,
.notice-open {
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
}

.linklike { display: inline; }

/* The browser's own modal dialog, which the script builds for a form marked
 * `data-confirm`: the question, what happens, Cancel and the action. It
 * waits; there is no timer. */
.confirm {
  width: min(var(--column), calc(100% - 2 * var(--gutter)));
  padding: var(--sp-6);
  color: var(--ink);
  background-color: var(--ground);
  border: var(--hairline) solid var(--rule);
}

.confirm::backdrop { background-color: var(--ground); opacity: 0.85; }
.confirm-q { margin: 0 0 var(--sp-4); font-size: var(--fs-1); line-height: var(--lh-tight); }
.confirm-more { color: var(--quiet); }
.confirm .actions { justify-content: flex-end; }

/* --- The console's kit: tables, chips, states, the pager -------------------------------- */

/* A table fits the column: a cell's words wrap, hyphenated where the language
 * allows and broken where they must, rather than pushing the page sideways; a
 * head's word is never broken. A list of more columns than a phone holds is
 * its domain's to lay out. */
table {
  width: 100%;
  margin: 0 0 var(--sp-6);
  border-collapse: collapse;
  font-size: var(--fs-small);
  line-height: var(--lh-label);
}

th,
td {
  padding: var(--sp-3) var(--sp-2);
  border-bottom: var(--hairline) solid var(--rule);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
  hyphens: auto;
}

th { color: var(--quiet); overflow-wrap: normal; hyphens: manual; }
.record th[scope="row"] { color: var(--ink); }

th.num,
td.num {
  text-align: right;
}

.pick { width: var(--target); }

.pick-hit {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--target);
  min-height: var(--target);
  cursor: pointer;
}

/* A ticked row is ruled in the accent at its start, and the box says it too. */
tr:has(input[name="selected"]:checked) > td:first-child { box-shadow: inset var(--hairline-2) 0 0 var(--accent); }

.sort { gap: var(--sp-2); color: inherit; text-decoration: none; }
.sort:hover { text-decoration: underline; }
th[aria-sort] .sort { color: var(--ink); }
.sort-dir { font-size: 0.75em; }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-6);
}

.chip {
  gap: var(--sp-3);
  padding: 0 var(--sp-4);
  color: var(--ink);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-1);
  text-decoration: none;
  transition: border-color var(--dur-small) var(--ease);
}

.chip:hover { border-color: var(--ink); }
.chip[aria-current="page"] { border: var(--hairline-2) solid var(--accent); }
.chip--zero { color: var(--quiet); }
.chip-n { color: var(--ink); font-variant-numeric: tabular-nums; }

/* A STATE IS A WORD, in a ruled box: open is ruled in the accent, closed is
 * filled with the ink, stale is ruled dashed, and a state nobody named is
 * quiet. The word is always there. */
.status {
  display: inline-block;
  padding: 0 var(--sp-2);
  color: var(--ink);
  border: var(--hairline) solid var(--rule);
  vertical-align: middle;
  white-space: nowrap;
}

.status--open { border-color: var(--accent); }
.status--closed { color: var(--ground); background-color: var(--ink); border-color: var(--ink); }
.status--stale { border-style: dashed; }
.status--unknown { color: var(--quiet); }

/* A count riding on a link: the ground's words on the accent. */
.badge {
  display: inline-block;
  min-width: 1.5em;
  margin-left: var(--sp-2);
  padding: 0 var(--sp-2);
  color: var(--ground);
  background-color: var(--accent);
  border-radius: var(--r-1);
  font-family: var(--mono);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin: var(--sp-6) 0;
}

.pager-disabled { color: var(--quiet); }
.meter { width: 8em; height: var(--sp-3); vertical-align: middle; accent-color: var(--accent); }

.empty {
  padding: var(--sp-6) 0;
  color: var(--quiet);
  border-block: var(--hairline) dashed var(--rule);
  text-align: center;
}

/* --- The console's kit: facts, the timeline, the panes ----------------------------------- */

.kv {
  display: grid;
  gap: var(--sp-3) var(--sp-6);
  margin: 0 0 var(--sp-6);
}

.kv > div {
  min-width: 0;
  padding-top: var(--sp-2);
  border-top: var(--hairline) solid var(--rule);
}

.kv-key { color: var(--quiet); }
.kv-val { margin: 0; overflow-wrap: anywhere; }
.facts > div { margin: 0 0 var(--sp-5); }
.facts dt { font-weight: 600; }
.facts dd { margin: 0; }
.timeline { margin: 0 0 var(--sp-6); padding: 0; list-style: none; }

.entry {
  display: grid;
  grid-template-columns: 11ch minmax(0, 1fr);
  gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-top: var(--hairline) solid var(--rule);
}

.entry-when { color: var(--quiet); }

.panel {
  margin: 0 0 var(--sp-6);
  padding: var(--sp-4) 0 0;
  border-top: var(--hairline-2) solid var(--rule);
}

.panel > h2,
.panel > h3 {
  margin-top: 0;
}

.panel .status { margin-left: var(--sp-2); }
.pane-area { margin: 0 0 var(--sp-8); }
.pane-what { color: var(--quiet); }
.pane { margin: 0; padding: 0; list-style: none; }
.pane > li { padding: var(--sp-4) 0; border-top: var(--hairline) solid var(--rule); }
.pane h3 { margin: 0 0 var(--sp-2); }
.pane p { margin: 0; }

/* --- The console's kit: the notices bell, and its door ------------------------------------- */

/* The bell at the end of the rail, a disclosure needing no script: its word
 * is drawn, its count rides on it, and what it says to a screen reader is the
 * hidden sentence inside it. */
.notices { position: relative; margin-left: auto; }

.notices > summary {
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-1);
  list-style: none;
  cursor: pointer;
}

.notices > summary::-webkit-details-marker { display: none; }
.notices > summary::before { content: "Notices" / ""; }
.notices--new > summary { border-color: var(--accent); }
.notices--unread > summary { border-style: dashed; }
.notices-badge { margin-left: 0; }

.notices-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: var(--z-raised);
  width: min(var(--column), calc(100vw - 2 * var(--gutter)));
  margin-top: var(--sp-2);
  padding: var(--sp-5);
  color: var(--ink);
  background-color: var(--ground);
  border: var(--hairline) solid var(--rule);
}

.notices-full { padding-bottom: var(--sp-5); }
.notices-group { margin: 0 0 var(--sp-5); }
.notices-label { margin: 0 0 var(--sp-2); }
.notices-label a { color: var(--ink); }
.notices-list { margin: 0; padding: 0; list-style: none; }
.notice-entry { padding: var(--sp-3) 0; border-top: var(--hairline) solid var(--rule); }

.notice-entry-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 var(--sp-4);
  margin: 0;
}

.notice-open { grid-column: 1 / -1; display: block; min-height: var(--target); text-align: left; }
.notice-entry--new .notice-title { font-weight: 600; }
.notice-text { color: var(--ink); }
.notice-meta { margin: 0; }
.notice-new { color: var(--ink); font-size: inherit; }
.notice-dismiss { justify-self: end; }

.notices-empty,
.notices-failed,
.notices-more {
  margin: 0 0 var(--sp-4);
}

.notices-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-5);
  padding-top: var(--sp-3);
  border-top: var(--hairline) solid var(--rule);
}

.notices-move { margin: 0; }

/* --- A day's furniture -------------------------------------------------------------------- */

.crumbs { margin: 0 0 var(--sp-5); }

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--sp-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.crumbs li + li::before { content: "/" / ""; margin-right: var(--sp-3); color: var(--quiet); }
.crumbs [aria-current="page"] { color: var(--quiet); }
.byline { margin: 0 0 var(--sp-6); }
.byline-author { color: var(--ink); }
.article-figure { margin: 0 0 var(--sp-6); }
.article-figure img { display: block; width: 100%; }
.article-figure figcaption { margin-top: var(--sp-3); }

/* --- From the breakpoint: two across ---------------------------------------------------- */

@media (min-width: 40rem) {
  .cards--2,
  .cards--3,
  .cards--4,
  .grid,
  .kv {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --- Paper, printed ----------------------------------------------------------------------- */

/* The generated block lays the paper ground at more contrast on every page;
 * here the chrome comes off and the type is set in points, which is all a
 * print block may write of its own. */
@media print {
  .skip,
  .site-nav,
  .door,
  .rail-nav,
  .rail-foot,
  .notices,
  .nav-form,
  .actions,
  .move,
  .ad-frame {
    display: none;
  }

  body { font-size: 11pt; line-height: 1.5; }
  .page { max-width: none; padding-inline: 0; }
  a { color: var(--ink); }
}
