/* =============================================================================
   review.loops.fail — the review room. One stylesheet, every page.

   THE IDEA. The page is the black card. In the deck, black is the Strategic
   Agenda's colour — "the colour the deck does not have", the one card never in
   play (packages/card-visual/src/card.css, [data-type='agenda']). A room where
   people read the cards without playing them is that card, so its ground is
   that card's ground. Every page is black, and under the black lies THE
   GROUND (below): the deck, very nearly gone. The five type colours are left to the
   cards themselves: the chrome never borrows one to mean "active" or
   "primary". The only colour the room prints on its own is the card's type
   badge, on each group heading, where it says what the card says.

   TYPE. The leaflet's three faces, because it is the most recent thing in this
   box that reads well (docs/rules/leaflet/leaflet.css):
     Archivo Narrow   the deck's display face. The mark, headings, buttons,
                      and the status line, set as the card sets its system
                      line: a dot, then capitals.
     Archivo          reading text. The rules, descriptions, the UI's sentences.
     IBM Plex Mono    the two voices that are not the room's own. Upright, for
                      machine data (a card id, a rules `code`, the field you type
                      in). Italic, for a person speaking: the card's quote, and so
                      a saved comment — your words, set as the deck sets its
                      postmortem.

   GEOMETRY. The machine is square and the card is die-cut (tokens.css §7):
   every control, panel and field has square corners; the card images and the
   type badge keep the corners they were cut with. Two radii, each with a reason.

   CSP: style-src 'self'. Nothing here may be needed inline, and no page writes
   a style attribute. Per-element values arrive as custom properties via CSSOM.
   ============================================================================= */

@font-face {
  font-family: 'Archivo Narrow';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/archivo-narrow-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/archivo-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-400-italic.woff2') format('woff2');
}

:root {
  /* ---- six neutrals: the Agenda card's own ramp, plus the two inks ---------
     Contrast measured against --void, then --graphite.                       */
  --void: #030405; /* the page. The Agenda gradient's darkest stop (52%)     */
  --graphite: #14161a; /* raised: fields, comments, notes. Its 14% stop        */
  --slate: #1f2228; /* hover on raised. Its 100% stop                        */
  --rule: #2b2f36; /* hairlines, decoration only (1.5:1). Its 0% stop       */
  --steel: #6b717c; /* the edge of a control: 4.2 / 3.7 — clears 3:1       */
  --ash: #9a9ea6; /* secondary text: 7.6 / 6.7                             */
  --paper: #e9e8e6; /* text and the primary button: 16.8 / 14.8. The Agenda's
                       accent — "the paper white the face already uses"     */

  /* ---- the deck's five, and the Agenda's badge (card.css, verbatim) -------- */
  --threat: #bd2323;
  --workaround: #0e65d7;
  --leverage: #03bc05;
  --chaos: #cc9a04;
  --discovery: #a030bf;
  --agenda: #3a4049;
  /* An error's edge: the Threat's text tint (tokens.css --type-threat-text),
     because the accent itself is under 3:1 against a field. */
  --alarm: #e05252;

  --display: 'Archivo Narrow', 'Arial Narrow', 'Helvetica Neue', Arial, sans-serif;
  --text: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --voice: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --page: 80rem;
  --gutter: clamp(1rem, 4vw, 3rem);
  --bar-h: 4rem;
  --fast: 120ms;
  --base: 180ms;

  color-scheme: dark;
}

/* A type sets its accent; the badge and anything else typed reads --accent.
   The letter on Leverage and Chaos is dark, as tokens.css rules for the screen:
   white on those two is 2.6:1. The card face keeps white; the screen does not
   have to. */
[data-type='threat'] { --accent: var(--threat); --accent-on: #fff; }
[data-type='workaround'] { --accent: var(--workaround); --accent-on: #fff; }
[data-type='discovery'] { --accent: var(--discovery); --accent-on: #fff; }
[data-type='leverage'] { --accent: var(--leverage); --accent-on: var(--void); }
[data-type='chaos'] { --accent: var(--chaos); --accent-on: var(--void); }
[data-type='agenda'] { --accent: var(--agenda); --accent-on: #fff; }

/* ---- base ------------------------------------------------------------------ */

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

html {
  background: var(--void);
  color: var(--paper);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--bar-h) + 1rem);
}
body {
  margin: 0;
  min-height: 100vh;
  font: 400 1rem/1.55 var(--text);
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
body:has(dialog[open]) { overflow: hidden; }

h1, h2, h3, h4, p, figure, ol, ul { margin: 0; }
img { display: block; max-width: 100%; height: auto; }
button, input, textarea { font: inherit; color: inherit; }
a { color: inherit; }
[hidden] { display: none !important; }

/* =============================================================================
   THE GROUND — every page is black, and under the black lies the deck.

   Two fixed layers behind everything, both animated by transform alone, so
   the compositor moves them and nothing is repainted per frame:

   1. THE FIVE GROUNDS (body::before). Each card type's gradient, taken at the
      stop its title sits on — Threat #610000, Workaround #00127A, Discovery
      #5E1273, Chaos #574100, Leverage #006602 (card.css) — laid as five wide,
      soft pools, the way five cards lie on a dark table, and pushed to about
      a tenth of their strength. At the brightest point no channel passes
      ~15/255: it reads as the black not being flat, never as colour. They
      drift and turn a few degrees over minutes — a table seen while
      something on it is slowly being turned. (The Threat clock is a card
      turned on its side; the room turns, imperceptibly.)
   2. THE STOCK (body::after). Fine grain, the coated card stock under a lamp.
      It is the texture, and it has a job: gradients this close to black band
      into visible rings on an 8-bit screen, and grain of a few levels is what
      dithers the bands away. It drifts one tile a minute.

   Contrast is unchanged in practice: secondary text measured against the
   ground's brightest pixel still clears 7:1. The card images are opaque and
   sit above all of it. Reduced motion: both layers stand still (the global
   rule at the end of this file). More contrast asked for: both go.
   ============================================================================= */

:root {
  /* 240 x 240, seamless (stitchTiles), white with a 0-3% alpha drawn from the
     noise. Alpha is baked in, so the same tile can be laid anywhere —
     including under the opaque bar and the dialogs — without an opacity. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 .05 0 0 0 -.012'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)'/%3E%3C/svg%3E");
  --grain-tile: 240px;
}

body::before,
body::after {
  content: '';
  position: fixed;
  z-index: -1;
  pointer-events: none;
  will-change: transform;
}
body::before {
  inset: -10%;
  background:
    radial-gradient(36% 32% at 15% 18%, rgb(97 0 0 / 0.09), transparent),
    radial-gradient(40% 34% at 88% 14%, rgb(0 18 122 / 0.08), transparent),
    radial-gradient(36% 34% at 82% 84%, rgb(94 18 115 / 0.08), transparent),
    radial-gradient(34% 30% at 20% 86%, rgb(87 65 0 / 0.09), transparent),
    radial-gradient(30% 26% at 52% 50%, rgb(0 102 2 / 0.05), transparent);
  animation: ground-turn 220s ease-in-out infinite alternate;
}
body::after {
  /* one tile of overhang up and left, so a full tile of travel never shows an edge */
  top: calc(-1 * var(--grain-tile));
  left: calc(-1 * var(--grain-tile));
  right: 0;
  bottom: 0;
  background: var(--grain);
  animation: grain-drift 60s linear infinite;
}
@keyframes ground-turn {
  0% { transform: translate3d(-2%, -1.5%, 0) rotate(-2deg) scale(1); }
  50% { transform: translate3d(1.5%, 2%, 0) rotate(1.5deg) scale(1.04); }
  100% { transform: translate3d(2.5%, -2%, 0) rotate(3deg) scale(1.02); }
}
@keyframes grain-drift {
  /* --grain-tile, written out: a var() in a keyframe can keep the animation
     off the compositor */
  to { transform: translate3d(240px, 240px, 0); }
}

:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
}
main:focus, [tabindex='-1']:focus { outline: none; }

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.skip {
  position: absolute; left: var(--gutter); top: 0.5rem; z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--paper); color: var(--void);
  font: 600 1rem/1 var(--display); text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* ---- controls ------------------------------------------------------------------
   A button looks like a button: a filled plate or an outlined one, 44px high.
   The primary is paper on black — the Agenda's own accent, the one bright
   thing on a black card. Never a type colour: those mean a card type.       */

.btn, .btn-line {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4em;
  min-height: 2.75rem;
  padding: 0.55rem 1.15rem;
  border: 1px solid var(--paper);
  border-radius: 0;
  font: 600 1.0625rem/1 var(--display);
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--fast), border-color var(--fast), color var(--fast);
}
.btn { background: var(--paper); color: var(--void); }
.btn:hover { background: #fff; border-color: #fff; }
.btn-line { background: transparent; color: var(--paper); border-color: var(--steel); }
.btn-line:hover { border-color: var(--paper); background: var(--graphite); }
.btn:active, .btn-line:active { transform: translateY(1px); }
.btn[disabled], .btn-line[disabled] { cursor: default; opacity: 0.45; transform: none; }
.btn-line[disabled]:hover { border-color: var(--steel); background: transparent; }
/* Saving: the button stays legible and says so; it is not "disabled". */
.btn[aria-busy='true'] { cursor: progress; }
.small { min-height: 2.25rem; padding: 0.4rem 0.8rem; font-size: 0.9375rem; }

label, .label { font: 600 1rem/1.2 var(--display); letter-spacing: 0.01em; }

input[type='email'], input[type='text'], textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.6rem 0.8rem;
  background: var(--graphite);
  border: 1px solid var(--steel);
  border-radius: 0;
  color: var(--paper);
  transition: border-color var(--fast);
}
input[type='email'], input[type='text'] { font: 400 1rem/1.4 var(--text); }
input:hover, textarea:hover { border-color: var(--ash); }
input:focus-visible, textarea:focus-visible { outline-offset: 0; border-color: var(--paper); }
/* An error edge is two pixels of the Threat's text tint (tokens.css, 5.1:1):
   the accent itself is under 3:1 against a field. */
input[aria-invalid='true'], textarea[aria-invalid='true'] {
  border-color: var(--alarm);
  box-shadow: inset 0 0 0 1px var(--alarm);
}
textarea {
  display: block;
  min-height: 7.5rem;
  resize: vertical;
  font: 400 0.9375rem/1.55 var(--voice);
}
::placeholder { color: #80858e; opacity: 1; } /* 5.5:1 on void, 4.9:1 on graphite */

/* Two-cell plates: IT | EN, and the admin's By card | By reviewer. The one in
   use is filled. */
.lang, .seg { display: inline-flex; border: 1px solid var(--steel); }
.lang button, .seg button {
  min-width: 2.75rem; min-height: 2.25rem;
  padding: 0 0.6rem;
  background: transparent; border: 0;
  font: 600 0.9375rem/1 var(--display); letter-spacing: 0.06em;
  color: var(--ash);
  cursor: pointer;
}
.seg button { letter-spacing: 0.01em; padding: 0 0.9rem; }
.lang button + button, .seg button + button { border-left: 1px solid var(--steel); }
.lang button:hover, .seg button:hover { color: var(--paper); }
.lang button[aria-pressed='true'], .seg button[aria-pressed='true'] { background: var(--paper); color: var(--void); cursor: default; }
.lang-slot { display: contents; }

/* ---- the type badge: the card face's, at screen sizes ---------------------
   64 x 64 with a 14 radius on a 744-wide card: the radius stays 14/64 of the
   side at every size here, so it is the same object, not a lookalike.     */
.badge {
  flex: none;
  display: inline-grid; place-items: center;
  width: var(--b); height: var(--b);
  border-radius: calc(var(--b) * 14 / 64);
  background: var(--accent);
  color: var(--accent-on);
  font: 700 calc(var(--b) * 0.5625) / 1 var(--display);
}
.badge-sm { --b: 1.375rem; }
.badge-md { --b: 1.75rem; }
.badge-lg { --b: clamp(2.5rem, 2rem + 1.5vw, 3.25rem); }

/* ---- the status line ---------------------------------------------------------
   The card face's system line: a round dot, then the caption in capitals, in
   the display face, tracked 6% — "● THREE LOOPS REMAINING." The room uses it
   for its own few states and for nothing decorative.                       */
.sys-block { display: grid; gap: 0.3rem; animation: arrive var(--base) ease-out; }
.sys {
  display: flex; align-items: baseline; gap: 0.6em;
  font: 500 1rem/1.25 var(--display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.sys::before {
  content: '';
  flex: none;
  width: 0.62em; height: 0.62em;
  border-radius: 50%;
  background: var(--paper);
  transform: translateY(-0.02em);
}
.sys-block[data-tone='error'] .sys::before { background: var(--threat); }
.sys-body { color: var(--ash); padding-left: calc(0.62em + 0.6em); max-width: 38rem; }
@keyframes arrive { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }

/* A question asked in place — "Delete this comment?" — never a browser dialog. */
.ask {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.6rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--steel);
  background: var(--void);
}
.ask-q { font: 600 1rem/1.25 var(--display); margin-right: auto; }
.ask-yes { border-color: var(--paper); }

/* =============================================================================
   LOGIN (and the page the emailed link opens) — the leaflet's cover, printed
   in reverse. The mark at the head, what this is at the foot, and between them
   the room the cover leaves empty. The boldness of the site is spent here, once.
   ============================================================================= */

.login {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(4.5rem, 12vh, 7.5rem) var(--gutter) clamp(2rem, 7vh, 4rem);
  display: flex; flex-direction: column;
}
.login .lang { position: absolute; top: clamp(1rem, 3vh, 1.75rem); right: var(--gutter); }
.mark-xl {
  /* As on the leaflet's cover, the mark is as wide as its panel: FAIL in this
     face is 1.73 em wide, so 21.5rem fills the 38rem column and 52vw fills a
     phone's — each with ~10px of slack. The slack matters: the mark may break
     (overflow-wrap) rather than overflow under a text-spacing override, and
     without it, it would break at ordinary spacing too. */
  font: 700 min(52vw, 21.5rem) / 0.76 var(--display);
  letter-spacing: 0.005em;
  margin-left: -0.045em; /* the F's side bearing: the stem sits on the gutter */
  overflow-wrap: anywhere;
}
.expansion {
  margin-top: clamp(1rem, 2.5vh, 1.75rem);
  font: 500 clamp(1.3rem, 1rem + 1.3vw, 1.9rem) / 1.1 var(--display);
}
.login-foot { margin-top: auto; padding-top: clamp(3rem, 10vh, 7rem); display: grid; gap: 1.75rem; }
.kicker { font: 700 clamp(1.75rem, 1.4rem + 1.4vw, 2.4rem) / 1 var(--display); }
.kicker + p { margin-top: 0.5rem; color: var(--ash); font-size: 1.0625rem; }
.login-form { display: grid; gap: 0.5rem; max-width: 34rem; justify-items: start; }
.field-row { display: flex; gap: 0.5rem; width: 100%; }
.field-row input { flex: 1; min-width: 0; }
.hint { color: var(--ash); font-size: 0.9375rem; }
.login-status:empty { display: none; }
.login-status { max-width: 34rem; }
.login-status .sys-block + .sys-block { margin-top: 1.25rem; }
.sent { display: grid; gap: 1rem; justify-items: start; max-width: 34rem; }
.sent .sys-body + .sys-body { margin-top: 0.5rem; }
.enter { min-width: 14rem; min-height: 3.25rem; font-size: 1.25rem; }
@media (max-width: 30rem) {
  .field-row { flex-direction: column; }
  .field-row .btn, .enter { width: 100%; }
}
@media (orientation: portrait) and (max-height: 40rem) {
  .login { padding-top: 3.75rem; }
  .login-foot { padding-top: 2rem; gap: 1.25rem; }
}
/* A phone on its side: the cover becomes a spread — the mark on the left, the
   form on the right — so the form is on the screen, not under it. */
@media (orientation: landscape) and (max-height: 30rem) {
  .login {
    max-width: 62rem;
    display: grid;
    grid-template-columns: auto minmax(18rem, 26rem);
    grid-template-rows: auto auto;
    column-gap: clamp(2rem, 5vw, 4rem);
    align-content: center;
    padding-block: 1.25rem;
  }
  .mark-xl { font-size: min(34svh, 26vw); grid-column: 1; align-self: end; }
  .expansion { grid-column: 1; align-self: start; }
  .login .lang { top: 0.75rem; }
  .login-foot { grid-column: 2; grid-row: 1 / span 2; margin: 0; padding: 0; align-self: center; gap: 1.1rem; }
}

/* =============================================================================
   THE BAR — mark, sections, your tally, language, who you are. One line of
   type with a hairline under it, sticky at every width:
     60rem and up   everything on one row
     48–60rem       one row still: the room's name and yours step out
     under 48rem    three rows, and it leaves while you scroll down and comes
                    back the moment you scroll up (review.js)
   ============================================================================= */

.bar {
  position: sticky; top: 0; z-index: 20;
  background: var(--grain), var(--void);
  border-bottom: 1px solid var(--rule);
  transition: transform 200ms ease;
}
.bar.is-hidden { transform: translateY(-100%); }
.bar-in {
  max-width: var(--page); margin: 0 auto;
  min-height: var(--bar-h);
  padding: 0 var(--gutter);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.5rem clamp(1rem, 2.2vw, 2.25rem);
}
.brand { display: flex; align-items: baseline; gap: 0.7rem; text-decoration: none; }
.brand .mark { font: 700 1.875rem/1 var(--display); letter-spacing: 0.01em; }
.brand .room { font: 500 1.0625rem/1 var(--display); color: var(--ash); }
.views { display: flex; flex-wrap: wrap; column-gap: 1.75rem; align-self: stretch; }
.views a {
  display: flex; align-items: center;
  font: 600 1.0625rem/1 var(--display);
  color: var(--ash); text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding-top: 2px;
}
.views a:hover { color: var(--paper); }
.views a[aria-current='page'] { color: var(--paper); border-bottom-color: var(--paper); }
.tally { margin-left: auto; }
.tally b { font-weight: 700; font-variant-numeric: tabular-nums; }
.account { display: flex; align-items: center; gap: 1.1rem; min-width: 0; font-size: 0.9375rem; color: var(--ash); }
.account .who { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account a { color: var(--paper); text-underline-offset: 0.2em; text-decoration-color: var(--steel); white-space: nowrap; }
.account a:hover { text-decoration-color: var(--paper); }
@media (max-width: 72rem) { .account .who { display: none; } }

@media (min-width: 48rem) and (max-width: 59.99rem) {
  .brand .room { display: none; }
  .views { column-gap: 1.25rem; }
}

@media (max-width: 47.99rem) {
  html { scroll-padding-top: 4.5rem; }
  .bar-in {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: 'brand lang' 'views views' 'tally account';
    padding-top: 0.75rem; padding-bottom: 0.75rem;
    gap: 0.75rem 1rem;
  }
  .brand { grid-area: brand; }
  .bar-in > .lang { grid-area: lang; }
  .views { grid-area: views; column-gap: 1.5rem; }
  .views a { padding-bottom: 0.5rem; margin-bottom: 0; }
  .tally { grid-area: tally; margin: 0; justify-self: start; }
  .account { grid-area: account; justify-self: end; }
  /* The admin bar has no tally: its back link and the account share a row. */
  .page-admin .bar-in { grid-template-areas: 'brand lang' 'views account'; }
  .page-admin .tally { display: none; }
}

/* ---- page frame ---------------------------------------------------------------- */

.wrap { max-width: var(--page); margin: 0 auto; padding: clamp(2rem, 5vw, 3.5rem) var(--gutter) 7rem; }
.view-head { display: grid; gap: 0.75rem; margin-bottom: clamp(2.5rem, 6vw, 4.5rem); max-width: 46rem; }
/* Two columns, cut like a rules row: the reading measure on the left and the
   margin on the right, where the PDFs sit — the same column the notes use. */
.view-head.split {
  max-width: none;
  grid-template-columns: minmax(0, 44rem) minmax(15rem, 20rem);
  column-gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.view-head.split > * { grid-column: 1; }
.view-head.split > .downloads { grid-column: 2; grid-row: 1 / span 6; }
@media (max-width: 59.99rem) {
  .view-head.split { grid-template-columns: minmax(0, 1fr); }
  .view-head.split > .downloads { grid-column: 1; grid-row: auto; margin-top: 0.75rem; max-width: 28rem; }
}
.view-title { font: 700 clamp(2.25rem, 1.6rem + 2.4vw, 3.5rem) / 1 var(--display); }
.lead { font-size: 1.125rem; line-height: 1.5; color: var(--paper); max-width: 40rem; }
.lead-sub { color: var(--ash); }
.loading { padding-top: 4rem; }

/* The PDFs: a file list. The card's own arrow, the title, the size; the row is
   the link, and it opens the PDF in a tab to be read. */
.dl-h { font: 600 1rem/1.2 var(--display); color: var(--ash); margin-bottom: 0.5rem; }
.dl-list { list-style: none; padding: 0; }
.dl {
  display: grid; grid-template-columns: 1rem minmax(0, 1fr) auto; align-items: center; gap: 0.6rem;
  min-height: 2.9rem;
  padding: 0.75rem 0.25rem 0.7rem;
  border-top: 1px solid var(--rule);
  text-decoration: none;
  transition: background-color var(--fast);
}
.dl-list li:last-child .dl { border-bottom: 1px solid var(--rule); }
.dl:hover { background: var(--graphite); }
.dl:hover .dl-t { text-decoration: underline; text-underline-offset: 0.2em; }
.dl-arrow {
  width: 0; height: 0;
  border-left: 0.55rem solid var(--paper);
  border-top: 0.34rem solid transparent;
  border-bottom: 0.34rem solid transparent;
}
.dl-t { font: 600 1.125rem/1.2 var(--display); }
.dl-m { color: var(--ash); font-size: 0.875rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* =============================================================================
   CARDS — the deck laid out on the black card. The cards carry the colour.
   ============================================================================= */

.deck-index { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.deck-index a {
  display: inline-flex; align-items: center; gap: 0.55rem;
  min-height: 2.75rem; padding: 0.35rem 0.9rem 0.35rem 0.45rem;
  border: 1px solid var(--rule);
  text-decoration: none;
  font: 600 1.0625rem/1 var(--display);
  transition: border-color var(--fast), background-color var(--fast);
}
.deck-index a:hover { border-color: var(--steel); background: var(--graphite); }
.deck-index .n { color: var(--ash); font-weight: 500; font-variant-numeric: tabular-nums; }
.aside-line { color: var(--ash); font-size: 0.9375rem; }
/* the rules index: the deck index's chips, without badges; a dot where you commented */
.rules-index .deck-index { list-style: none; padding: 0; margin-top: 0.25rem; }
.rules-index .deck-index a { padding-inline: 0.8rem; font-size: 1rem; min-height: 2.5rem; }
.idx-dot { display: none; width: 0.45em; height: 0.45em; border-radius: 50%; background: var(--paper); }
.rules-index a.has .idx-dot { display: inline-block; }
.jump { display: none; }
.jump select {
  width: 100%; min-height: 2.75rem; padding: 0.5rem 0.75rem;
  font: 600 1.0625rem/1.2 var(--display); color: var(--paper);
  background: var(--graphite); border: 1px solid var(--steel); border-radius: 0;
}
@media (max-width: 47.99rem) {
  .rules-index .deck-index { display: none; }
  .jump { display: block; margin-top: 0.25rem; }
}
.aside-line b { color: var(--paper); font-weight: 600; }

/* The phone's way through 74 cards: the six badges, held at the top. */
.type-strip { display: none; }
@media (max-width: 47.99rem) {
  .view-head .deck-index { display: none; }
  .type-strip {
    display: flex; justify-content: space-between;
    position: sticky; top: 0; z-index: 15;
    margin: -1rem calc(-1 * var(--gutter)) 1.5rem;
    padding: 0.25rem var(--gutter);
    background: var(--grain), var(--void);
    border-bottom: 1px solid var(--rule);
  }
  .type-strip a { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-bottom: 2px solid transparent; text-decoration: none; }
  .type-strip a[aria-current] { border-bottom-color: var(--paper); }
}

.group { margin-top: clamp(3.5rem, 8vw, 6rem); scroll-margin-top: calc(var(--bar-h) + 1.5rem); }
.group:first-of-type { margin-top: 0; }
@media (max-width: 47.99rem) { .group { scroll-margin-top: 4rem; } }

/* The group heading is the card's own title row, at page scale: the name on
   the left, the type badge squared off on the right. Two lines under it:
   what the type does, and how many. */
.group-h {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 0.6rem 1.5rem;
  padding-bottom: 1.25rem;
  margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--rule);
}
.group-name { font: 700 clamp(2.25rem, 1.5rem + 2.6vw, 3.5rem) / 0.95 var(--display); letter-spacing: 0.002em; }
.group-h .badge { grid-column: 2; grid-row: 1; justify-self: end; }
.group-desc { grid-column: 1; font-size: 1.0625rem; max-width: 40rem; }
.group-count {
  grid-column: 2; grid-row: 2; align-self: end; justify-self: end;
  color: var(--ash); font-size: 0.9375rem; white-space: nowrap; font-variant-numeric: tabular-nums;
}

.tiles {
  list-style: none; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
  gap: 2.25rem 1.5rem;
}
.tile { display: grid; gap: 0.7rem; align-content: start; }

/* A card lying on the black: die-cut corners (14 on 744 x 1039, as cut), a
   hairline of edge so the Agenda's own black does not dissolve into the page,
   and the shadow a card casts on a table. Lying cards do not lift on hover;
   the edge brightens, that is all. */
.face {
  position: relative;
  display: block; width: 100%;
  padding: 0; border: 0; background: none;
  cursor: zoom-in;
  border-radius: 1.88% / 1.35%;
}
.face img {
  width: 100%;
  border-radius: 1.88% / 1.35%;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.1), 0 14px 34px rgb(0 0 0 / 0.55);
  transition: box-shadow var(--fast);
  background: var(--graphite);
}
.face:hover img { box-shadow: 0 0 0 1px rgb(255 255 255 / 0.42), 0 14px 34px rgb(0 0 0 / 0.55); }

.tile-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.tile-meta { display: grid; gap: 0.25rem; }
.tile-id { font: 400 0.875rem/1 var(--voice); color: var(--ash); }
/* the other edition's comments: "IT 2" */
.tile-twin { font: 400 0.75rem/1 var(--voice); color: var(--ash); }
.tile-twin:empty { display: none; }
.tile-btn { color: var(--ash); }
.tile-btn:hover { color: var(--paper); }
.tile-btn.has, .tile-btn.draft { color: var(--paper); border-color: var(--paper); }
.tile-btn.has::before, .tile-btn.draft::before {
  content: ''; flex: none; width: 0.5em; height: 0.5em; border-radius: 50%; background: var(--paper);
}
/* a draft is a hollow dot: something is there, nothing is filed */
.tile-btn.draft::before { background: transparent; box-shadow: inset 0 0 0 1.5px var(--paper); }

@media (max-width: 34rem) {
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.75rem 0.75rem; }
  .tile-foot { gap: 0.35rem; }
  .tile-btn { padding-inline: 0.6rem; }
  .group-desc { grid-column: 1 / -1; }
  .group-count { grid-column: 1 / -1; grid-row: auto; justify-self: start; }
}

/* =============================================================================
   THE VIEWER — one card, full size, and your comments beside it.
   A native <dialog>: focus is trapped and Escape closes, for free.

   Three layouts, chosen by the screen and never by the device:
     A  wide and tall     bar on top; card at the height of the screen, panel
                          beside it; only the body scrolls
     B  narrow and tall   a phone held upright: position and Close on top, the
                          card, the form straight under it, and the language
                          and Previous / Next in a bar at the thumb
     C  short             a phone on its side, a small window, the page zoomed
                          to 400%: nothing is fixed and the whole dialog
                          scrolls. Two columns if there is width for a card
                          of at least 21.5rem; one if not.
   ============================================================================= */

dialog {
  padding: 0; border: 0;
  color: var(--paper);
  background: var(--grain), var(--void);
}
dialog::backdrop { background: rgb(0 0 0 / 0.72); }
dialog[open] { animation: arrive 160ms ease-out; }

.viewer {
  width: 100%; height: 100%; height: 100dvh;
  max-width: none; max-height: none;
  margin: 0;
}
.v-in { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 100%; }
.v-top {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem 1.5rem;
  /* on a wide screen the bar lines up with the content under it */
  padding: 0.75rem max(var(--gutter), calc((100% - 76rem) / 2));
  border-bottom: 1px solid var(--rule);
}
.v-pos { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 0.6rem; font: 600 1.0625rem/1.2 var(--display); }
.v-pos-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-tools { order: 1; display: flex; align-items: center; gap: 0.5rem; }
.v-tools .lang { margin-right: 0.75rem; }
.v-close { order: 2; }
.v-body {
  overflow: auto;
  overscroll-behavior: contain;
  display: grid;
  grid-template-columns: auto minmax(18rem, 27rem);
  justify-content: center;
  align-items: start;
  gap: 2.5rem clamp(2rem, 4vw, 4rem);
  padding: clamp(1.5rem, 3.5vh, 2.5rem) var(--gutter) 3rem;
}
/* pan-y: a sideways swipe is the reader's (next / previous); pinch stays the browser's */
.v-card { position: sticky; top: 0; touch-action: pan-y pinch-zoom; }
.v-card img {
  width: auto;
  height: min(var(--h), calc(100dvh - 9rem));
  max-height: calc(100vh - 9rem);
  aspect-ratio: var(--ar);
  border-radius: 1.88% / 1.35%;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.1), 0 24px 64px rgb(0 0 0 / 0.72);
}
.v-panel { display: grid; gap: 1.5rem; align-content: start; padding-top: 0.25rem; min-width: 0; }
.v-flash:empty { display: none; }
.v-name { font: 700 clamp(1.75rem, 1.4rem + 1vw, 2.25rem) / 1.02 var(--display); }
.v-meta { display: flex; align-items: center; gap: 0.75rem; margin-top: 0.6rem; color: var(--ash); }
.v-meta .id { font: 400 0.9375rem/1 var(--voice); color: var(--paper); }

/* The face as words, folded: a reader who needs it opens it, nobody else
   reads the card twice. */
.v-text { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.v-text summary {
  display: flex; align-items: center; gap: 0.6rem;
  min-height: 2.75rem;
  cursor: pointer;
  font: 600 1rem/1.2 var(--display);
  list-style: none;
}
.v-text summary::-webkit-details-marker { display: none; }
/* the card's own arrow, turning down when open */
.v-text summary::before {
  content: '';
  border-left: 0.5em solid var(--ash);
  border-top: 0.31em solid transparent;
  border-bottom: 0.31em solid transparent;
  transition: transform var(--fast);
}
.v-text[open] summary::before { transform: rotate(90deg); }
.v-text div { display: grid; gap: 0.5rem; padding: 0.25rem 0 1rem; font: 400 0.9375rem/1.55 var(--voice); }
.v-text div p:nth-child(2) { font-style: italic; }

/* B — a phone held upright */
@media (max-width: 52rem) {
  .v-in {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: 'pos close' 'body body' 'tools tools';
  }
  .v-top { display: contents; }
  .v-pos { grid-area: pos; padding: 0.55rem 0 0.55rem var(--gutter); }
  .v-close { grid-area: close; align-self: center; margin: 0.4rem var(--gutter) 0.4rem 0.75rem; }
  .v-body {
    grid-area: body;
    border-top: 1px solid var(--rule);
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 1.5rem;
    padding: 1rem var(--gutter) 2rem;
  }
  .v-tools {
    grid-area: tools;
    display: flex; gap: 0.5rem;
    padding: 0.5rem var(--gutter) calc(0.5rem + env(safe-area-inset-bottom));
    border-top: 1px solid var(--rule);
    background: var(--grain), var(--void);
  }
  .v-tools .lang { margin-right: auto; }
  .v-tools .btn-line { min-height: 2.75rem; min-width: 2.75rem; }
  .v-card { position: static; width: 100%; max-width: 31rem; }
  .v-card img { width: 100%; height: auto; max-height: none; }
  .v-panel { width: 100%; max-width: 31rem; gap: 1.25rem; }
}
/* a tablet upright: the panel can sit beside the card */
@media (min-width: 45rem) and (max-width: 52rem) {
  .v-body { grid-template-columns: minmax(0, 1fr) minmax(16rem, 18rem); justify-items: stretch; }
  .v-card, .v-panel { max-width: none; }
}
/* The narrowest phones keep the arrows and lose the words (the buttons keep their names). */
@media (max-width: 23rem) {
  .v-word {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .v-tools .btn-line { font-size: 1.25rem; }
}

/* C — short screens: everything scrolls together (after B, so it wins on a
   phone at 400% zoom, which is both narrow and short) */
@media (max-height: 34rem) {
  .viewer { overflow: auto; overscroll-behavior: contain; }
  .v-in { display: block; height: auto; }
  .v-top { display: flex; padding-block: 0.4rem; border-bottom: 1px solid var(--rule); }
  .v-pos { padding: 0; }
  .v-close { margin: 0; }
  .v-tools { padding: 0; border: 0; background: none; }
  .v-tools .lang { margin-right: 0.5rem; }
  .v-body {
    overflow: visible; border-top: 0;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    padding: 1rem var(--gutter) 2.5rem;
  }
  .v-card { position: static; width: 100%; max-width: 31rem; }
  .v-card img { width: 100%; height: auto; max-height: none; }
  .v-panel { width: 100%; max-width: 31rem; }
}
/* narrow as well as short (a phone at 400%): Close beside the position, the tools under them */
@media (max-height: 34rem) and (max-width: 52rem) {
  .v-close { order: 0; }
  .v-tools { order: 1; flex-basis: 100%; }
}
@media (max-height: 34rem) and (min-width: 46rem) {
  .v-body {
    grid-template-columns: minmax(21.5rem, 1fr) minmax(15rem, 20rem);
    justify-items: stretch;
    max-width: 62rem; margin: 0 auto;
  }
  .v-card, .v-panel { max-width: none; }
}

/* =============================================================================
   COMMENTS — the same block on a card and on a rules section. Write first,
   read after: the form leads, your earlier comments follow it, newest first.
   Typed upright in the machine's face; saved, a comment is set as the deck
   sets a person speaking: Plex Mono italic.
   ============================================================================= */

.notes { display: grid; gap: 0.9rem; align-content: start; }
.notes-h { display: flex; align-items: baseline; gap: 0.5rem; font: 600 1.125rem/1.2 var(--display); margin-top: 0.5rem; }
.notes-h .n { color: var(--ash); font-weight: 500; font-variant-numeric: tabular-nums; }
.notes-list { list-style: none; padding: 0; display: grid; gap: 0.6rem; }
.note { padding: 0.8rem 0.9rem 0.65rem; background: var(--graphite); }
.note-text {
  font: italic 400 0.9375rem/1.6 var(--voice);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.note-meta {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin-top: 0.55rem;
  color: var(--ash); font-size: 0.8125rem;
}
.note-meta .btn-line { min-height: 2rem; padding: 0.3rem 0.7rem; font-size: 0.875rem; }
.note .ask { margin-top: 0.55rem; }
.note-form { display: grid; gap: 0.55rem; }
.form-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.draft-flag {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 0.45em;
  color: var(--ash); font-size: 0.8125rem;
}
.draft-flag::before { content: ''; width: 0.55em; height: 0.55em; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--paper); }
.counter { margin-left: 0.5rem; color: var(--ash); font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.draft-flag[hidden] + .counter { margin-left: auto; }
.privacy { color: var(--ash); font-size: 0.875rem; }
.notes .status:empty, .twin:empty { display: none; }
.notes-add { justify-self: start; }
/* "1 comment on the Italian card": a way across, set as a link */
.twin-link {
  padding: 0.25rem 0; border: 0; background: none;
  font: 400 0.9375rem/1.4 var(--text); color: var(--paper); text-align: left;
  text-decoration: underline; text-decoration-color: var(--steel); text-underline-offset: 0.2em;
  cursor: pointer;
}
.twin-link:hover { text-decoration-color: var(--paper); }

@media (max-width: 60rem) {
  textarea { font-size: 1rem; } /* under 16px, iOS zooms the page on focus */
}

/* =============================================================================
   RULES — the full rules, each section beside its notes.
   The reading column holds 65 characters; the margin holds what you said.
   ============================================================================= */

.rows { border-top: 1px solid var(--rule); }
.row {
  display: grid;
  grid-template-columns: minmax(0, 44rem) minmax(15rem, 20rem);
  gap: 1.5rem clamp(2rem, 5vw, 4.5rem);
  padding: clamp(2rem, 4vw, 3rem) 0;
  border-bottom: 1px solid var(--rule);
  scroll-margin-top: calc(var(--bar-h) + 0.5rem);
}
.row-title { font: 700 clamp(1.5rem, 1.3rem + 0.8vw, 1.9rem) / 1.05 var(--display); margin-bottom: 1.1rem; }
.row-notes { position: sticky; top: calc(var(--bar-h) + 1.5rem); align-self: start; }
/* Stacked, the notes hang off their section by a rule down the left, so the
   Comment button cannot be read as the next section's. */
@media (max-width: 59.99rem) {
  .row { grid-template-columns: minmax(0, 1fr); row-gap: 1rem; padding-bottom: clamp(2.75rem, 7vw, 3.5rem); }
  .row-notes { position: static; border-left: 2px solid var(--rule); padding-left: 1rem; }
}
@media (max-width: 47.99rem) { .row { scroll-margin-top: 1rem; } }

.prose { max-width: 65ch; font-size: 1.0625rem; line-height: 1.62; }
.prose p { margin-bottom: 0.85em; text-wrap: pretty; }
.prose > :last-child { margin-bottom: 0; }
.prose b { font-weight: 640; color: #fff; }
.prose i { font-style: italic; }
.prose code {
  font: 400 0.84em/1 var(--voice);
  padding: 0.12em 0.36em;
  background: var(--graphite);
  border: 1px solid var(--rule);
  white-space: nowrap;
}
/* LISTS. An item is one block of running text and its marker HANGS, taken
   out of flow. Never make the <li> itself a grid or a flex box: every text run
   and every <b> inside it becomes a separate item and the sentence falls apart
   into columns — which is exactly how Setup broke (2026-10-08). The list may be
   a grid (its children are whole items); the item may not. */
.prose ul, .prose ol { list-style: none; padding: 0; margin: 0 0 0.95em; display: grid; gap: 0.45em; }
.prose li { position: relative; text-wrap: pretty; }
/* the card's resolve list: a small square, then the line */
.prose ul li { padding-left: 1.3em; }
.prose ul li::before {
  content: ''; position: absolute; left: 0.1em; top: 0.62em;
  width: 0.38em; height: 0.38em; background: var(--paper);
}
/* numbered steps: the numeral in the display face, a size up, hanging in its
   own column. Its line box is the text's own (1.62 of the item's em), so the
   numeral sits on the first line rather than above or below it. */
.prose ol { counter-reset: step; }
.prose ol li { counter-increment: step; padding-left: 1.9em; }
.prose ol li::before {
  content: counter(step);
  position: absolute; left: 0; top: -0.04em;
  font: 700 1.2em / 1.35 var(--display);
  font-variant-numeric: tabular-nums;
}
/* Tables: the first cell of a row is its header (<th scope="row">). */
.prose table { width: 100%; border-collapse: collapse; margin: 0.25em 0 1.1em; font-size: 0.9688rem; line-height: 1.45; }
.prose th, .prose td { padding: 0.6rem 1rem 0.6rem 0; border-top: 1px solid var(--rule); vertical-align: baseline; text-align: left; }
.prose tr:last-child > * { border-bottom: 1px solid var(--rule); }
.prose th, .prose td:first-child { font: 600 1.0625rem/1.3 var(--display); white-space: nowrap; color: var(--paper); }
.prose th + td { color: var(--ash); font-variant-numeric: tabular-nums; }
.prose td:last-child { padding-right: 0; }
/* A Note, captioned as the card captions its function block: an arrow, then
   the word in capitals. */
.prose aside {
  margin: 1.4em 0 1.1em;
  padding: 1rem 1.2rem 1.05rem;
  background: var(--graphite);
  font-size: 0.97rem;
  line-height: 1.6;
}
.prose aside > b:first-child {
  display: flex; align-items: center; gap: 0.55em;
  margin-bottom: 0.4rem;
  font: 500 0.9375rem/1.2 var(--display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash);
}
.prose aside > b:first-child::before {
  content: '';
  border-left: 0.5em solid var(--ash);
  border-top: 0.31em solid transparent;
  border-bottom: 0.31em solid transparent;
}
/* The postmortem voice, as on the leaflet and on every card. */
.prose blockquote { margin: 1.3em 0 0.4em; font: italic 400 1.25rem/1.5 var(--voice); color: var(--paper); }

@media (max-width: 34rem) {
  .prose th, .prose td:first-child { white-space: normal; }
  .prose th, .prose td { padding-right: 0.65rem; }
}

/* =============================================================================
   COMMENTED — the list, a sheet from the right: what you said, and where
   ============================================================================= */

.ledger {
  width: min(30rem, 100%); height: 100%; height: 100dvh;
  max-width: none; max-height: none;
  margin: 0 0 0 auto;
  border-left: 1px solid var(--rule);
}
.l-in { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 100%; }
.l-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.75rem 1.25rem; border-bottom: 1px solid var(--rule); }
.l-top h2 { font: 700 1.5rem/1 var(--display); }
.l-body { overflow: auto; padding: 1.25rem 1.25rem 3rem; display: grid; gap: 1.75rem; align-content: start; }
.l-summary { color: var(--ash); }
.l-lang { font: 600 1rem/1.2 var(--display); color: var(--ash); margin-bottom: 0.5rem; }
.l-list { list-style: none; padding: 0; display: grid; }
.l-row {
  width: 100%;
  display: grid; grid-template-columns: 1.375rem minmax(0, 1fr) auto; align-items: start; gap: 0.35rem 0.75rem;
  padding: 0.75rem 0.5rem;
  background: none; border: 0; border-top: 1px solid var(--rule);
  text-align: left; cursor: pointer;
}
.l-list li:last-child .l-row { border-bottom: 1px solid var(--rule); }
.l-row:hover { background: var(--graphite); }
.l-row .badge { margin-top: 0.05rem; }
.l-name { font: 600 1.0625rem/1.2 var(--display); display: block; }
.l-kind { color: var(--ash); font-size: 0.875rem; display: block; margin-top: 0.15rem; }
.l-n { font: 600 1rem/1.2 var(--display); font-variant-numeric: tabular-nums; }
/* the newest thing you said there, two lines of it */
.l-snip {
  grid-column: 2 / -1;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden;
  font: italic 400 0.875rem/1.5 var(--voice); color: var(--ash);
  white-space: pre-line; overflow-wrap: anywhere;
}
.l-snip.is-draft { font-style: normal; } /* typed, not yet said */

/* =============================================================================
   ADMIN
   ============================================================================= */

.admin-section + .admin-section { margin-top: clamp(4rem, 8vw, 6rem); }
.section-title {
  font: 700 clamp(2rem, 1.5rem + 2vw, 3rem) / 1 var(--display);
  padding-bottom: 1.25rem; margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--rule);
}
.add-form { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto; align-items: end; gap: 0.75rem; max-width: 52rem; }
.add-form .field { display: grid; gap: 0.45rem; }
.admin-status { margin-top: 1rem; max-width: 52rem; }
.admin-status:empty { display: none; }
.copy-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.6rem; padding-left: calc(0.62em + 0.6em); }
.copy-row code { font: 400 0.9375rem/1.3 var(--voice); padding: 0.55rem 0.75rem; background: var(--graphite); border: 1px solid var(--rule); overflow-wrap: anywhere; }
.people { width: 100%; border-collapse: collapse; margin-top: 2rem; font-size: 0.9375rem; }
.people th {
  text-align: left; font: 600 0.9375rem/1.2 var(--display); color: var(--ash);
  padding: 0 1rem 0.7rem 0; border-bottom: 1px solid var(--rule);
}
.people td { padding: 0.75rem 1rem 0.75rem 0; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.people .p-name { font: 600 1.0625rem/1.2 var(--display); }
.people .p-mail { overflow-wrap: anywhere; }
.people .num { font-variant-numeric: tabular-nums; text-align: right; }
.people th.num { text-align: right; }
.people td:last-child, .people th:last-child { padding-right: 0; text-align: right; }
.muted { color: var(--ash); }

@media (max-width: 40rem) {
  .add-form { grid-template-columns: 1fr; }
  .add-form .btn { justify-self: start; }
  /* stacked rows; the header row stays for a screen reader (roles are explicit in admin.js) */
  .people thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .people, .people tbody, .people tr, .people td { display: block; width: 100%; }
  .people tr { padding: 1rem 0; border-bottom: 1px solid var(--rule); display: grid; grid-template-columns: 1fr auto; gap: 0.3rem 1rem; }
  .people td { border: 0; padding: 0; text-align: left !important; }
  .people td.p-name { grid-column: 1; }
  .people td.p-act { grid-column: 2; grid-row: 1 / span 2; align-self: start; }
  .people td[data-label]::before { content: attr(data-label) ' '; color: var(--ash); }
  .people td.p-mail, .people td[data-label] { grid-column: 1; }
}

.comments-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; }
.exports { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 1rem; }
.rev { margin-top: 3rem; }
.rev-h {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 1rem;
  padding-bottom: 0.9rem; border-bottom: 1px solid var(--rule);
}
.rev-h h3 { font: 700 1.75rem/1.05 var(--display); }
.rev-h .mail { color: var(--ash); overflow-wrap: anywhere; }
.rev-h .count { margin-left: auto; color: var(--ash); font-size: 0.9375rem; }
.ri {
  display: grid; grid-template-columns: 4rem minmax(0, 46rem); gap: 0.6rem 1.25rem;
  padding: 1.5rem 0; border-bottom: 1px solid var(--rule);
}
.ri-thumb { grid-row: 1 / span 2; width: 4rem; }
.ri-thumb img { width: 100%; border-radius: 1.88% / 1.35%; box-shadow: 0 0 0 1px rgb(255 255 255 / 0.1); }
.ri-thumb.blank { height: 0; }
.ri-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.75rem; }
.ri-name { font: 600 1.25rem/1.15 var(--display); }
.ri-name a { text-decoration: underline; text-decoration-color: var(--steel); text-underline-offset: 0.18em; }
.ri-name a:hover { text-decoration-color: var(--paper); }
.ri-meta { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--ash); font-size: 0.875rem; }
.ri-meta .tag { font: 400 0.8125rem/1 var(--voice); color: var(--paper); border: 1px solid var(--steel); padding: 0.2em 0.4em; }
.ri .notes-list { grid-column: 2; }
.ri .note-meta .who { color: var(--paper); font: 600 0.9375rem/1.2 var(--display); }
/* Enrico reads every comment here, many at a time: a size up, the measure held. */
.page-admin .note-text { font-size: 1rem; line-height: 1.65; max-width: 65ch; }
@media (max-width: 34rem) {
  .ri { grid-template-columns: 3rem minmax(0, 1fr); }
  .ri-thumb { width: 3rem; }
  .ri .notes-list { grid-column: 1 / -1; }
}

/* =============================================================================
   LARGE SCREENS — six cards to a row, the page a little wider
   ============================================================================= */

@media (min-width: 100rem) {
  :root { --page: 92rem; }
  .tiles { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
}

/* =============================================================================
   A FINGER, NOT A POINTER — every target 44px (WCAG 2.5.5)
   ============================================================================= */

@media (pointer: coarse) {
  .small, .lang button, .seg button, .note-meta .btn-line, .tally { min-height: 2.75rem; }
  .views a, .brand { min-height: 2.75rem; }
  .account a { display: inline-flex; align-items: center; min-height: 2.75rem; padding-inline: 0.25rem; }
  .twin-link { min-height: 2.75rem; }
}

/* ---- forced colours: what colour and fill carried, an edge carries ------------- */
@media (forced-colors: active) {
  body::before, body::after { display: none; }
  .views a { border-bottom-color: Canvas; margin-bottom: 0; } /* no overlap: Canvas would cut the bar's rule */
  .views a[aria-current='page'], .type-strip a[aria-current] { border-bottom-color: CanvasText; }
  .lang button[aria-pressed='true'], .seg button[aria-pressed='true'] { forced-color-adjust: none; background: Highlight; color: HighlightText; }
  .prose ul li::before, .sys::before, .tile-btn.has::before { forced-color-adjust: none; background: CanvasText; }
  .tile-btn.draft::before, .draft-flag::before { forced-color-adjust: none; box-shadow: inset 0 0 0 1.5px CanvasText; }
  .dl-arrow, .v-text summary::before, .prose aside > b:first-child::before { forced-color-adjust: none; border-left-color: CanvasText; }
}

/* ---- reduced motion: states arrive, nothing travels -------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root { --fast: 0ms; --base: 0ms; }
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .btn:active, .btn-line:active { transform: none; }
}

/* ---- more contrast asked for: the decorative hairlines become edges ----------- */
@media (prefers-contrast: more) {
  :root { --rule: #6b717c; --ash: #c4c7cc; --steel: #9a9ea6; }
  body::before, body::after { display: none; }
}
