/* Generated by app/bin/make-standalone.js — do not edit. */

/*
 * Site chrome: the design tokens, and the bar that wraps every page.
 *
 * Split out of wikicritic.css on 2026-08-01 so that a page which brings its own
 * complete stylesheet — /submit serves mockups-goal/submit-comment.html
 * verbatim (8.7) — can take the header WITHOUT taking the app's page styles.
 *
 * ‼ Why that mattered. Both stylesheets define `.hero h1`. The mockup's rule
 *   sets no colour: the heading is white because `.hero` is white and colour
 *   inherits. Ours sets `color: var(--navy)` — and a direct declaration beats an
 *   inherited value whatever the source order, so loading the app stylesheet
 *   turned the mockup's headline navy-on-navy and invisible. Loading it "first,
 *   so the page's own rules win" does not help; specificity, not order, decided
 *   it.
 *
 * The tokens live here rather than in wikicritic.css because this is the file
 * both paths load. wikicritic.css imports it, so there is still exactly one
 * definition of the palette.
 */

:root {
  --navy: #151e2b;
  --navy-lift: #1c2a3a;
  --navy-line: #2a3a4d;
  --gold: #c08a30;
  --gold-ink: #8b6914;
  --green: #4a7c59;
  --paper: #eae7e0;
  --paper-lift: #f8f6f1;
  --ink: #23282f;
  --ink-quiet: #6b6355;
  --serif: Georgia, 'Times New Roman', serif;
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* --- top bar --------------------------------------------------------- */

.wc-topbar {
  background: var(--navy);
  color: #fff;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  position: relative;
  z-index: 900;
  font-family: var(--sans);
}

.wc-left { display: flex; align-items: center; gap: 14px; }

/*
 * ‼ A flex row, and it has to be. The waiting list is a <details>, which is a
 *   BLOCK element by default, so dropping one into this corner took a full line
 *   to itself and pushed Submit and Support onto a second row — making the
 *   whole bar two storeys tall. The container never needed a display rule while
 *   it held only inline-block anchors, which is exactly the kind of assumption
 *   that survives until somebody adds a different element.
 *
 * `gap` replaces the whitespace between the anchors, which flex would otherwise
 * collapse to nothing.
 */
.wc-right { display: flex; align-items: center; gap: 10px; }

.wc-brand {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 17px;
  display: flex;
  align-items: center;
  gap: 10px;
}
/*
 * ‼ The brand keeps its white on hover, and gains a gold rule under it
 *   (2026-08-06). It had no hover rule of its own, so it inherited the site's
 *   `a:hover { color: var(--gold-ink) }` — a dark gold chosen to be readable on
 *   paper, which on a near-black bar is almost the bar. Pointing at the word
 *   made it harder to read, which is the opposite of what hover is for.
 *
 * The signal moves to an underline rather than a colour change: on this bar
 * there is no colour that both reads as "gold, our accent" and stays legible,
 * and the word itself never needs to change to say it is a link.
 */
.wc-brand a {
  color: #fff; text-decoration: none;
  border-bottom: 2px solid transparent; padding-bottom: 1px;
}
.wc-brand a:hover {
  color: #fff; border-bottom-color: var(--gold, #c08a30);
}

.wc-beta {
  font-family: var(--sans);
  font-size: 9px;
  background: var(--gold);
  color: var(--navy);
  padding: 2px 7px;
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.wc-menu { position: relative; }

.wc-menu-btn {
  background: transparent;
  border: 1px solid #3a4a5d;
  color: #cfd6e0;
  border-radius: 4px;
  height: 30px;
  width: 36px;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wc-menu-btn:hover { border-color: var(--gold); color: #fff; }

.wc-menu-panel {
  position: absolute;
  top: 40px;
  left: 0;
  background: var(--navy-lift);
  border: 1px solid var(--navy-line);
  border-radius: 6px;
  min-width: 236px;
  padding: 6px 0;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  z-index: 1000;
  display: none;
}
.wc-menu-panel.open { display: block; }

.wc-menu-panel a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 8px 16px 8px 24px;
  position: relative;
  color: #dfe4ea;
  text-decoration: none;
  font-size: 13px;
  font-family: var(--sans);
}
.wc-menu-panel a:hover { background: #243447; color: #fff; }
.wc-menu-panel a.wc-active { color: #fff; }
.wc-menu-panel a.wc-active::before {
  content: '\25B8';
  color: var(--gold);
  font-size: 11px;
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
}

.wc-note {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #93a1b2;
  background: var(--navy);
  border: 1px solid var(--navy-line);
  padding: 1px 6px;
  border-radius: 3px;
}

.wc-menu-sec {
  padding: 8px 16px 3px;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #77879a;
}

.wc-menu-div { border-top: 1px solid var(--navy-line); margin: 6px 0; }

/*
 * The two top-bar buttons, from mockups-goal/header.js (8.7).
 *
 * Both are anchors here. The goal header makes Support a <button>, and its own
 * comment records what that cost: three separate rules — a transparent border,
 * font-family:inherit and an explicit line-height — were needed to make a
 * button and an anchor agree on 28px, and removing any one brought the bug
 * back. Two anchors agree by construction, so that whole apparatus is unneeded.
 * 16 + 5 + 5 + 1 + 1 = 28.
 */
.wc-topbar .wc-right a {
  padding: 5px 14px;
  border-radius: 4px;
  font-size: 12px;
  line-height: 16px;
  font-weight: 700;
  text-decoration: none;
  display: inline-block;
  border: 1px solid transparent;
  font-family: var(--sans);
}
/* Submit is the action we want pressed: filled green, white text at 4.86:1. */
.wc-topbar .wc-btn-submit { background: var(--green); color: #fff; border-color: var(--green); }
.wc-topbar .wc-btn-submit:hover { background: #56906a; border-color: #56906a; color: #fff; }
.wc-topbar .wc-btn-support { background: var(--gold); color: var(--navy); }
.wc-topbar .wc-btn-support:hover { background: #d09a3c; color: var(--navy); }

.wc-topbar a:focus-visible,
.wc-topbar button:focus-visible,
.wc-menu-panel a:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 3px;
}

/* A planned destination, in the menu or the footer. Dimmed, never disabled:
 * it resolves to a page that explains itself. */
.wc-planned { opacity: 0.62; }
.wc-menu-panel a.wc-planned:hover { opacity: 1; }
.wc-note.wc-soon {
  background: transparent; color: #8a97a8; border: 1px solid #3a4a5d;
  font-size: 8.5px; letter-spacing: .05em;
}

/* Narrow screens. Widest breakpoint first, as everywhere in this project. */
@media (max-width: 700px) {
  .wc-topbar { padding: 0 12px; gap: 8px; }
  .wc-brand { font-size: 15px; gap: 6px; }
  /* The brand is the only part that may be squeezed; the buttons keep their
     size and lose words instead. */
  .wc-left { min-width: 0; }
  .wc-brand a { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .wc-right { flex-shrink: 0; }
}

/* Labels shorten, they do not truncate: "Support WikiCritic" becomes
   "Support" rather than being clipped mid-word.
   Moved out from 430px on 2026-08-04: making `.wc-right` a flex row stopped the
   buttons wrapping, so instead of two storeys the bar became wider than the
   window. 620px is where the arithmetic says the row stops fitting once the
   brand and the waiting badge are counted. */
@media (max-width: 620px) {
  .wc-sm-hide { display: none; }
}

@media (max-width: 430px) {
  .wc-beta { display: none; }
  /* Below this the two buttons and a badge cannot all keep their padding.
     Losing some beats a page that scrolls sideways, which is the one outcome a
     top bar must never produce. */
  .wc-topbar .wc-right a { padding: 5px 9px; }
  .wc-topbar { padding: 0 8px; }
}

/* --- the waiting list (4.16) ------------------------------------------- */

/*
 * A count in the top bar that opens a list of what is waiting. Operators only,
 * and rendered at all only when something IS waiting: a zero badge is
 * furniture, and the point of a badge is that its presence means something.
 *
 * ‼ Note the selector. `.wc-topbar .wc-right a` above gives every anchor in
 *   this corner a filled button's padding and border, which would turn each
 *   line of the panel into a button. These rules undo that for the panel
 *   specifically rather than loosening the rule above, because that rule is
 *   what makes Submit and Support agree on 28px — see its comment.
 */
/*
 * Two shapes, one appearance. With a single queue this is a plain link straight
 * to it; with several it is a disclosure listing them. The styling is shared so
 * the bar does not change shape as the second thing arrives.
 */
.wc-waiting { position: relative; }
.wc-topbar .wc-right a.wc-waiting-one {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 4px;
  font-family: var(--sans); font-size: 12px; font-weight: 700; line-height: 16px;
  color: #d8dde5; background: transparent;
  border: 1px solid rgba(255, 255, 255, .22);
}
.wc-topbar .wc-right a.wc-waiting-one:hover { border-color: var(--gold); color: #fff; }
/*
 * Padding and line-height copied from `.wc-topbar .wc-right a` above, so the
 * badge is exactly as tall as Submit and Support: 16 + 5 + 5 + 1 + 1 = 28. A
 * control one pixel taller than its neighbours makes the whole 48px bar grow.
 */
.wc-waiting > summary {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 4px; cursor: pointer;
  font-family: var(--sans); font-size: 12px; font-weight: 700; line-height: 16px;
  color: #d8dde5; border: 1px solid rgba(255, 255, 255, .22);
  list-style: none;
}
.wc-waiting > summary::-webkit-details-marker { display: none; }
.wc-waiting > summary:hover { border-color: var(--gold); color: #fff; }

/* Red, and the one red thing in the header: it is the only element that means
   "somebody is waiting on you". */
.wc-badge {
  display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 9px;
  background: #a4442e; color: #fff; text-align: center;
  font-size: 11px; font-weight: 700; line-height: 18px;
}
.wc-badge-sm { min-width: 16px; line-height: 16px; font-size: 10px; }

.wc-waiting-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  min-width: 240px; padding: 6px;
  background: #fff; border: 1px solid #d8d2c6; border-radius: 6px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .22);
}
.wc-topbar .wc-waiting-panel a {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border: 0; border-radius: 4px;
  font-weight: 400; font-size: 13px; color: var(--navy);
}
.wc-topbar .wc-waiting-panel a:hover { background: #f2efe8; color: var(--navy); }

@media (max-width: 620px) {
  /* Full width on a phone, because a 240px panel anchored to the right edge of
     a narrow screen has nowhere to go. */
  .wc-waiting-panel { position: fixed; left: 8px; right: 8px; min-width: 0; }
}

/* --- the article lookup box in the top bar (2026-08-04) ---------------- */

/*
 * Taken from mockups-goal/header.js, where it is `cfg.search`. Sized to sit in
 * the navy bar without competing with the brand.
 *
 * ‼ White, 2026-08-06 (Larry). It was `#1c2a3a` on a bar that is `#151e2b`
 *   shading to `#1c2a3a` — a field the same colour as the thing it sits on,
 *   which is not restraint, it is invisibility. A dark field one shade lighter
 *   was tried the same day and was still too quiet against navy. **A control
 *   has to look like somewhere you can type before anything about its styling
 *   matters**, and on this bar only paper does that.
 *
 * Its text goes navy with it: white-on-white would have replaced an invisible
 * box with an invisible caret.
 */
.wc-search-form { display: flex; margin-left: 4px; }
.wc-topbar .wc-search {
  background: #fff; border: 1px solid #cfd6dd; border-radius: 4px;
  padding: 6px 14px; color: var(--navy, #151e2b); font-size: 13px; width: 300px;
  outline: none; font-family: var(--sans);
}
.wc-topbar .wc-search::placeholder { color: #6b7480; }
.wc-topbar .wc-search:focus { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(192,138,48,.35); }

/*
 * Recent searches, ours (2026-08-06). Anchored to the form, so it begins where
 * the box begins whatever the bar is doing around it — the browser's own panel
 * sat a hundred pixels to the right of the field it belonged to, which is the
 * complaint that produced this.
 */
.wc-recent {
  position: absolute; top: calc(100% + 4px); left: 0; min-width: 100%;
  background: #fff; border: 1px solid #cfd6dd; border-radius: 4px;
  box-shadow: 0 6px 20px rgba(0,0,0,.28); padding: 4px 0; z-index: 60;
  font-family: var(--sans);
}
.wc-recent-item {
  display: block; padding: 7px 14px; font-size: 13px;
  color: var(--navy, #151e2b); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 340px;
}
.wc-recent-item:hover { background: #f2efe8; color: var(--navy, #151e2b); }
.wc-recent-clear {
  display: block; width: 100%; text-align: left; background: none; cursor: pointer;
  border: 0; border-top: 1px solid #e6e0d5; margin-top: 4px; padding: 7px 14px;
  font-family: var(--sans); font-size: 12px; color: #6b7480;
}
.wc-recent-clear:hover { color: var(--gold); }

/*
 * ‼ Below 900px the box goes and the menu link appears — never both, and never
 *   neither. A 300px input beside a brand, a menu button and two buttons on a
 *   phone leaves all of them too small to use, and shrinking it to fit produces
 *   a search box nobody can type a title into.
 */
.wc-mi-search { display: none; }

@media (max-width: 900px) {
  .wc-search-form { display: none; }
  .wc-mi-search { display: block; }
  a.wc-mi-search { display: block; }
}


/*
 * WikiCritic — shared stylesheet.
 *
 * The mockups inline their CSS because each file must open standalone over
 * file://. The application has no such constraint, so the palette and type
 * live here once. Tokens match the mockups exactly; keep them in step.
 *
 * Media queries are written widest-first, as in the mockups: scattering them
 * caused a real bug there, where a 720px rule beat a 600px rule at 500px
 * purely because it came later in source order.
 */

/*
 * ‼ chrome.css is NOT imported here any more, and this comment is the headstone.
 *
 *   `@import url('/static/chrome.css')` carried no version while this file was
 *   linked as `wikicritic.css?v=<assetVersion>`. So every change to the top bar
 *   sat behind a cache nothing busted: the stylesheet the browser already had
 *   was, as far as it could tell, still current. It presented as CSS that
 *   "does not work" — a media query that never fired — which sends you looking
 *   at the rule rather than at whether the file arrived.
 *
 *   Both sheets are now linked from `views/partials/head.ejs`, chrome first,
 *   both carrying the version. That also removes a render-blocking import:
 *   an @import cannot start downloading until the file containing it has.
 */


* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  line-height: 1.6;
}

a { color: #1c4f7c; }
a:hover { color: var(--gold-ink); }

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

.wrap {
  max-width: 860px;
  margin: 0 auto;
  padding: 40px 28px 64px;
}

.hero h1 {
  font-family: var(--serif);
  font-size: 32px;
  line-height: 1.25;
  margin: 0 0 14px;
  color: var(--navy);
}

.lede { font-size: 17px; margin: 0 0 8px; }

/*
 * ‼ `.hero-dark` was here and is gone (Larry, 2026-08-09). It dressed /about
 *   and nothing else, and on the page it was furniture in front of prose. The
 *   front page keeps its own gradient hero in `front.css`, which is a different
 *   decision about a different page.
 */

.panel {
  background: var(--paper-lift);
  border: 1px solid #d8d2c6;
  border-left: 3px solid var(--gold);
  border-radius: 4px;
  padding: 22px 26px;
  margin-top: 28px;
}

.panel h2 {
  font-family: var(--serif);
  font-size: 19px;
  margin: 0 0 10px;
  color: var(--navy);
}

/* What a person told a requester, on their own status page (2026-08-06).
   Green-ruled rather than gold: on this page gold is the site talking about
   process, and these are the sentences somebody wrote to them. */
.reply-thread { border-left-color: var(--green, #4a7c59); }
.reply { margin: 0 0 16px; }
.reply:last-child { margin-bottom: 0; }
.reply-line { margin: 0; }
.reply-body { margin: 4px 0 0; white-space: pre-wrap; }
.reply-at { margin: 4px 0 0; font-family: var(--sans); font-size: 12px; color: var(--ink-quiet); }

/* Their own words, read back to them. Quoted rather than set as body text, so
   nobody mistakes what they wrote for what we said. */
.sent-head { font-family: var(--serif); font-size: 16px; margin: 18px 0 6px; color: var(--navy); }
.sent-claim { margin: 0; padding: 10px 14px; border-left: 3px solid #d8d2c6;
  background: var(--paper); white-space: pre-wrap; }
.sent-contact { font-size: 13px; margin: 10px 0 0; }

/* The acknowledgement above the send button: a line to read, not a notice to
   skip, so it sits at body size beside its box rather than in small print. */
.ack { display: flex; gap: 10px; align-items: flex-start; margin: 22px 0 18px; }
.ack input { margin-top: 4px; flex: 0 0 auto; }

.panel h1 {
  font-family: var(--serif);
  font-size: 40px;
  margin: 0 0 6px;
  color: var(--navy);
}

.panel p { margin: 0 0 10px; }
.panel p:last-child { margin-bottom: 0; }

.muted { color: var(--ink-quiet); font-size: 15px; }

/* --- footer ---------------------------------------------------------- */

/* --- footer -----------------------------------------------------------
 * Dark, full-bleed and centred, from `.footer` in mockups-goal/index.html.
 *
 * ‼ The app had taken the footer's link colours and left its BACKGROUND
 *   behind, so `#b0b8c4` links and a `#fff` hover sat on the paper colour: the
 *   link was low-contrast at rest and invisible under the pointer. The colours
 *   were never the mistake — the surface they were designed against had gone
 *   missing. Restoring it fixes the hover and the navy `#2a3a4d` divider in
 *   the same move, since both were right for the footer this is meant to be.
 */
.wc-foot {
  background: var(--navy);
  margin-top: 48px;
  padding: 26px 28px 34px;
  text-align: center;
  /*
   * Brighter than the mockup's #8a97a8, deliberately. Measured on #151e2b that
   * was 5.6:1 — passing AA on paper and thin to read at 13px — and the meta
   * line's #5a6a7e was 3.0:1, which fails outright at 11px. These are 8.6:1 and
   * 6.3:1. Grey on black is the easiest contrast to under-set, because the
   * designer is looking at it on a bright screen in a dark room.
   */
  color: #b6c0cd;
  font-size: 13px;
}
.wc-foot p { margin: 0 0 6px; max-width: 720px; margin-inline: auto; }
.wc-foot-meta { font-family: var(--sans); font-size: 11px; letter-spacing: 0.04em; color: #93a0b0; }

/* --- narrow screens. Widest breakpoint first. ------------------------ */

/* --- AI report page (4.12) -------------------------------------------- */
/* Tokens copied from mockups-goal/ai-report-acupuncture.html. The purple
   #6b5ce7 is the AI-provenance colour and means one thing only: machine
   authorship. Do not reuse it for emphasis. */

.report-header { background: var(--navy-lift); color: #fff; padding: 28px 28px 24px; }
.rh-inner { max-width: 800px; margin: 0 auto; }
/*
 * The way back, above the title. Gold rather than the sub-line's blue, because
 * it is the one link on this header that leads deeper into the site rather than
 * out of it — and because a reader looking for the way out should find it
 * before reading the heading, not after the seven criteria below.
 */
.rh-back {
  display: inline-block; margin: 0 0 8px;
  font-family: var(--sans); font-size: 13px; font-weight: 700;
  color: var(--gold); text-decoration: none;
}
.rh-back:hover { color: #e0b25c; text-decoration: underline; }

.rh-inner h1 { font-family: var(--serif); font-size: 26px; font-weight: 400; margin: 0 0 4px; }
.rh-sub { font-size: 13px; color: #8a97a8; margin-bottom: 10px; }
.rh-sub a { color: #5a8fbf; text-decoration: none; }
.rh-sub a:hover { text-decoration: underline; }
/* Off-site links read as such: the ones that stay here are the default. */
.rh-off { color: #7f8b99 !important; }
.rh-badge {
  display: inline-block; font-size: 9px; font-weight: 700; background: #6b5ce7; color: #fff;
  padding: 3px 10px; border-radius: 3px; letter-spacing: 0.06em; margin-right: 8px;
  font-family: var(--sans);
}
.rh-meta { font-size: 11px; color: #77879a; font-family: var(--sans); }

.report-body { max-width: 800px; margin: 0 auto; padding: 28px 28px 60px; }

.method {
  background: var(--paper-lift); border: 1px solid #d8d2c6; border-left: 3px solid #6b5ce7;
  border-radius: 5px; padding: 14px 18px; margin-bottom: 22px;
  font-size: 12.5px; line-height: 1.7; color: #55504a;
}
.method b { color: var(--navy-lift); }

.grade-summary {
  background: #fff; border: 1px solid #d4cfc6; border-radius: 6px;
  padding: 20px 24px; margin-bottom: 28px;
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 12px; text-align: center;
}
.gs-item .gs-grade { font-size: 22px; font-weight: 700; font-family: var(--serif); }
.gs-item .gs-label { font-size: 10px; color: var(--ink-quiet); margin-top: 2px; font-family: var(--sans); }
.gs-item .gs-lede { font-size: 10px; color: #726c61; margin-top: 1px; font-family: var(--sans); }
.gsrc, .gsrc-inline {
  font-size: 9px; font-weight: 700; letter-spacing: 0.06em; color: #6b5ce7; font-family: var(--sans);
}
/* An ungraded criterion has no provenance label, so the div is empty. Keep its
   line so the labels below it stay on one baseline across the row — the empty
   ones used to be held open by an &nbsp; that was printing itself. */
.gsrc:empty { min-height: 1em; }
.gsrc-inline { margin-left: 8px; }

/* 4.3: provenance travels with the grade, never as decoration. */
.ga { color: #2d8659; } .gb { color: #2d8659; } .gc { color: #d4932a; }
.gd { color: #c0392b; } .gf { color: #a82020; } .gn { color: var(--ink-quiet); }

.section { background: #fff; border: 1px solid #d4cfc6; border-radius: 6px; margin-bottom: 18px; }
.section-header {
  padding: 14px 20px; display: flex; justify-content: space-between; align-items: center;
  border-bottom: 1px solid #ebe8e1;
}
.section-header h2 { font-family: var(--serif); font-size: 17px; font-weight: 400; margin: 0; color: var(--navy); }
.section-grade { font-size: 20px; font-weight: 700; font-family: var(--serif); }
.section-note { font-size: 11px; color: var(--ink-quiet); font-family: var(--sans); }
.section-body { padding: 16px 20px; font-size: 14px; line-height: 1.75; color: #444; font-family: var(--serif); }
.section-body p { margin: 0 0 12px; }
.section-body ul { margin: 0 0 12px; padding-left: 20px; }
.section-body li { margin-bottom: 5px; }

/* ‼ 12.5px italic grey for a sentence that DEFINES what the lede is — the one
   thing a reader must understand before the grades below it mean anything.
   Body size, ordinary ink. Italic kept: it introduces rather than asserts. */
.lede-intro { color: var(--ink); font-style: italic; }
.lede-crit { border-top: 1px solid #ebe8e1; padding-top: 12px; margin-top: 12px; }
.lede-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.lede-name { font-family: var(--sans); font-size: 12px; letter-spacing: 0.04em;
             text-transform: uppercase; color: var(--ink-quiet); font-weight: 700; }
.back { max-width: 800px; margin: 0 auto; font-family: var(--sans); font-size: 13px; }

/* Grade summary doubles as a table of contents. Links inherit the grade colour
   so provenance and severity still read at a glance — a blue underlined B
   would say "link" louder than it says "B". */
.gs-link { display: block; color: inherit; text-decoration: none; border-radius: 4px; }
.gs-link:hover .gs-grade,
.gs-link:focus-visible .gs-grade { text-decoration: underline; }
.gs-link:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.gs-item .gs-lede:hover, .gs-item .gs-lede:focus-visible { text-decoration: underline; }

.to-top {
  font-family: var(--sans); font-size: 12px; font-weight: 400;
  color: var(--ink-quiet); text-decoration: none; margin-left: 10px;
}
.to-top:hover { color: var(--gold-ink); }

/* --- label mode ------------------------------------------------------- *
 * Swaps every letter on the report for its gloss. Done with a checkbox and
 * the sibling combinator rather than script: the summary and the sections are
 * siblings of the input, so one :checked drives the whole page. Both forms are
 * in the DOM and one is hidden, so nothing has to be re-rendered or fetched.
 *
 * These rules out-specify the 700px block below (four classes against two), so
 * the label sizing survives on a phone instead of reverting to the letter's. */
.lm-check { position: absolute; width: 1px; height: 1px; opacity: 0; }
.summary-tools { display: flex; justify-content: flex-end; margin: 0 0 8px; }
.lm-switch {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--sans); font-size: 12px; color: var(--ink-quiet);
  -webkit-user-select: none; user-select: none;
}
.lm-track {
  flex: none; position: relative; width: 32px; height: 18px;
  border-radius: 9px; background: #cfc9be; transition: background .15s;
}
.lm-knob {
  position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
  border-radius: 50%; background: #fff; transition: transform .15s;
}
.lm-check:checked ~ .summary-tools .lm-track { background: var(--gold); }
.lm-check:checked ~ .summary-tools .lm-knob { transform: translateX(14px); }
.lm-check:checked ~ .summary-tools .lm-switch { color: var(--gold-ink); }
.lm-check:focus-visible ~ .summary-tools .lm-track {
  outline: 2px solid var(--gold); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .lm-track, .lm-knob { transition: none; }
}

/* Both forms ship; exactly one shows. */
.g-lab { display: none; }
/*
 * ‼ `.cmp` joined these on 2026-08-09, when the switch went onto the dossier.
 *   The selectors are written out rather than collapsed because each one names
 *   a SIBLING of the checkbox: the toggle only reaches what follows it, so a
 *   panel moved above the input silently stops responding.
 */
.lm-check:checked ~ .grade-summary .g-let,
.lm-check:checked ~ .cmp .g-let,
.lm-check:checked ~ .section .g-let { display: none; }
.lm-check:checked ~ .grade-summary .g-lab,
.lm-check:checked ~ .cmp .g-lab,
.lm-check:checked ~ .section .g-lab { display: inline; }

/*
 * A comparison cell is a 62px column built for one character. Showing a gloss
 * in it needs the column to give: the letters keep their mono/serif treatment,
 * the words take the sans stack at a size that will wrap inside the cell.
 */
.lm-check:checked ~ .cmp .rg {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  line-height: 1.25; letter-spacing: 0; padding: 2px 4px;
  display: inline-block; white-space: normal; overflow-wrap: break-word;
}
.lm-check:checked ~ .cmp th.num,
.lm-check:checked ~ .cmp td.num { width: auto; min-width: 96px; }
/*
 * On a phone the glosses make the table wider than the screen. It scrolls
 * inside its own container rather than scrolling the page — the house rule —
 * but there is no reason to make it scroll further than it must, so the columns
 * give back what they can.
 */
@media (max-width: 620px) {
  .lm-check:checked ~ .cmp th.num,
  .lm-check:checked ~ .cmp td.num { min-width: 74px; }
  .lm-check:checked ~ .cmp .rg { font-size: 10px; padding: 2px 3px; }
}

/* A letter is one glyph set in Georgia at 22px; a gloss is up to twenty-six
   characters. Nothing about the letter's typography survives the swap. */
.lm-check:checked ~ .grade-summary .gs-grade {
  font-family: var(--sans); font-size: 11.5px; font-weight: 700;
  line-height: 1.3; overflow-wrap: break-word;
}
.lm-check:checked ~ .section .section-grade {
  font-family: var(--sans); font-size: 13px; font-weight: 700;
  text-align: right; overflow-wrap: break-word;
}
/* Both headers are single-line flex rows built for a one-character grade. */
.lm-check:checked ~ .section .section-header { flex-wrap: wrap; gap: 2px 12px; }
.lm-check:checked ~ .section .lede-head { flex-wrap: wrap; }

/* Anchored sections should not land flush against the viewport edge. */
.section, .lede-crit { scroll-margin-top: 14px; }

@media (max-width: 620px) {
  .wrap { padding: 28px 14px 48px; }
  .report-header { padding: 16px 14px 14px; }
  .rh-inner h1 { font-size: 21px; }
  .report-body { padding: 14px 14px 30px; }
  .grade-summary { padding: 12px 14px; gap: 9px; grid-template-columns: repeat(4, 1fr); }
  .gs-item .gs-grade { font-size: 19px; }
  .method { padding: 10px 12px; }
  .section-header { padding: 10px 12px; }
  .section-body { padding: 11px 12px; font-size: 13.5px; }
  .section-header h2 { font-size: 16px; }
  .panel { padding: 16px 14px; }
  .hero h1 { font-size: 26px; }
  .wc-foot { padding: 20px 14px 32px; }
  .row { flex-direction: column; }
}

@media (max-width: 430px) {
  .grade-summary { grid-template-columns: repeat(2, 1fr); }
}

/* --- operator console ------------------------------------------------- */

/*
 * Waiting overlay for a run.
 *
 * The assess request is synchronous and blocks for about a minute, so without
 * this the browser shows a dead page and the honest question is whether it has
 * hung. The bar is indeterminate on purpose: nothing outside the request knows
 * how many of the seven calls have returned, and a bar that implies otherwise
 * would be a lie. A real fraction needs the job to outlive the request, which
 * is Group 1 work.
 *
 * Progressive enhancement: no script, no overlay, form still posts.
 */
.wait {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgba(21, 30, 43, 0.82);
  padding: 20px;
}
.wait-card {
  background: var(--paper, #f8f6f1); border-radius: 8px;
  padding: 26px 28px; max-width: 420px; width: 100%;
  text-align: center; box-shadow: 0 18px 50px rgba(0,0,0,0.35);
}
.wait-card h2 { font-family: var(--serif); font-size: 20px; margin: 0 0 8px; color: var(--navy); }
.wait-card p { font-size: 13.5px; color: var(--ink-quiet); margin: 0 0 16px; font-family: var(--sans); }
.wait-bar { height: 6px; border-radius: 3px; background: #d9d4ca; overflow: hidden; }
.wait-bar span {
  display: block; height: 100%; width: 38%; border-radius: 3px;
  background: var(--gold);
  animation: wait-slide 1.6s ease-in-out infinite;
}
@keyframes wait-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(305%); }
}
.wait-meta {
  margin-top: 12px; font-family: var(--sans); font-size: 12px; color: var(--ink-quiet);
  font-variant-numeric: tabular-nums;
}
/* Without motion the bar must still read as "working", so fall back to a pulse
   rather than a stripe frozen at 38%, which looks like stalled progress. */
@media (prefers-reduced-motion: reduce) {
  .wait-bar span { width: 100%; animation: wait-pulse 2s ease-in-out infinite; }
  @keyframes wait-pulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
}

.panel-warn { border-left-color: #a4442e; }
.warn { color: #a4442e; font-family: var(--sans); font-size: 12px; margin-left: 8px; }

.row { display: flex; gap: 10px; margin: 12px 0; }
.row input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid #cfc8ba;
  border-radius: 4px;
  font-family: var(--serif);
  font-size: 15px;
  background: #fff;
}
.row button {
  /* Buttons carry their own vertical padding rather than relying on the flex
     parent stretching them — when this row stacks on a phone the stretch goes. */
  padding: 9px 20px;
  border: 1px solid var(--green);
  border-radius: 4px;
  background: var(--green);
  color: #fff;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.row button:hover { background: #56906a; border-color: #56906a; }

/*
 * ‼ THE ARTICLE LOOKUP INSIDE ONE OF THOSE ROWS (2026-08-10, the operator's
 *   assessment form). `.row` is a flex line of an input and a button; the lookup
 *   puts a wrapper around the input carrying a results list and a status line
 *   beneath it, so the wrapper takes the flex growth the input used to have and
 *   the input fills it.
 *
 * ‼ AND THE ROW ALIGNS TO THE TOP, or the button would ride down the row's
 *   middle as the suggestions open and the box grew taller under it — the button
 *   moving because a list appeared somewhere else. Scoped to a row that actually
 *   contains a lookup, so every other `.row` on the console keeps the centring
 *   it was written with.
 */
.row:has(.wc-title-lookup) { align-items: flex-start; }
.row .wc-title-lookup { flex: 1 1 auto; min-width: 0; }
.row .wc-title-lookup input[type="text"] { width: 100%; }
.row .wc-title-results { max-width: none; }
/*
 * ‼ AND THE SUGGESTIONS ARE NOT SUBMIT BUTTONS, though they are `<button>`s.
 *   `.row button` scores (0,1,1) against `.wc-title-hit`'s (0,1,0), so every
 *   suggestion came out in the green, bold, 20px-padded dress of the *Assess*
 *   button beside them — three green blocks under the box, each looking like the
 *   thing that spends the money. Found by rendering the page; it is invisible in
 *   either stylesheet alone, and it is the third time this exact score has
 *   caught this repo.
 *
 *   So the hit restates everything the row sets on a button, rather than
 *   trusting the order of two files.
 */
.row .wc-title-hit {
  padding: 7px 11px;
  border: none; border-bottom: 1px solid #ece8e0; border-radius: 0;
  background: none; color: var(--ink);
  font-family: var(--sans); font-size: 13.5px; font-weight: 400;
}
.row .wc-title-hit:last-child { border-bottom: none; }
.row .wc-title-hit:hover, .row .wc-title-hit:focus-visible {
  background: #f4f1ea; color: var(--navy);
}
/* Nothing to say yet is no reason to reserve a line of blank space above the
   panel below. It grows when it has something to report. */
.row .wc-title-status { min-height: 0; }
.row .wc-title-status:empty { margin-top: 0; }

/*
 * ‼ AND UNDONE WHEN THE ROW STACKS. Under 620px `.row` becomes a column, where
 *   `align-items` governs the HORIZONTAL axis instead — so the rule above would
 *   shrink the box and the button to their own content on a phone. This block
 *   sits after the one it overrides, which is the file's rule about media
 *   queries and the half of it that is invisible from the text alone.
 */
@media (max-width: 620px) {
  .row:has(.wc-title-lookup) { align-items: stretch; }
}

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }

.tablewrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 15px; }
/*
 * Rows are single-line by default (2026-08-03). Every cell used to wrap: a
 * two-word article title broke over two lines, a timestamp over three, and the
 * last column fell off the right edge — eight rows filled a screen and the
 * list stopped being scannable, which is the only thing a list is for.
 *
 * The fix is columns that know their own size. The URL is the only cell with
 * unbounded content, so it is the only one allowed to take the slack, and it
 * truncates rather than wrapping.
 */
th, td { text-align: left; padding: 9px 14px 9px 0; border-bottom: 1px solid #ece7de;
         vertical-align: middle; }
tbody tr:hover td { background: #f3f0e9; }
th { font-family: var(--sans); font-size: 11px; text-transform: uppercase;
     letter-spacing: 0.06em; color: var(--ink-quiet); font-weight: 700;
     white-space: nowrap; border-bottom-color: #ddd6ca; }
td:last-child, th:last-child { padding-right: 0; }
.nowrap { white-space: nowrap; }

.crit { border-top: 1px solid #e0dad0; padding-top: 14px; margin-top: 16px; }
.crit h3 { font-family: var(--serif); font-size: 17px; margin: 0 0 8px; color: var(--navy); }

.grade { display: flex; align-items: baseline; gap: 10px; margin-top: 8px; }
.letter {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 22px;
  color: var(--navy);
  min-width: 1.2em;
}
.letter.ungraded { color: var(--ink-quiet); }
.scope { font-family: var(--sans); font-size: 12px; color: var(--ink-quiet); }
.why { margin: 4px 0 0; font-size: 15px; }

/* 4.3: provenance is never optional. An unlabelled grade is the one thing we
   said we cannot ship, so the chip is part of the heading, not decoration. */
.prov {
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  background: var(--navy);
  color: #fff;
  padding: 2px 7px;
  border-radius: 3px;
  vertical-align: middle;
}

/* --- submissions: the running account ---------------------------------- */

.chip {
  display: inline-block; padding: 2px 9px; border-radius: 10px;
  font-family: var(--sans); font-size: 11px; font-weight: 700; letter-spacing: .03em;
}
.st-ok   { background: #dff0e4; color: #235c39; }
.st-hold { background: #f2ead6; color: #7a6320; }
.st-fail { background: #f6dedb; color: #8d2f22; }

.tryme { margin-top: 12px; font-family: var(--sans); font-size: 13px; }
.tryme summary { cursor: pointer; color: var(--ink-quiet); }
.tryme ul { margin: 8px 0 0; padding-left: 18px; }
.tryme li { margin-bottom: 4px; }
.tryme code { font-size: 12px; word-break: break-all; }

.account { list-style: none; margin: 0; padding: 0; }
/* A left rule carries the outcome, so a failure is findable by eye down a long
   account without reading every entry. */
.ev { border-left: 3px solid #d4cfc6; padding: 2px 0 2px 14px; margin-bottom: 16px; }
.ev-ok       { border-left-color: #4a7c59; }
.ev-rejected { border-left-color: #c0392b; }
.ev-error    { border-left-color: #a4442e; }
.ev-head {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline;
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-quiet);
}
.ev-stage { font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--navy); }
.ev p { margin: 4px 0 0; font-family: var(--serif); font-size: 14px; color: #444; }
.ev-detail {
  margin: 6px 0 0; padding: 8px 10px; background: #f3f0ea; border-radius: 4px;
  font-size: 11.5px; color: #55504a; overflow-x: auto; white-space: pre-wrap;
}
.panel-warn-inline {
  border-left: 3px solid #a4442e; padding-left: 12px; margin: 12px 0 0;
  font-family: var(--serif); font-size: 14px;
}
.trunc {
  max-width: 220px; width: 28%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The article title, or the glossed reason it failed. One line and a size down:
   it is a label on the row, not the row's subject, and the whole table has to
   fit without sideways scrolling. */
td.reason {
  white-space: nowrap; max-width: 14em; font-size: 13.5px;
  overflow: hidden; text-overflow: ellipsis;
}

/* Actions in one cell, kept on one line and separated without punctuation. */
.acts { white-space: nowrap; text-align: right; }
.acts a { font-size: 13px; }
.acts a + a { margin-left: 12px; }
.acts form { display: inline; }
.btn-run { padding: 4px 12px; font-size: 13px; }
.btn-run {
  padding: 3px 10px; font-family: var(--sans); font-size: 11.5px; font-weight: 600;
  color: var(--navy); background: var(--paper-lift); border: 1px solid #cfc8ba;
  border-radius: 3px; cursor: pointer;
}
.btn-run:hover { background: #fff; border-color: var(--gold); }

/* --- destructive actions -------------------------------------------------
 * Set apart and coloured, because the console's other buttons are all safe to
 * press twice and this one is not. The red is the same #a4442e the warning
 * panels use, so the page has one colour for "careful" rather than two.
 */
.panel-danger { border-color: #e2c4bb; }
.panel-danger h2 { color: #8c3a26; }
.btn-danger {
  background: #a4442e; color: #fff; border: none; border-radius: 4px;
  padding: 9px 16px; font-family: var(--sans); font-size: 13px; font-weight: 600;
  cursor: pointer;
}
.btn-danger:hover { background: #8c3a26; }
/* ‼ Two acts in one panel, side by side so neither is read as a footnote to
   the other (2026-08-06). Each says what it LEAVES BEHIND before its button,
   and they are different colours because they are different in kind: one keeps
   the published comment, the other does not. */
.danger-acts { display: flex; gap: 18px; align-items: stretch; }
.danger-act { flex: 1 1 0; display: flex; flex-direction: column; }
.danger-act p { margin: 0 0 12px; }
.danger-act form { margin-top: auto; }

/* The milder of the two: nothing published changes, so it does not shout. */
.btn-danger-mild {
  background: #fff; color: #8c3a26; border: 1px solid #d8b6ab;
}
.btn-danger-mild:hover { border-color: #8c3a26; background: #fbf3f1; }

/* Narrower than this and side-by-side squeezes both into a column of words. */
@media (max-width: 720px) {
  .danger-acts { flex-direction: column; gap: 0; }
  .danger-act + .danger-act { border-top: 1px solid #e2c4bb; padding-top: 14px; margin-top: 14px; }
}

.danger-also {
  display: flex; gap: 9px; align-items: flex-start; margin: 0 0 14px;
  font-family: var(--serif); font-size: 14px; color: #4f4a42; line-height: 1.55;
}
.danger-also input { margin-top: 4px; flex-shrink: 0; }

/* --- the acknowledgement page (1.1) --------------------------------------
 * A visitor's page, so it reads as prose with a small table of fact, not as a
 * record card. `.sub-more` is the sentence that explains the state rather than
 * naming it.
 */
.kv { width: 100%; border-collapse: collapse; font-size: 14px; }
.kv th {
  text-align: left; vertical-align: top; white-space: nowrap; padding: 8px 16px 8px 0;
  font-family: var(--sans); font-size: 12px; font-weight: 600; color: var(--ink-quiet);
  text-transform: uppercase; letter-spacing: .04em; width: 1%;
}
.kv td { padding: 8px 0; font-family: var(--serif); word-break: break-word; }
.kv tr + tr th, .kv tr + tr td { border-top: 1px solid #e4dfd5; }
.sub-more {
  margin: 14px 0 0; font-family: var(--serif); font-size: 14px; color: #4f4a42;
}
.hero-took {
  margin: 8px 0 0; font-family: var(--sans); font-size: 12.5px; color: var(--ink-quiet);
}

/* A refusal, written to be acted on.
 * Gold-ruled rather than red: this is a page telling somebody what to do next,
 * not a warning about damage. `.why-quote` is the literal text to paste, so it
 * gets the mono/gold treatment `.lit` has in the mockups — one visual meaning
 * for "type this exactly".
 */
.panel-why { border-left: 3px solid var(--gold); }
.why-what {
  margin: 0 0 10px; font-family: var(--serif); font-size: 16px; color: var(--ink);
}
.why-todo, .why-again {
  margin: 0 0 10px; font-family: var(--serif); font-size: 14px; color: #4f4a42; line-height: 1.6;
}
.why-quote {
  margin: 0 0 10px; padding: 10px 14px; background: var(--paper-lift);
  border: 1px solid #e0dacd; border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; font-weight: 700; color: var(--gold-ink); overflow-x: auto;
}
.why-note {
  margin: 0 0 10px; font-family: var(--serif); font-style: italic; font-size: 13.5px;
  color: var(--ink-quiet); line-height: 1.55;
}
.why-code {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid #e4dfd5;
  font-family: var(--sans); font-size: 12px; color: var(--ink-quiet);
}

.where { list-style: none; margin: 0; padding: 0; }
.where li + li { margin-top: 14px; padding-top: 14px; border-top: 1px solid #e4dfd5; }
.where > li > a {
  font-family: var(--serif); font-size: 16px; font-weight: 700;
}
.where-note {
  display: block; margin-top: 3px;
  font-family: var(--serif); font-size: 13.5px; color: var(--ink-quiet); line-height: 1.55;
}
@media (max-width: 620px) {
  .kv, .kv tbody, .kv tr, .kv th, .kv td { display: block; width: auto; }
  .kv th { padding-bottom: 2px; }
  .kv tr + tr th { border-top: 1px solid #e4dfd5; padding-top: 10px; }
  .kv tr + tr td { border-top: 0; }
}

/* --- the archived copy, contained (6.2) ---------------------------------
 * The frame is given a white background and a border on purpose: what is
 * inside it is somebody else's page, and it should read as a quotation rather
 * than as part of ours. Everything the page tried to load is blocked, so it
 * arrives unstyled and would otherwise sit on our paper colour looking like a
 * region of the console that had lost its formatting.
 */
.src { margin: 16px 0 0; }
.src > summary {
  cursor: pointer; font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  color: var(--navy); padding: 6px 0;
}
.src-frame {
  width: 100%; height: 60vh; min-height: 320px; margin: 8px 0 0;
  border: 1px solid #d4cfc6; border-radius: 4px; background: #fff;
}
@media (max-width: 620px) { .src-frame { height: 50vh; } }

/* --- comment cards ------------------------------------------------------
 * Taken from mockups-goal/dossier-acupuncture.html rather than re-invented,
 * per 4.12: the mockups encode decisions (one visual treatment means one
 * thing; a tag chip on a card is identical to the one in the reference table)
 * that get silently re-decided by whoever writes the CSS instead.
 * Phase 1 renders fewer of these than the mockup does — no endorsements, no
 * reply threading — so those rules are not carried across until something
 * writes them. */

.cc {
  background: #fff; border: 1px solid #d4cfc6; border-radius: 6px;
  padding: 18px 20px; margin-bottom: 14px;
}
.cc-expert { border-left: 3px solid #1b3a5c; }
.cc-top {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin-bottom: 8px; gap: 10px; flex-wrap: wrap;
}
/*
 * ‼ The badge and date must stay at the top right. Once a bio line went into
 *   the left column its longest word set a min-content width wide enough to
 *   push the badges onto their own row, and the date ended up under the
 *   author's self-description as if it belonged to it. The left column may
 *   shrink; the badges may not.
 */
.cc-top > div:first-child { flex: 1 1 60%; min-width: 0; }
.cc-badges { flex: 0 0 auto; }
.cc-author { font-weight: 700; font-size: 14px; font-family: var(--sans); }
.cc-cred { font-size: 12px; color: var(--gold); margin-top: 1px; font-family: var(--sans); }
/* The publication, beside the address it lives at. Not italic: this is a name,
   not a case under discussion. */
.cc-pub { font-weight: 600; color: #4a463f; }
/* What KIND of identifier a handle is. Quiet, because it is a label on a fact
   rather than a fact — the reader wants the handle, not the word for it. */
.idkind { color: #948c80; font-size: 10.5px; }
/*
 * A self-description that is NOT a claim to standing on this topic. Body colour,
 * not the gold of a credentials line: the gold says "this qualifies them here",
 * and these words do not — they are a byline, and read as one.
 */
.cc-bio { font-size: 12px; color: #4a463f; margin-top: 1px; font-family: var(--sans); }
/* The three ways into a comment from its card. Each is a real link and looks
   like the thing it already was — a name, a chip — rather than growing an
   underline that would make the card a wall of links. */
a.cc-author-link { color: inherit; text-decoration: none; }
a.cc-author-link:hover, a.cc-author-link:focus-visible {
  color: var(--navy); text-decoration: underline;
}
a.cc-tag { text-decoration: none; cursor: pointer; }
a.cc-tag.kind:hover, a.cc-tag.kind:focus-visible { background: #24374d; border-color: #24374d; }
.bio-line { font-size: 14.5px; color: var(--ink-quiet); margin: 2px 0 8px; }
.who-class { margin: 0 0 10px; }
/* The scope that qualifies a criterion: "Overall (lede)". Quieter than the
   criterion, because the criterion is what the eye is scanning for. */
.scope-q { color: #948c80; font-size: 11px; }
/* Which scope a grade panel is showing. Stated where it can be read before the
   grades are, because a panel of lede grades read as whole-article grades is a
   misreading the page caused. */
.scope-note {
  font-size: 13px; color: var(--ink); background: #f4f1ea;
  border-left: 3px solid var(--gold); padding: 8px 12px; margin: 0 0 12px;
}
.cc-more { margin: 4px 0 8px; }
.cc-more > summary { font-size: 12px; }
/*
 * ‼ ONE CONTROL, NOT TWO — and on 2026-08-10 Larry decided WHICH one, having
 *   made the same objection twice. On 08-09 this was answered by keeping the "?"
 *   and hiding the summary behind `.js .more.q-only`, which left a control that
 *   only existed with JavaScript and a worded heading that only existed without
 *   it. Today: *"(?) should be deleted wherever the '> ...' header exists."*
 *
 *   So the summary is the control, everywhere, and `a.q` is gone from every view
 *   in the app. The one surviving "?" is on each rubric criterion, where the "?"
 *   IS the summary — one element, not two, which was never the thing he
 *   objected to.
 *
 *   `q-only` is deleted rather than left unused: a rule that hides a summary is
 *   a rule that hides the only way in now.
 */
.cc-more > p { font-size: 12.5px; color: var(--ink-quiet); }
/*
 * Where a comment was published, badged — ported from the goal dossiers, which
 * carry it on every card. The app had the domain and showed it as grey text;
 * "who says this" and "where they said it" are different questions.
 *
 * `.b-plain` is the fallback for a platform we recognise but have no colour
 * for. A colour on this site is a claim about a category, so an unrecognised
 * domain gets no badge at all rather than a made-up one.
 */
.badge {
  font-size: 9px; font-weight: 700; padding: 2px 7px; border-radius: 2px;
  letter-spacing: 0.04em; display: inline-block; font-family: var(--sans);
}
.b-academic { background: #1b3a5c; color: #fff; }
.b-substack { background: #ff6719; color: #fff; }
.b-blog     { background: #4a7c59; color: #fff; }
.b-x        { background: #000;    color: #fff; }
.b-youtube  { background: #c0392b; color: #fff; }
.b-mastodon { background: #6364ff; color: #fff; }
.b-gdoc     { background: #1a73e8; color: #fff; }
.b-plain    { background: #e6e1d6; color: #6b6355; }
/* Not italic: Georgia-italic is reserved site-wide for "a case under
   discussion, never typed". This is metadata about a person. */
.cc-rel { font-size: 11px; color: var(--ink-quiet); margin-top: 2px; font-family: var(--sans); }
.cc-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-bottom: 10px; }
.cc-tag {
  font-size: 10px; font-weight: 600; letter-spacing: .02em; font-family: var(--sans);
  background: #f2eee5; border: 1px solid #ded7c8; color: #6a6357;
  border-radius: 2px; padding: 2px 7px;
}
.cc-tag.kind { background: #1c2a3a; border-color: #1c2a3a; color: #fff; }
.cc-ratings {
  display: flex; gap: 5px 10px; flex-wrap: wrap; margin-bottom: 10px;
  font-size: 12px; color: var(--ink-quiet); font-family: var(--sans);
}
.cc-ratings .rg { font-weight: 700; font-family: var(--mono, Consolas, monospace); }
/*
 * ‼ THE REVIEW IS THE PAGE'S MAIN TEXT and was set smaller and paler than
 *   everything around it — 14px in #444, a step below the site's own prose and
 *   in medium grey. Larry, 2026-08-09: it should be the standard size, and dark
 *   grey or black. He is right, and the reason is not typographic: this is the
 *   one thing on the page written by a person rather than by us, and we had it
 *   quieter than our own explanatory notes.
 */
.cc-text {
  font-size: 16px; line-height: 1.7; color: var(--ink);
  margin-bottom: 10px; font-family: var(--serif);
}
.cc-text p { margin: 0 0 12px; }
.cc-text ul { margin: 0 0 12px; padding-left: 20px; }
.cc-foot {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11px; color: #726c61; padding-top: 8px; border-top: 1px solid #f0ede8;
  font-family: var(--sans); gap: 10px; flex-wrap: wrap;
}
.cc-foot a { color: #1b3a5c; }
.cc-licence { font-size: 11px; color: #726c61; margin-top: 8px; font-family: var(--sans); }
.cc-rationale {
  border-left: 2px solid #ebe8e1; padding-left: 12px; margin: 4px 0 12px;
  font-size: 13.5px; color: #555; font-family: var(--serif);
}
@media (max-width: 620px) {
  .cc { padding: 11px 12px; }
  .cc-foot { flex-direction: column; align-items: flex-start; gap: 6px; }
  .cc-foot > span { word-break: break-word; }
}

/* The origin notice on a comment permalink. Gold-ruled because it is a
   standing statement about whose work this is, not a hint — the weight this
   site gives a rule rather than a tip. */
.origin { border-left: 3px solid var(--gold); background: #fdfbf6; }
.origin p { margin: 0 0 8px; font-size: 14.5px; font-family: var(--serif); }
.origin .url { font-family: var(--mono, Consolas, monospace); font-size: 13px; word-break: break-all; }
.rationale-head {
  font-family: var(--sans); font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--navy); margin-bottom: 4px;
}
.fp { font-family: var(--mono, Consolas, monospace); font-size: 12px; word-break: break-all; }

/* An editorial note about a panel, not content within it. Set as chrome —
   small, sans, letter-spaced, ruled off — because a grey paragraph above a
   body of prose reads as the first line of that prose. Not italic: Georgia
   italic means "a case under discussion" everywhere else on this site. */
.panel-note {
  font-family: var(--sans); font-size: 11px; line-height: 1.55;
  letter-spacing: .02em; color: #8a8378;
  border-bottom: 1px solid #ebe8e1; padding-bottom: 10px; margin: 0 0 16px;
}

/* --- the article page (4.1) ---------------------------------------------
 * From Planning and discussion/mockups-phase-1/dossier-unmoved-mover.html per 4.12. The comparison
 * table is the page's argument: the machine's judgement and the readers' side
 * by side, criterion by criterion, with "not graded" said out loud rather than
 * left blank — a gap a reader can see is worth more than a tidy column. */

.article-header { background: var(--navy-soft, #1c2a3a); color: #fff; padding: 28px; }
.ah-inner { max-width: 940px; margin: 0 auto; display: flex; gap: 24px; align-items: flex-start; }
.ah-score-ring {
  width: 76px; height: 76px; border-radius: 50%; border: 3px solid currentColor;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex-shrink: 0; font-size: 26px; font-weight: 700; font-family: var(--serif);
}
.ah-score-ring .rl { font-size: 8px; font-weight: 700; letter-spacing: .09em; font-family: var(--sans); color: #8a97a8; }
.ah-info { flex: 1; min-width: 0; }
.ah-info h1 { font-family: var(--serif); font-size: 28px; font-weight: 400; margin: 0 0 4px; color: #fff; }
.ah-url { font-size: 13px; margin-bottom: 10px; }
.ah-url a { color: #5a8fbf; }
.ah-stats { display: flex; gap: 20px; font-size: 12px; color: #8a97a8; flex-wrap: wrap; font-family: var(--sans); }
.ah-stats .sv { color: #fff; font-weight: 700; }

.as-box { background: #fff; border: 1px solid #d4cfc6; border-radius: 6px; overflow: hidden; margin-bottom: 28px; }
.as-header {
  background: var(--navy-soft, #1c2a3a); color: #fff; padding: 12px 20px;
  display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 700;
  flex-wrap: wrap; font-family: var(--sans);
}
.ai-badge { background: #6b5ce7; font-size: 9px; padding: 2px 8px; border-radius: 3px; letter-spacing: .06em; }
.as-header a { color: #9fb4cc; font-weight: 500; font-size: 12px; margin-left: auto; }
.as-body { padding: 20px; }

.cmp { width: 100%; border-collapse: collapse; font-size: 13px; font-family: var(--sans); }
.cmp th {
  text-align: left; font-size: 10px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-quiet); font-weight: 700; padding: 0 10px 8px 0; border-bottom: 1px solid #e6e1d8;
}
.cmp th.num, .cmp td.num { text-align: center; width: 88px; }
.cmp td { padding: 7px 10px 7px 0; border-bottom: 1px solid #f0ede8; color: #444; }
/* ‼ The criterion names had no left padding at all and sat hard against the
   edge of the panel (4.12, seen by Larry on the live site). Five pixels, which
   is the most this can take before the column stops looking like a list. */
.cmp th:first-child, .cmp td:first-child { padding-left: 5px; }
.cmp tr:last-child td { border-bottom: none; }
.cmp .rg { font-weight: 700; font-family: var(--mono, Consolas, monospace); font-size: 15px; }
/* Georgia italic: "a case under discussion, never typed" — which is exactly
   what an absent grade is. */
.cmp .ng { font-size: 11px; color: #9a938a; font-style: italic; font-family: var(--serif); }
/*
 * Overall is the row a reader looks for first, and it is a judgement in its own
 * right rather than a summary of the six below it (DESIGN.md → Overall is
 * judged, not computed). So it is set apart deliberately: tinted, heavier, and
 * carrying a gold rule that no other row has. The grade itself also renders a
 * size larger, because on a table of single letters weight alone is easy to
 * miss.
 */
.cmp tr.overall td {
  background: #f4efe3;
  font-weight: 700;
  color: #1a1a1a;
  border-top: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
}
.cmp tr.overall td:first-child { letter-spacing: .02em; }
.cmp tr.overall .rg { font-size: 18px; }

/* Group headers over the AI and Readers columns, so two adjacent "Lede"
   headings cannot be read as a pair belonging to one source. */
.cmp .cmp-groups th {
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  border-bottom: 1px solid #e6e1d8;
  padding-bottom: 3px;
}

/* Said once, in a sentence, instead of a column of "not graded". */
.cmp-absent {
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--ink-quiet);
  margin: 10px 0 0;
}

details.why { margin-top: 16px; border-top: 1px solid #f0ede8; padding-top: 12px; }
details.why summary { cursor: pointer; font-size: 12px; color: #6b5ce7; list-style: none; font-family: var(--sans); }
details.why summary::-webkit-details-marker { display: none; }
details.why summary::before {
  content: '?'; display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border: 1px solid #6b5ce7; border-radius: 50%;
  font-size: 10px; font-weight: 700; margin-right: 7px;
}
details.why p { font-size: 12.5px; line-height: 1.7; color: #555; margin-top: 10px; font-family: var(--serif); }
.as-meta { font-size: 11px; color: var(--ink-quiet); padding-top: 12px; margin-top: 12px; border-top: 1px solid #f0ede8; font-family: var(--sans); }

.section-head { font-family: var(--serif); font-size: 19px; font-weight: 400; margin: 0 0 4px; }
.section-sub { font-size: 12px; color: #888; margin-bottom: 16px; font-family: var(--sans); }

@media (max-width: 620px) {
  .article-header { padding: 18px 12px; }
  .ah-inner { gap: 14px; }
  .cmp th.num, .cmp td.num { width: 62px; }
}

/* A state chip that is also a link to what it produced. */
a.chip { text-decoration: none; }
a.chip:hover { filter: brightness(.95); text-decoration: underline; }

/* --- the article index (4.7), from Planning and discussion/mockups-phase-1/index.html ----------- */
.list { background: #fff; border: 1px solid #d4cfc6; border-radius: 6px; overflow: hidden; }
.list-head {
  display: flex; align-items: baseline; gap: 10px; padding: 13px 20px;
  border-bottom: 1px solid #e6e1d8; background: #faf8f4;
}
.list-head h2 { font-family: var(--serif); font-size: 15px; font-weight: 400; margin: 0; }
.list-head .ct { font-size: 11px; color: #888; margin-left: auto; font-family: var(--sans); }
.row { display: flex; align-items: center; gap: 16px; padding: 15px 20px; border-bottom: 1px solid #f0ede8; }
.row:last-child { border-bottom: none; }
.row-g { flex-shrink: 0; width: 56px; text-align: center; }
.row-g .rg { font-size: 23px; font-weight: 700; font-family: var(--serif); display: block; line-height: 1.1; }
.row-g .gsrc { display: block; font-size: 8px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #9a938a; }
/* Georgia italic: a case under discussion. An unassessed article is exactly that. */
.row-g .none { font-size: 11px; color: #b3aca1; font-family: var(--serif); font-style: italic; }
.row-main { flex: 1; min-width: 0; }
.row-main a { font-family: var(--serif); font-size: 17px; }
.row-main span.plain { font-family: var(--serif); font-size: 17px; color: var(--ink-quiet); }
.row-meta { font-size: 11.5px; color: #726c61; margin-top: 3px; font-family: var(--sans); }
.row-meta .dot { color: #cfc8bc; margin: 0 6px; }
/* An excerpt on an index row. Two lines at most: this is a pointer to the
   comment, not the comment—the whole argument is at /c/<slug>. */
.row-ex {
  font-size: 13px; color: #4a463f; line-height: 1.5; margin-top: 5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.row-ex.muted { color: #857e73; font-style: italic; }
.row-g .gradelink { font-size: 12px; font-weight: 700; text-decoration: none; }
/* Also used as a link to the explanation, so it must not gain link styling. */
a.blp { text-decoration: none; }
a.blp:hover { filter: brightness(1.08); }
.blp {
  display: inline-block; font-size: 8.5px; font-weight: 700; letter-spacing: .06em;
  background: #7a2f2f; color: #fff; padding: 1px 6px; border-radius: 2px;
  margin-right: 6px; vertical-align: 1px; font-family: var(--sans);
}
.note {
  margin-top: 36px; border: 1px dashed #b9b2a5; border-radius: 6px; padding: 16px 20px;
  background: #f2efe8; font-size: 12.5px; color: #5a5348; line-height: 1.7; font-family: var(--sans);
}
.note h3 { font-family: var(--serif); font-size: 14px; font-weight: 400; margin: 0 0 8px; color: #3a3630; }
.note ul { margin: 6px 0 0 18px; }
.note li { margin-bottom: 4px; }
@media (max-width: 620px) { .row { gap: 12px; } }

/* --- the site's shape (group 8) --------------------------------------- */
/*
 * Components for pages that are not finished: the greyed menu entry, the
 * placeholder page, and the empty region drawn in place of data we do not have.
 *
 * One visual treatment means one thing, so all three share a single idiom — a
 * dashed warm-grey border on paper — inherited from the `Note on this mockup`
 * panel in Planning and discussion/mockups-phase-1/. Dashed means "this is the shape of something, not
 * the thing". Solid borders are reserved for real content throughout the site,
 * and nothing here may borrow one.
 */

.region-empty {
  border: 1px dashed #b9b2a5; border-radius: 6px; padding: 16px 20px;
  background: #f2efe8; color: #5a5348; font-size: 13.5px; line-height: 1.7;
  font-family: var(--sans); margin: 10px 0 26px;
}
.region-empty p { margin: 0 0 8px; }
.region-empty p:last-child { margin-bottom: 0; }
.region-empty b { color: #3a3630; }

.planned-flag {
  font-family: var(--sans); font-size: 10px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold-ink); margin: 0 0 6px;
}
.planned-will { margin: 0; padding-left: 20px; }
.planned-will li { margin-bottom: 8px; }
.planned-meta { font-family: var(--sans); font-size: 12.5px; }
.planned-meta p { display: flex; gap: 10px; flex-wrap: wrap; align-items: baseline; }
.pm-key { color: var(--ink-quiet); min-width: 92px; }
.pm-val { font-weight: 700; color: #3a3630; }
.pm-note { color: #8a8275; }

/* --- dashboard -------------------------------------------------------- */
.dash-stats { display: flex; gap: 14px; margin: 0 0 18px; flex-wrap: wrap; }
/*
 * ‼ A card is a link now (2026-08-06), so it needs to say so and to keep its
 *   own colours: the site's `a { color: #1c4f7c }` would otherwise turn the
 *   figure and its label blue, which reads as an unstyled anchor rather than as
 *   a card. Whole card, not the number alone — a 30px numeral is a poor target
 *   and its label is the part that says what it counts.
 */
.ds {
  flex: 1; min-width: 150px; background: var(--paper-lift);
  border: 1px solid #d4cfc6; border-radius: 6px; padding: 16px 18px;
  display: block; text-decoration: none; color: inherit;
  transition: border-color .12s, background .12s;
}
a.ds:hover { border-color: var(--gold); background: #fbf7ef; }
a.ds:hover .ds-l { color: var(--navy); }
.ds-n { display: block; font-family: var(--serif); font-size: 30px; font-weight: 700; color: var(--navy); line-height: 1; }
.ds-l { display: block; font-family: var(--sans); font-size: 11.5px; color: var(--ink-quiet); margin-top: 6px; }
.dash-list { list-style: none; margin: 0 0 12px; padding: 0; }
.dash-list li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid #e6e1d8;
}
.dash-list li:last-child { border-bottom: 0; }
.dash-list .muted { font-family: var(--sans); font-size: 11.5px; }

/* --- dossier: main column and sidebar --------------------------------- */
.dossier-cols { display: flex; gap: 26px; align-items: flex-start; }
.dossier-main { flex: 1; min-width: 0; }
.dossier-side { width: 260px; flex-shrink: 0; }
.side-box {
  background: var(--paper-lift); border: 1px solid #d4cfc6; border-radius: 6px;
  padding: 14px 16px; margin-bottom: 14px; font-family: var(--sans); font-size: 12.5px;
}
.side-title {
  font-family: var(--serif); font-size: 14px; color: var(--navy);
  margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid #e6e1d8;
}
.side-links { list-style: none; margin: 0; padding: 0; }
.side-links li { margin-bottom: 6px; }
.side-note { color: var(--ink-quiet); line-height: 1.6; margin: 0 0 8px; }
.side-box p:last-child { margin-bottom: 0; }
/* A credit, not a sentence of the panel: set apart from what it follows by
   being smaller, quieter, italic and pushed to the right margin. */
.side-credit {
  font-family: var(--serif); font-style: italic; font-size: 12px;
  color: var(--ink-quiet); text-align: right; margin: 6px 0 0;
}
/* Count rows in a sidebar panel, ported from the goal dossiers. A figure, then
   what it counts—the number leads because it is what the panel is for. */
.cr { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 13px; }
.cr-n { font-weight: 700; color: var(--navy); min-width: 18px; font-family: var(--sans); }
.cr-t { color: #555; }
.cr-indent { padding-left: 28px; font-size: 12px; color: #857e73; padding-bottom: 4px; }
.sr { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12px; color: #555; }
@media (max-width: 620px) { .cr-indent { padding-left: 16px; } }

/* --- footer nav -------------------------------------------------------
 * Centred on the dark band, per the goal footer. White on hover is right here
 * and only here: it is the one place on the site where raising contrast means
 * going lighter rather than darker.
 */
.wc-foot-nav {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px;
  margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid #2a3a4d;
  font-family: var(--sans); font-size: 12.5px;
}
/* Brighter than the body text around them, so a link still reads as a link
   without needing an underline to say so. */
.wc-foot-nav a { color: #d3dae3; text-decoration: none; }
.wc-foot-nav a:hover { color: #fff; }

/* Narrow screens. Widest breakpoint first, as everywhere in this file. */
@media (max-width: 860px) {
  /* The sidebar is supplementary, so it follows the argument rather than
     competing with it for a phone's width. */
  .dossier-cols { display: block; }
  .dossier-side { width: auto; margin-top: 26px; }
}
@media (max-width: 620px) {
  .dash-stats { gap: 10px; }
  .ds { padding: 12px 14px; min-width: 120px; }
  .ds-n { font-size: 24px; }
  .planned-meta p { gap: 4px; }
  .pm-key { min-width: 0; width: 100%; }
}

/* --- the spend cap (1.10) ------------------------------------------------
 * A bar rather than a number alone, because the useful question is not "how
 * much" but "how close" — and gold turns red as it fills, so the answer is
 * legible before it is read.
 */
.budget-bar {
  height: 8px; background: #e4dfd5; border-radius: 4px; overflow: hidden; margin: 4px 0 8px;
}
.budget-bar > span {
  display: block; height: 100%; background: var(--gold);
  transition: width .2s ease;
}
.panel-warn .budget-bar > span { background: #a4442e; }

/*
 * The allowance editor on the console (1.12).
 *
 * A stack of labelled inputs inside a <details>, rather than a row: the row is
 * already seven columns wide and a phone has to be able to open one of these.
 * Nothing here appears outside /operator.
 */
.allowance { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; min-width: 220px; }
.allowance label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: #6b6355; }
.allowance label.inline { flex-direction: row; align-items: center; gap: 6px; }
.allowance input[type="number"] { width: 90px; }
.allowance button { align-self: flex-start; padding: 6px 14px; }

/* A blocked address, marked on the row rather than only in its chip: the whole
   line is the thing that has been switched off. */
.st-fail-row > td { background: #fbf1ee; }

/* A failure code, glossed (1.6). Dotted underline is the browser's own idiom
   for "there is more if you hover"; the code itself stays in the detail page
   rather than on the row, since nobody reading a list wants an identifier. */
abbr.why { text-decoration: underline dotted #b9b2a5; text-underline-offset: 3px; cursor: help; }

/*
 * Detail behind a disclosure, not in front of it (2026-08-03).
 *
 * The house rule: a page states the thing, and the reasoning, caveats and
 * background sit behind a "?" or a "more" for the reader who wants them. Prose
 * a reader must get through to reach the number is charged to every reader for
 * the sake of the few.
 */
/*
 * ‼ The revealed text is ordinary body text, not a footnote. It was 13.5px in
 *   #6b6355 with a 62ch cap, and all three were wrong for the same reason: I
 *   styled it as an aside because it starts hidden. Something a reader
 *   deliberately opened is something they want to read.
 *
 *   The width cap was written for a full-page-width panel and never re-checked
 *   inside a numbered list, where the list's own indent had already narrowed
 *   the column — so it wrapped at roughly 60% of the space available and looked
 *   like a mistake, which Larry's screenshot shows it was.
 *
 *   Body colour, body size, and no cap of its own: the panel it sits in already
 *   sets a readable measure, and a second limit inside a limit is how you get
 *   text that stops halfway across an empty box.
 */
/*
 * ‼ Room BELOW as well as above. A `.more` sat flush against whatever followed
 *   it, so its summary line read as a label for the next thing rather than as a
 *   thing of its own — and open, its text ran straight into the field beneath.
 */
.more { margin: 10px 0 16px; }
.more > summary {
  cursor: pointer; color: var(--ink-quiet); font-family: var(--sans); font-size: 13.5px;
}
.more > summary:hover { color: var(--gold); }
.more > p { margin: 10px 0 0; }


/* The number itself, when a panel exists to show one. */
.figure { font-size: 22px; margin: 2px 0 10px; }

/* --- who wrote a comment (4a.1, 4a.2, 4a.4) ---------------------------- */

/*
 * The tag chips, matching the mockups' `.tn`: navy filled for the KIND of a
 * comment, outlined for anything softer. Same treatment must mean the same
 * thing here as it does on a dossier, or a reader learns the vocabulary twice.
 */
.kinds { margin: 0 0 8px; display: flex; gap: 8px; flex-wrap: wrap; }
/*
 * ‼ THE SAME CHIP AS `.cc-tag`, and now actually the same.
 *
 *   `CLAUDE.md` says these two must be identical, "so a reader recognises on a
 *   comment card what they read about in the reference table". They were not:
 *   11px/600 with 3px 10px of padding here against 10px/700 with 2px 7px there,
 *   because each was ported faithfully from a different mockup and the two
 *   mockups disagree. One visual treatment means one thing, so the difference
 *   was saying something neither page intended.
 *
 *   `.cc-tag`'s metrics win: it is the one a reader meets on every dossier,
 *   where `.tn` appears on three pages. Two names survive because they are used
 *   in different documents and a rename would touch every one of them for no
 *   reader-visible gain; a test asserts they stay in step.
 */
.tn {
  display: inline-block; font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: .02em; padding: 2px 7px; border-radius: 2px;
  border: 1px solid transparent;
}
.tn-kind { background: var(--navy); color: #fff; }
/*
 * ‼ Written as pale text on a translucent white border, which assumed a navy
 *   hero. The permalink's hero is paper, so this rendered beige on beige and
 *   looked deliberately hard to read — on the one line of the page that
 *   qualifies everything else on it. An outlined chip in ordinary ink, which is
 *   also what the mockups use for a tag that is not a kind.
 */
.tn-who  { background: transparent; color: var(--ink-quiet); border: 1px solid #c9c2b4; }

.who .says { margin: 10px 0 0; display: grid; grid-template-columns: max-content 1fr; gap: 4px 18px; }
.who .says dt {
  font-family: var(--sans); font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-quiet); font-weight: 700; padding-top: 3px;
}
.who .says dd { margin: 0; }
/*
 * ‼ NOT quiet. It qualifies everything above it, so it must not be smaller or
 *   fainter than the claims it is warning about — which is what it was: 13.5px
 *   muted grey under a hairline. It is an alert to the reader, not a footnote.
 *
 * Body size, a tinted band and a gold rule. Gold is "pay attention" in this
 * palette; red would say something is damaged, and nothing here is. The band is
 * what marks it as a remark ABOUT the page rather than part of it.
 */
/*
 * A full hairline rather than a heavy left rule: the tint already says "this is
 * a remark about the page", and the bar beside it was saying the same thing a
 * second time. One box, one signal.
 */
.who .rests-on {
  margin: 16px 0 0;
  padding: 11px 14px;
  background: #faf3e3;
  border: 1px solid #e6d9b8;
  border-radius: 4px;
  font-size: 15px;
  line-height: 1.6;
  color: #5a4a28;
}
.who .rests-on strong { color: #7a5a12; }

@media (max-width: 620px) {
  .who .says { grid-template-columns: 1fr; gap: 2px; }
  .who .says dd { margin-bottom: 8px; }
}

/* --- the submission log, grouped by attempt (4.15) --------------------- */

/*
 * The boundary between runs has to be visible at a glance, because the whole
 * fault this fixes is two runs reading as one story. A rule and an indent do
 * it; the most recent run is the one an operator came to read, so it is the
 * one that is not dimmed.
 */
.attempt { margin: 0 0 22px; }
.attempt:last-child { margin-bottom: 0; }
.attempt > h3 {
  font-family: var(--sans); font-size: 12px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-quiet); font-weight: 700;
  border-top: 1px solid #ddd6ca; padding-top: 10px; margin: 0 0 8px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.attempt > h3 .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }
/* Older runs are context, not the subject. Still readable, plainly secondary. */
.attempt:not(.attempt-latest) .account { opacity: .72; }

/* --- the assessment table's scope control (4a.7) ----------------------- */

/*
 * Quiet: this chooses which part of the article you are reading grades for,
 * which is a narrowing of an already-correct table rather than a mode the page
 * depends on. Buttons rather than a select, since there are three and they are
 * short — a select would hide two of the three answers behind a click.
 */
.cmp-scope { display: flex; gap: 6px; margin: 0 0 10px; flex-wrap: wrap; }
.cmp-scope button {
  font-family: var(--sans); font-size: 12px; padding: 4px 12px; cursor: pointer;
  background: transparent; color: var(--ink-quiet);
  border: 1px solid #cfc7b8; border-radius: 3px;
}
.cmp-scope button:hover { border-color: var(--gold); color: var(--gold); }
.cmp-scope button.on { background: var(--navy); border-color: var(--navy); color: #fff; }

/* --- the takedown form (6.3) ------------------------------------------- */

/*
 * A stacked form with the label above each field. Not the site's usual inline
 * row: somebody filling this in is upset or is a lawyer, and neither wants to
 * work out which box is which.
 */
.td-form { display: flex; flex-direction: column; gap: 18px; max-width: 46rem; }
.td-form > label { display: flex; flex-direction: column; gap: 5px; }
.td-form > label > span:first-child {
  font-family: var(--sans); font-size: 13px; font-weight: 700; color: var(--navy);
}
.td-form small { color: var(--ink-quiet); font-size: 12.5px; line-height: 1.5; }
.td-form input[type="url"], .td-form input[type="text"], .td-form textarea { width: 100%; }
.td-form textarea {
  font-family: var(--serif); font-size: 15px; padding: 8px 10px;
  border: 1px solid #c9c2b4; border-radius: 3px; background: #fff; resize: vertical;
}
/*
 * The proof block, revealed when "I wrote it" is chosen.
 *
 * ‼ CLOSED by default. It was open until an option was definitely chosen,
 *   reasoning that a first-time visitor should see the requirement — but the
 *   result is a form that greets everybody mid-question, with an unchecked box
 *   and its follow-up already unfolded. Larry's screenshot is the argument: it
 *   reads as broken, and four people in five are being shown a requirement that
 *   does not apply to them.
 *
 *   `:has()` cannot express "nothing is selected", so this needs the positive
 *   form — open only when the withdrawal radio is checked. The cost is that a
 *   browser without `:has()` support never shows it at all, which is why the
 *   OPTION ITSELF now names the requirement ("once we can see it is yours,
 *   below"), and why the server's refusal explains what would have worked.
 *   Nobody is refused without being told why; they simply learn it a moment
 *   later.
 *
 * A grid transition rather than max-height: a guessed height either clips long
 * text or leaves a gap, and this block's length is not fixed.
 */
.proof-slide {
  display: grid; grid-template-rows: 0fr; opacity: 0;
  margin: 0 0 0 27px; padding-left: 12px;
  border-left: 2px solid transparent; pointer-events: none;
  transition: grid-template-rows .18s ease, opacity .18s ease, margin .18s ease;
}
.td-form fieldset:has(input[value="author_withdrawal"]:checked) .proof-slide {
  grid-template-rows: 1fr; opacity: 1; margin: 4px 0 10px 27px;
  border-left-color: #e0dad0; pointer-events: auto;
}
/* ‼ ONE child. A collapsing grid animates its single row to 0fr and the child
   hides its own overflow; with several children only the first row collapses
   and the block never leaves the page. That is how this shipped. */
.proof-slide > .proof-slide-inner { overflow: hidden; min-height: 0; }
@media (prefers-reduced-motion: reduce) { .proof-slide { transition: none; } }

/*
 * A label that changes with the chosen option.
 *
 * ‼ All six ship and CSS picks one, rather than JavaScript swapping text. The
 *   default shows when nothing is selected AND when `:has()` is unsupported —
 *   so the fallback is a neutral wording that reads correctly for any request,
 *   never a blank label.
 *
 * The selectors reach out of the fieldset, so they are written against the form
 * rather than the fieldset: the label sits outside it.
 */
/* Unlike the proof block, the default here is a NEUTRAL wording rather than a
   requirement, so showing it before anything is chosen is correct. */
.claim-label .cl, .claim-note .cl { display: none; }
.claim-label .cl-default, .claim-note .cl-default { display: inline; }
.td-form:has(input[name="kind"]:checked) .cl-default { display: none; }

.td-form:has(input[value="author_withdrawal"]:checked) .cl-withdraw,
.td-form:has(input[value="subject_complaint"]:checked) .cl-subject,
.td-form:has(input[value="legal"]:checked) .cl-legal,
.td-form:has(input[value="misimport"]:checked) .cl-misimport,
.td-form:has(input[value="feedback"]:checked) .cl-feedback { display: inline; }
/* "Something else" has no wording of its own; the neutral one is right for it. */
.td-form:has(input[value="other"]:checked) .cl-default { display: inline; }
.claim-label em { color: var(--ink-quiet); font-style: normal; font-weight: 400; }

.td-form fieldset { border: 1px solid #e0dad0; border-radius: 4px; padding: 12px 14px; margin: 0; }
.td-form legend {
  font-family: var(--sans); font-size: 13px; font-weight: 700; color: var(--navy); padding: 0 6px;
}
.td-form .radio { display: flex; gap: 9px; align-items: flex-start; margin: 6px 0; font-size: 14.5px; }
.td-form .radio input { margin-top: 4px; }
.td-form button { align-self: flex-start; }

/* Shared with any public form that has to report a problem. */
.form-problem {
  background: #fbf1ee; border-left: 3px solid #a4442e; padding: 10px 14px; margin: 0 0 4px;
  font-family: var(--sans); font-size: 13.5px; line-height: 1.6; color: #7a2e1c;
}
.claim-url { font-size: 15px; word-break: break-all; }

/* --- takedown requests in the console (6.3) ---------------------------- */

.td { border-top: 1px solid #e6e0d5; padding: 14px 0 4px; }
.td:first-of-type { border-top: 0; }
/* Unread sits on a tinted band: the point of this panel is that nothing waits
   in it unnoticed. */
.td-open { background: #fdf7ee; margin: 0 -14px; padding-left: 14px; padding-right: 14px; }
.td-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.td-claim { margin: 0 0 8px; white-space: pre-wrap; }
.td-meta { font-size: 13px; display: flex; gap: 6px; flex-wrap: wrap; align-items: baseline; }
.td-meta .trunc { max-width: 32em; display: inline-block; vertical-align: bottom; }
.td-acts { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px; }
.td-acts input[type="text"] { flex: 1 1 18em; min-width: 12em; }
.td-promise { font-size: 13px; margin: 8px 0 0; }

/* --- replying to a communication (2026-08-06) --------------------------- */
/* What we have already said, above the box that would say something else.
   Ruled on the left so the thread reads as ours rather than as theirs: the
   claim above it is in the requester's words and these are in ours. */
.td-thread { margin: 10px 0 0; border-left: 3px solid #cfd8d0; padding-left: 10px; }
.td-thread-head { margin: 0 0 6px; font-family: var(--sans); font-size: 12px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-quiet); }
.td-reply { margin: 0 0 8px; }
.td-reply-line { margin: 0; }
.td-reply-body { margin: 2px 0 0; white-space: pre-wrap; }
.td-reply-meta { margin: 2px 0 0; font-family: var(--sans); font-size: 12px;
  color: var(--ink-quiet); display: flex; gap: 8px; align-items: baseline; }
/* Cleared: still legible, visibly not in force. Not hidden—what we told
   somebody and then withdrew is the part worth being able to find. */
.td-reply-cleared { opacity: .55; }
.td-reply-cleared .td-reply-line strong { text-decoration: line-through; }
.td-clear button { background: none; border: 0; padding: 0; font: inherit;
  color: var(--ink-quiet); text-decoration: underline; cursor: pointer; }
.td-clear button:hover { color: var(--gold); }

.td-reply-form { margin: 10px 0 0; }
.td-reply-form textarea { width: 100%; min-height: 4.5em; font: inherit; padding: 8px 10px;
  border: 1px solid #d8d2c6; border-radius: 3px; background: #fff; resize: vertical; }
.td-reply-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 6px; }
.td-canned { display: flex; flex-direction: column; gap: 3px; flex: 1 1 26em; min-width: 14em; }
.td-canned span { font-family: var(--sans); font-size: 12px; }
.td-canned select { font: inherit; padding: 6px 8px; border: 1px solid #d8d2c6;
  border-radius: 3px; background: #fff; max-width: 100%; }
.td-reply-hint { font-size: 12px; margin: 6px 0 0; }

/* The ownership check came back empty. Stated, not shouted: it is a fact the
   operator weighs, not an accusation, and the red button below is loud enough. */
.td-unproved { margin: 0 0 8px; padding: 8px 12px; background: #faf3e3;
  border-left: 3px solid var(--gold, #c08a30); font-size: 14px; }

/* The record note: quiet, and visibly not part of answering anybody. */
.td-note { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.td-note input[type="text"] { flex: 1 1 20em; min-width: 12em; }

/* A check that has stopped being a control. Still legible as "read", which is
   what it is now stating rather than offering. */
.td-corner button[disabled] { opacity: .6; cursor: default; }

/* The archived count. Its own line, hard right, so it reads as a way out of
   this list rather than as another message in it. */
.td-archived { display: block; text-align: right; margin: 18px 0 0;
  padding-top: 10px; border-top: 1px solid #e6e0d5; }

/* Stacked on a phone: the dropdown carries a whole sentence, so side-by-side
   with a button squeezes it to nothing. Narrower blocks come last. */
@media (max-width: 620px) {
  .td-reply-row { flex-direction: column; align-items: stretch; }
  .td-canned { flex: 1 1 auto; }
}

/* --- prose lists on the ported content pages (4.12) -------------------- */

/*
 * `needs-list` comes from the About mockup: a numbered list where each item is
 * a short heading and a sentence, so it needs room between items that an
 * ordinary <ol> does not give.
 */
.needs-list { padding-left: 22px; margin: 0; }
.needs-list > li { margin-bottom: 12px; padding-left: 4px; }
.needs-list > li:last-child { margin-bottom: 0; }

.plain-list { padding-left: 20px; margin: 0; }
.plain-list > li { margin-bottom: 9px; }
.plain-list > li:last-child { margin-bottom: 0; }

/*
 * The contributor chip is a link to the panel explaining it, so it needs to
 * read as one without becoming a button: underline on hover, and the same
 * colours it had as a static chip.
 */
a.tn-who { text-decoration: none; cursor: pointer; }
a.tn-who:hover { border-color: var(--gold); color: var(--gold); }

/* The kind badge does the same job for the review itself: a label that opens
   the thing it names. Filled navy, so hover lightens rather than recolours. */
a.tn-kind { text-decoration: none; cursor: pointer; }
a.tn-kind:hover { background: #24374d; }

/*
 * ‼ There is deliberately NO highlight where the chip's link lands. It had a
 *   gold ring, which was worse than useless — `:target` persists as long as the
 *   fragment sits in the address bar, so a cue meant to say "you have arrived"
 *   became a permanent border. Replacing it with a fade was still answering a
 *   question nobody asked: the browser scrolls you to the panel, which is the
 *   emphasis, and anything on top of that is decoration competing with the
 *   content it points at.
 */

/* --- a message from a person, on the submitter's page ------------------ */

/*
 * Distinct from every other panel on that page, because everything else there
 * was produced by the machinery and this was typed by somebody. Same tint as
 * the unverified notice, which carries the same meaning: read this, it is a
 * remark rather than a record.
 */
.op-note { background: #faf3e3; border: 1px solid #e6d9b8; }
.op-note-body { font-size: 16px; line-height: 1.65; white-space: pre-wrap; margin: 0 0 10px; }

/* The console's box for writing it. */
.note-form { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.note-form textarea {
  width: 100%; font-family: var(--serif); font-size: 15px; padding: 9px 11px;
  border: 1px solid #c9c2b4; border-radius: 3px; background: #fff; resize: vertical;
}

/* The front page's own styles are ported wholesale from the mockup and live in
   public/front.css, loaded only on that page. See the note at the top of it. */

/* --- search (2026-08-04) ----------------------------------------------- */

/*
 * From mockups-goal/index.html. On the navy hero the input is dark; the plain
 * variant sits inside an ordinary panel and takes paper colours instead.
 */
.hero-search { display: flex; max-width: 540px; gap: 8px; margin: 18px 0 0; }
.hero-search input {
  flex: 1 1 auto; min-width: 0; padding: 10px 14px; font-size: 15px;
  font-family: var(--sans); border: 1px solid #c9c2b4; border-radius: 4px; background: #fff;
}
.hero-search button { padding: 10px 20px; white-space: nowrap; }
.hero-search-plain { margin: 0; max-width: none; }

/* One result per line: a link, then what it is, quietly. */
.hits { list-style: none; padding: 0; margin: 0; }
.hits > li {
  padding: 9px 0; border-bottom: 1px solid #ece7de;
  display: flex; gap: 9px; align-items: baseline; flex-wrap: wrap;
}
.hits > li:last-child { border-bottom: 0; }
.hits > li > a:first-child { font-weight: 600; }

@media (max-width: 620px) {
  .hero-search { flex-direction: column; }
  .hero-search input, .hero-search button { width: 100%; }
}

/*
 * The scope beside a criterion name, where a heading can be linked to directly
 * and so has to carry its own context.
 *
 * ‼ It does NOT fight its parent. `.lede-name` uppercases and bolds everything
 *   inside it, so this only drops the weight and lets the rest inherit — the
 *   result is "OVERALL (LEDE)", which is what the label already looks like.
 *   Setting a different case or family here would produce one heading in two
 *   typefaces, which reads as a mistake rather than as a distinction.
 */
.scope-tag { font-weight: 400; opacity: .75; }

/*
 * The policy list. Numbered because a reply needs to be able to say "policy 2"
 * and be understood — by a complainant, by us, and by whoever reads the
 * exchange afterwards.
 */
.policies { margin: 0; padding-left: 24px; }
.policies > li { margin-bottom: 14px; padding-left: 4px; }
.policies > li:last-child { margin-bottom: 0; }
.policies .more { margin-top: 8px; }


/* ------------------------------------------------------------------ *
 * ‼ ON QUIET TEXT, because this went wrong repeatedly (2026-08-04).
 *
 * `.muted` means "secondary to what is beside it" — a timestamp, a source
 * domain, a count. It does NOT mean "prose the reader has to get through", and
 * it was being used for both.
 *
 * Three symptoms, all the same mistake: text a reader deliberately opened set
 * at 13.5px in grey; the sentence defining what a lede is set smaller than the
 * grades it explains; and a width cap written for a full-width panel left in
 * place inside a numbered list, so it wrapped at 60% of the space.
 *
 * The test before reaching for a quiet style: WOULD SOMEBODY BE ANNOYED TO MISS
 * THIS? If yes it is body text, whatever else is on the line. And never cap the
 * width of something already inside something narrower — a limit inside a limit
 * is how text ends up stopping halfway across an empty box.
 * ------------------------------------------------------------------ */

/*
 * Read and archive, in the corner of a message.
 *
 * Two marks rather than words: they are the actions taken most often and least
 * deliberately, and a row of buttons saying "Mark read" would compete with the
 * decisions below — which are the ones worth pausing over.
 */
.td { position: relative; }
.td-corner {
  position: absolute; top: 10px; right: 0; display: flex; gap: 4px;
}
.td-corner button {
  width: 26px; height: 26px; padding: 0; line-height: 1;
  background: transparent; border: 1px solid #d8d2c6; border-radius: 4px;
  color: var(--ink-quiet); font-size: 14px; cursor: pointer;
}
.td-corner button:hover { border-color: var(--gold); color: var(--gold); }
/* A ticked check means "read" — pressing it again marks unread. */
.td-corner button.on { background: #e4efe6; border-color: #b7d3bd; color: #2f6b42; }
.td-archived { opacity: .75; }
.td-archived .td-claim { font-size: 14px; }

/* --- pagination -------------------------------------------------------- */

/*
 * Shown only when there is more than one page. A pager under a list that fits
 * on one screen is furniture, and the count in the middle is the part that
 * matters: it is what stops a truncated list reading as a complete one.
 */
.pager {
  display: flex; align-items: center; gap: 16px; margin: 14px 0 0;
  font-family: var(--sans); font-size: 13px;
}
.pager a { text-decoration: none; font-weight: 600; }
.pager a:hover { text-decoration: underline; }
.pager-off { color: #b9b2a5; }
.pager-at { color: var(--ink-quiet); margin-left: auto; margin-right: auto; }

/* --- the console's tabs (2026-08-04) ----------------------------------- */

/*
 * Ordinary links, because they are: each one is a URL that can be sent to
 * somebody, survives a form POST, and works with scripts off. The count on each
 * is not decoration — a tab that does not say how much is behind it is a tab
 * nobody opens.
 */
.tabs {
  display: flex; flex-wrap: wrap; gap: 2px;
  border-bottom: 1px solid #d8d2c6; margin: -6px -8px 18px;
}
.tabs .tab {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 14px; margin-bottom: -1px;
  font-family: var(--sans); font-size: 13.5px; font-weight: 600;
  color: var(--ink-quiet); text-decoration: none;
  border: 1px solid transparent; border-bottom-color: #d8d2c6;
  border-radius: 5px 5px 0 0;
}
.tabs .tab:hover { color: var(--navy); background: #f0ece3; }
.tabs .tab.on {
  color: var(--navy); background: var(--paper-lift);
  border-color: #d8d2c6; border-bottom-color: var(--paper-lift);
}
.tab-n {
  font-size: 11px; font-weight: 700; color: var(--ink-quiet);
  background: #eae5db; border-radius: 9px; padding: 1px 7px;
}
/* Red only when something is unread: the one number that means "you". */
.tab-badge {
  font-size: 11px; font-weight: 700; color: #fff;
  background: #a4442e; border-radius: 9px; padding: 1px 7px;
}
.tab-body > h2:first-child { margin-top: 0; }

@media (max-width: 620px) {
  .tabs { margin-left: -4px; margin-right: -4px; }
  .tabs .tab { padding: 8px 10px; font-size: 12.5px; }
}

/*
 * The PolicyScanner table, in a sealed frame (C-01).
 *
 * Tall and scrolling internally: it is 500 rows, and a frame sized to its
 * content would make the page's own scrollbar meaningless.
 */
/*
 * The page's own container. `wide` pages skip `.wrap` entirely so their content
 * can run full width — which is right for the table and wrong for everything
 * above it, since the heading and the lede ended up flush against the window
 * edge. So: the same padding as `.wrap`, without its 860px ceiling. The frame
 * keeps nearly all of its width and the prose is set like every other page.
 */
.ps-page { padding: 40px 28px 64px; }

/* The scan options. Compact and quiet: they sit under a button that spends
 * money, so they must be readable at a glance without competing with it. */
.scan-opts {
  border: 1px solid #e0dacd; border-radius: 4px;
  margin: 12px 0 0; padding: 8px 12px 10px;
}
.scan-opts legend {
  font-family: var(--sans); font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--ink-quiet); padding: 0 4px;
}
.scan-opts label {
  display: block; font-family: var(--sans); font-size: 14px; line-height: 1.5;
  margin: 3px 0;
}
.scan-opts input { margin-right: 6px; }
.scan-opts-off legend, .scan-opts-off label { opacity: 0.45; }

/* The command preview. Mono, because it IS the command — a paraphrase here
 * would defeat the point of showing it. */
.scan-preview {
  margin: 12px 0 0; font-family: var(--sans); font-size: 13px; color: var(--ink-quiet);
}
.scan-preview code {
  display: inline-block; margin-left: 4px; padding: 3px 7px;
  background: #f2eee5; border: 1px solid #e0dacd; border-radius: 3px;
  font-size: 13px; color: var(--navy); word-break: break-all;
}
/* A run that did not end well. Gold-ruled rather than red: this is telling the
 * operator what happened, not warning of damage. */
.figure-warn {
  border-left: 3px solid var(--gold, #c08a30); padding-left: 10px; margin-left: -13px;
}

.scan-preview code.scan-command-bad { background: #fbeeee; border-color: #e2c4c4; color: #8a3232; }

/* What the last run cost. Ordinary body size on purpose: it is a fact to read,
 * not a banner. Colour carries only whether the run got where it was going. */
.run-cost { margin: 6px 0 0; font-weight: 700; }
.run-cost-ok { color: #3f6b4d; }
.run-cost-bad { color: #8a3232; }
.run-cost-unknown { margin: 6px 0 0; font-family: var(--sans); font-size: 13px; color: var(--ink-quiet); }

.ps-frame {
  width: 100%; height: 78vh; min-height: 420px;
  border: 1px solid #d8d2c6; border-radius: 4px; background: #fff;
}
/* Halved at 620px, matching `.wrap`; narrower blocks come last, as the order
 * rule requires, and sit beside the component rather than in a queries section. */
@media (max-width: 620px) {
  .ps-page { padding: 28px 14px 48px; }
  .ps-frame { height: 70vh; }
}

/* ---------------------------------------------------------------------
 * An X thread, shown as the several posts it is.
 *
 * A light rule between posts and very little padding: enough that a reader can
 * see where the platform's character limit fell, not so much that one argument
 * reads as nine. The first post has no rule above it — a line at the top of a
 * block is a border, not a seam.
 * --------------------------------------------------------------------- */
.tw-post + .tw-post {
  border-top: 1px solid #e8e4db;
  margin-top: 10px;
  padding-top: 10px;
}
.tw-post p:last-child { margin-bottom: 0; }

/* Said once, at the top of the review, because "this is a thread" changes how
   every seam below it should be read. */
.thread-note {
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-quiet);
  margin: 0 0 10px;
}
.thread-note .tn-count { font-weight: 700; color: var(--ink); }

/* Tabs INSIDE a panel — which supplier a spending figure belongs to. Smaller
   and quieter than the console's own tabs, because these choose a view of one
   panel rather than a page. Server-rendered like the rest: only the open one is
   queried. */
.subtabs { display: flex; gap: 4px; margin: 0 0 10px; }
.subtabs a {
  font-family: var(--sans); font-size: 12px; font-weight: 700; text-decoration: none;
  color: var(--ink-quiet); padding: 4px 10px; border: 1px solid #ddd6c8;
  border-radius: 3px; background: #f6f3ec;
}
.subtabs a:hover { color: var(--navy); border-color: #c9c0ae; }
.subtabs a.on { background: var(--navy); border-color: var(--navy); color: #fff; }

/* ---------------------------------------------------------------------
 * A block quotation inside a review — the house design.
 *
 * ‼ NOT A LEFT RULE. The first attempt used a gold bar down the left, which is
 *   exactly what the panel around it already has — so a quotation looked like a
 *   second panel starting inside the first, and the two rules ran parallel
 *   inches apart. Larry: *using the same left line for blockquotes as for the
 *   whole page is confusing. Should be quite different.*
 *
 *   Different, then: a tinted block, inset from both margins, with a large
 *   serif quotation mark hanging in the corner. Nothing on this site looks like
 *   that, which is the point — a reviewer quoting the article they are
 *   criticising must not be mistaken for saying it.
 *
 * Deliberately NOT italic. Georgia italic already means "a case under
 * discussion" here, and a long quotation set in it is hard going besides.
 * --------------------------------------------------------------------- */
.cc-text blockquote,
.rationale blockquote {
  position: relative;
  margin: 16px 0;
  padding: 14px 18px 14px 40px;
  background: #efece4;
  border: 1px solid #e2ded3;
  border-radius: 3px;
  color: #3f3b34;
}
.cc-text blockquote::before {
  content: '\201C';
  position: absolute;
  left: 11px;
  top: 2px;
  font-family: var(--serif);
  font-size: 34px;
  line-height: 1;
  color: #c9c0ae;
}
.cc-text blockquote p,
.rationale blockquote p { font-size: 15px; line-height: 1.6; margin: 0 0 8px; }
.cc-text blockquote p:last-child,
.rationale blockquote p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------
 * Footnotes, as the author's page had them and we had been flattening.
 *
 * A marker in the text was rendered "[1]" — an author's reference reduced to
 * punctuation mid-sentence — and the notes themselves were an ordinary bullet
 * list with an unclickable arrow at the end of each. They are now a superscript
 * that goes to its note, and a note that goes back.
 *
 * Set smaller and quieter than the argument, because that is what a note is:
 * available to the reader who wants it and out of the way of the one who does
 * not.
 * --------------------------------------------------------------------- */
.cc-text .fn { font-size: 10.5px; line-height: 0; vertical-align: super; }
.cc-text .fn a { text-decoration: none; font-weight: 700; }
.cc-text .fn a:hover { text-decoration: underline; }
.cc-text ol.footnotes {
  margin: 10px 0 0; padding: 12px 0 0 22px;
  border-top: 1px solid #e2ded3;
  font-size: 13.5px; line-height: 1.6; color: var(--ink-quiet);
}
.cc-text ol.footnotes li { margin: 0 0 6px; }
.cc-text ol.footnotes li:last-child { margin-bottom: 0; }
/* ‼ A real link, where the author's page had a glyph we could not follow. */
.cc-text .fn-back { text-decoration: none; color: #948c80; }
.cc-text .fn-back:hover { color: var(--gold); }
/* Landing on a note should say which one you landed on, and stop saying it. */
.cc-text ol.footnotes li:target { background: #f7f3e8; }

/* A heading the author wrote, inside their review. One weight for every level:
   a review sits inside a page with its own hierarchy and must not outrank it. */
.cc-head {
  font-family: var(--sans); font-weight: 700; font-size: 13px;
  letter-spacing: .03em; text-transform: uppercase; color: var(--ink-quiet);
  margin: 18px 0 6px;
}

@media (max-width: 620px) {
  .cc-text blockquote { padding: 12px 12px 12px 32px; margin: 12px 0; }
  .cc-text blockquote::before { font-size: 28px; left: 8px; }
}

/* ---------------------------------------------------------------------
 * THE SUBJECT'S OWN ANSWER, from `mockups-goal/dossier-schiff.html`.
 *
 * ‼ Not a card in a list of cards. On a biography, the person written about
 *   answering is a different kind of thing from a stranger's review, and giving
 *   it the same treatment says it is one more opinion among them. Gold, boxed,
 *   and above everything.
 *
 * The badge in the mockup reads VERIFIED because its example is verified. Ours
 * reads whatever `class_basis` actually holds, which today is always a claim —
 * a gold box asserting VERIFIED over an identity nobody checked would be the
 * most confident lie on the site.
 * --------------------------------------------------------------------- */
.subject-box {
  background: var(--paper-lift, #f8f6f1); border: 2px solid var(--gold);
  border-radius: 6px; overflow: hidden; margin: 0 0 28px;
}
.subject-header {
  background: var(--gold); color: #fff; padding: 12px 20px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-family: var(--sans); font-size: 13px; font-weight: 700;
}
.subject-header .sh-badge {
  background: rgba(255, 255, 255, .25); font-size: 9px; padding: 2px 8px;
  border-radius: 3px; font-weight: 700; letter-spacing: .06em;
}
.subject-body { padding: 20px; }
.subject-top {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 10px; flex-wrap: wrap; margin-bottom: 12px;
}
.subject-top > div:first-child { flex: 1 1 60%; min-width: 0; }
.subject-name { font-family: var(--sans); font-weight: 700; font-size: 16px; }
.subject-name a { color: var(--ink); text-decoration: none; }
.subject-name a:hover { color: var(--navy); text-decoration: underline; }
.subject-who { font-family: var(--sans); font-size: 12px; color: var(--ink-quiet); margin-top: 2px; }
.subject-meta {
  font-family: var(--sans); font-size: 12px; color: var(--ink-quiet);
  margin-bottom: 14px; line-height: 1.7;
}
.subject-foot { margin-top: 12px; font-family: var(--sans); font-size: 13px; font-weight: 700; }
@media (max-width: 620px) {
  .subject-header { padding: 9px 12px; }
  .subject-body { padding: 12px; }
}
/* ---------------------------------------------------------------------
 * Preparing a comment: /prepare and /d/<token>.
 *
 * ‼ `.hint` is defined here and nowhere before it. It arrived from the mockups,
 *   where every page carries its own styles, and until these pages it was used
 *   by nothing the app served — so a rule here changes only what it dresses.
 *
 * ‼ The article-lookup styles duplicate what `submit-page.js` keeps inline, and
 *   that duplication is deliberate: /submit is given the CHROME sheet only, so
 *   a rule written here would load on every page except the one it applied to.
 *   That mistake has already been made once and is recorded there. Two copies,
 *   two audiences.
 * --------------------------------------------------------------------- */

.hint {
  font-family: var(--sans); font-size: 13px; line-height: 1.6;
  color: var(--ink-quiet); margin: 0 0 12px;
}
.panel .hint:last-child { margin-bottom: 0; }

/* --- choosing which kind you are writing ------------------------------ */

/*
 * ‼ TWO CARDS, NOT A TAB STRIP, and the reason is a design constraint rather
 *   than taste (Larry, 2026-08-08): a tab above a long form is read as
 *   decoration. Somebody arriving to report a block would scroll past a strip,
 *   meet seven grade selects, and conclude we only want reviews. Both kinds are
 *   named in full, with what each is for, before anything else on the page.
 */
.prep-pick-h {
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--ink-quiet);
  margin: 0 0 10px;
}
.prep-pick { display: flex; gap: 14px; margin: 0 0 22px; align-items: stretch; }
.pick {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 6px;
  padding: 16px 18px; border: 1px solid #d8d2c6; border-radius: 5px;
  background: var(--paper-lift); text-decoration: none; color: var(--ink);
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.pick:hover { border-color: var(--gold); background: #fffdf8; box-shadow: 0 2px 6px rgba(0,0,0,.07); }
.pick.on {
  background: var(--navy); border-color: var(--navy); color: #fff;
  box-shadow: inset 4px 0 0 var(--gold);
}
.pick.on:hover { background: var(--navy-lift); }
.pick-k { font-family: var(--serif); font-size: 21px; line-height: 1.2; }
.pick.on .pick-k { color: #fff; }
.pick-d { font-family: var(--sans); font-size: 13px; line-height: 1.55; color: var(--ink-quiet); }
.pick.on .pick-d { color: #cdd6e0; }
/* The affordance: the card you are not on says, in as many words, that it is a
   thing to press. The one you are on says which one you are on. */
.pick-s {
  margin-top: auto; padding-top: 8px;
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--gold-ink);
}
.pick.on .pick-s { color: rgba(255,255,255,.6); }

/* --- the form --------------------------------------------------------- */

.prep-lab {
  display: block; font-family: var(--sans); font-size: 13px; font-weight: 700;
  color: var(--navy); margin: 14px 0 4px;
}
.prep-lab:first-child { margin-top: 0; }
/*
 * ‼ MARK THE FEW, NOT THE MANY. Almost every field here is optional, and a form
 *   that writes "optional" beside twenty of them has written a word twenty times
 *   and told nobody anything. The two that are not optional carry `.req`; the
 *   handful of whole sections that are carry `.prep-opt` once, on the heading,
 *   rather than once per input.
 */
.prep-opt {
  font-family: var(--sans); font-size: 11px; font-weight: 400;
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-quiet);
  vertical-align: middle;
}
.req {
  display: inline-block; vertical-align: middle;
  font-family: var(--sans); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em;
  color: #fff; background: var(--gold); padding: 3px 7px; border-radius: 3px;
  margin-left: 4px;
}
.hint .req { margin: 0 1px; }
.prep-in, .prep-area {
  display: block; width: 100%; box-sizing: border-box; padding: 9px 11px;
  font-family: inherit; font-size: 15px; color: var(--ink); background: #fff;
  border: 1px solid #cfc8bc; border-radius: 4px;
}
.prep-in { max-width: 520px; font-family: var(--sans); font-size: 14px; }
.prep-area { line-height: 1.6; resize: vertical; }
.prep-area-sm { font-family: var(--sans); font-size: 13.5px; }
.prep-in:focus, .prep-area:focus {
  outline: 2px solid var(--gold); outline-offset: 1px; border-color: var(--gold);
}

.prep-checks { list-style: none; margin: 0; padding: 0; }
.prep-checks li { margin: 0 0 10px; }
.prep-checks label { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
.prep-checks input { margin: 3px 0 0; flex: none; }
.prep-checks .tn { flex: none; }
.prep-note { font-family: var(--sans); font-size: 13px; color: var(--ink-quiet); line-height: 1.5; }

/* --- the grade chooser, in four states -------------------------------- *
 *
 * ‼ A ROW OF LETTERS IS A SCALE; A DROPDOWN IS A LIST. Thirteen grades behind a
 *   <select> is thirteen options nobody opens, and it hides the one thing the
 *   letters are for — you cannot see that A− sits two steps above B without
 *   opening it. The radio itself is visually hidden but present, so keyboard
 *   and screen-reader behaviour is the browser's own.
 *
 * ‼ FOUR STATES FROM ONE ANSWER, AND NO JAVASCRIPT. `grade_mode` is a single
 *   radio group of four inside `.grading`, and `:has()` reads which is checked.
 *   The layout and the output are driven by the same field, so they cannot
 *   disagree — and everything stays posted whichever is chosen, so changing
 *   your mind loses nothing.
 *
 * ‼ TWO ROWS, GROUPED BY LETTER (Larry, 2026-08-09): A and B on the first row,
 *   C, D and F on the second. Seven columns; the seventh chip — C+ — is placed
 *   explicitly at the start of row two and the rest flow after it, which is the
 *   whole of the arithmetic.
 */

.gr-modes { border: none; margin: 0 0 20px; padding: 0; }
.gr-modes legend {
  padding: 0 0 8px; font-family: var(--sans); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-quiet);
}
.gr-modes-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.gr-mode { cursor: pointer; }
.gr-mode input {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}
.gr-mode > span {
  display: block; height: 100%; box-sizing: border-box; padding: 11px 13px;
  background: #fff; border: 1px solid #d8d2c6; border-radius: 5px;
  transition: background .1s, border-color .1s;
}
.gr-mode:hover > span { border-color: var(--gold); background: #fffdf8; }
.gr-mode input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }
.gr-mode input:checked + span {
  background: var(--navy); border-color: var(--navy); box-shadow: inset 3px 0 0 var(--gold);
}
.gr-mode-a {
  display: block; font-family: var(--sans); font-size: 13px; font-weight: 700;
  color: var(--navy); line-height: 1.35;
}
.gr-mode-b {
  display: block; margin-top: 3px;
  font-family: var(--sans); font-size: 12px; color: var(--ink-quiet); line-height: 1.35;
}
.gr-mode input:checked + span .gr-mode-a { color: #fff; }
.gr-mode input:checked + span .gr-mode-b { color: #cdd6e0; }

/* ── The four layouts ─────────────────────────────────────────────────── *
 *
 * ‼ OVERALL IS ALWAYS ALONE, full width, above the rest (Larry, 2026-08-09):
 *   it is a summary judgement rather than one of the criteria, and taking it
 *   out is also what makes the grid arithmetic work — six criteria fill 3×2 and
 *   2×3 exactly, where seven fill neither.
 *
 *   1 whole-body   3 columns × 2 rows, picker NARROW (3 across, 5 down)
 *                  ↓ ≤1000px   2 columns × 3 rows, picker WIDE
 *                  ↓ ≤620px    1 column, picker WIDE
 *   2 whole-here   2 columns × 3 rows, picker WIDE, a Why box per cell
 *                  ↓ ≤760px    1 column, Why box full width
 *   3 lede-body    1 criterion per row, two scope columns, picker WIDE
 *   4 lede-here    as 3, with a Why box under each scope
 *
 * ‼ NARROW AND WIDE ARE THE SAME MARKUP. One list of thirteen chips in one DOM
 *   order; only `grid-template-columns` and the two `grid-row` pins differ. A
 *   second set of markup would be a second thing to keep in step.
 */

.gr-list { display: block; }
.gr-solo { padding-bottom: 18px; margin-bottom: 18px; border-bottom: 1px solid #ded8cc; }
.gr-six { display: grid; grid-template-columns: 1fr; gap: 0 32px; }
.gr { border: none; margin: 0 0 18px; padding: 0 0 16px; border-bottom: 1px solid #ebe8e1; }
.gr-solo .gr, .gr-six .gr:last-of-type { border-bottom: none; padding-bottom: 0; }
.gr-solo .gr { margin-bottom: 0; }
.gr-name {
  padding: 0; font-family: var(--sans); font-size: 15px; font-weight: 700; color: var(--navy);
}
.gr-solo .gr-name { font-size: 17px; }
.gr-name .prep-gloss { display: block; margin-top: 1px; }

.gr-scopes { display: flex; gap: 30px; margin-top: 8px; align-items: flex-start; }
.gr-scope { flex: 1 1 0; min-width: 0; }
.gr-scope-h {
  display: none; font-family: var(--sans); font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-quiet);
  margin-bottom: 5px;
}
/* What a lede IS, beside the label rather than in a disclosure: it is the one
   word on this panel a reader may simply not know. */
.gr-scope-n { font-weight: 400; text-transform: none; letter-spacing: 0; }
/* Hidden until there is a second scope to tell it apart from. */
.gr-scope-lede { display: none; }

/* ── The picker ───────────────────────────────────────────────────────── */

/* WIDE is the default, because three of the four modes use it. */
.gr-grid { display: grid; grid-template-columns: repeat(7, 34px); gap: 3px; width: max-content; }
/*
 * ‼ BOTH ROWS ARE STATED, not just the break. Pinning only the seventh chip
 *   left a hole at the end of row 1, and grid's default placement is "sparse" —
 *   it backfilled the hole with the EIGHTH chip, so the rows came out
 *   `A+ A A− B+ B B− C` and `C+ C− D+ D D− F`.
 */
/* ‼ `:not(.gr-none)` on every one of these. `.gr-none` carries `.gr-chip` as
   well, so it was being caught by the row pins and landing in the middle of the
   scale — in the wide arrangement it took row 2 and pushed C, D and F down a
   row; in the narrow one it took row 4 and sat on top of F. A rule that means
   "the letters" has to say so. */
.gr-grid > .gr-chip:not(.gr-none):nth-of-type(-n+6) { grid-row: 1; }
.gr-grid > .gr-chip:not(.gr-none):nth-of-type(n+7) { grid-row: 2; }
/* Wide: its own row underneath, which is where it has always been. */
.gr-grid > .gr-none { grid-row: 3; }

.gr-chip { cursor: pointer; }
.gr-chip input {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.gr-chip span {
  display: block; padding: 7px 4px; text-align: center;
  font-family: var(--sans); font-size: 13px; font-weight: 700; line-height: 1;
  color: var(--ink-quiet); background: #fff;
  border: 1px solid #d8d2c6; border-radius: 4px;
  transition: background .1s, color .1s, border-color .1s;
}
.gr-chip:hover span { border-color: var(--gold); color: var(--gold-ink); }
.gr-chip input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }
.gr-chip input:checked + span { color: #fff; border-color: transparent; }
/* Green through red, so the block reads as a scale before it is read as letters. */
.gr-chip.g-a input:checked + span { background: #3f7a4e; }
.gr-chip.g-b input:checked + span { background: #5c8a4a; }
.gr-chip.g-c input:checked + span { background: #b58a2b; }
.gr-chip.g-d input:checked + span { background: #b86a2a; }
.gr-chip.g-f input:checked + span { background: #a5402f; }
/*
 * ‼ `not graded` LIVES IN THE GRID. In the wide arrangement it takes a row of
 *   its own underneath, which is where it has always sat. In the narrow one it
 *   fills the column the A and B rows leave empty — two lines, hard against the
 *   chips, which is a good deal of white space reclaimed for nothing.
 */
.gr-none { grid-column: 1 / -1; justify-self: start; margin-top: 1px; }
.gr-none span { padding: 5px 9px; font-weight: 400; font-style: italic; font-size: 12px; }
.gr-none input:checked + span { background: #6b6355; font-style: normal; }

/* ── The reason boxes ─────────────────────────────────────────────────── */

.gr-why { display: none; margin-top: 10px; }
.gr-why .prep-lab { margin-top: 0; font-size: 12px; }

/*
 * ‼ "not graded" GREYS OUT ITS OWN Why box, and only its own — the scope is the
 *   unit, so leaving the article ungraded must not disable the lede's reason.
 *   Non-interactive as well as pale, because a box that looks disabled and
 *   accepts typing is worse than either. Nothing is lost by it: `lines()`
 *   prints a reason only where there is a grade to hang it on, so text left
 *   behind by a change of mind was never going to appear anyway.
 */
.gr-scope:has(.gr-none input:checked) .gr-why { opacity: .45; }
.gr-scope:has(.gr-none input:checked) .gr-why textarea {
  pointer-events: none; background: #f2efe8;
}

/* Reasons here — the whole-article box in every mode, the lede's only when the
   lede is being graded. Written on the PANEL because `:has()` looks down from
   where it is attached, and the switch is not inside the fieldset it governs. */
.grading:has(#mode-whole-here:checked) .gr-scope:not(.gr-scope-lede) .gr-why,
.grading:has(#mode-lede-here:checked) .gr-why { display: block; }

/* ── 1. whole-body: three columns, narrow picker ──────────────────────── *
 *
 * ‼ FOUR COLUMNS, NOT THREE, so F sits beside the D's (Larry, 2026-08-09). One
 *   letter alone on a fifth row read as an afterthought, and F is not an
 *   afterthought — it is the bottom of the scale. Only the D row uses the
 *   fourth column; the rest of the grid is three wide and the empty cells cost
 *   nothing.
 *
 *      A+  A  A−
 *      B+  B  B−
 *      C+  C  C−
 *      D+  D  D−  F
 *
 * Every row is pinned, because grid's default placement is "sparse" and would
 * happily pull a chip up into a gap it found.
 */
.grading:has(#mode-whole-body:checked) .gr-six { grid-template-columns: 1fr 1fr 1fr; }
.grading:has(#mode-whole-body:checked) .gr-six .gr-grid {
  grid-template-columns: repeat(4, 34px);
}
.grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:not(.gr-none):nth-of-type(-n+3) {
  grid-row: 1;
}
.grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:not(.gr-none):nth-of-type(n+4):nth-of-type(-n+6) {
  grid-row: 2;
}
.grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:not(.gr-none):nth-of-type(n+7):nth-of-type(-n+9) {
  grid-row: 3;
}
.grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:not(.gr-none):nth-of-type(n+10) {
  grid-row: 4;
}
/* The empty cell beside the A and B rows is exactly where this belongs. */
.grading:has(#mode-whole-body:checked) .gr-six .gr-none {
  grid-column: 4; grid-row: 1 / span 2; margin-top: 0; align-self: stretch;
}
.grading:has(#mode-whole-body:checked) .gr-six .gr-none span {
  height: 100%; box-sizing: border-box; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 4px 5px; font-size: 10.5px; line-height: 1.2; white-space: normal;
}

/* ── 2. whole-here: two columns, wide picker, a Why box per cell ──────── */
.grading:has(#mode-whole-here:checked) .gr-six { grid-template-columns: 1fr 1fr; }

/* ── 3 and 4. the lede alongside ──────────────────────────────────────── */
.grading:has(#mode-lede-body:checked) .gr-scope-lede,
.grading:has(#mode-lede-here:checked) .gr-scope-lede { display: block; }
.grading:has(#mode-lede-body:checked) .gr-scope-h,
.grading:has(#mode-lede-here:checked) .gr-scope-h { display: block; }

/* ── Breakpoints ──────────────────────────────────────────────────────── *
 *
 * ‼ Narrower LATER, which is the rule that bites: two blocks that both apply at
 *   some width and touch the same selector are resolved by order, not by which
 *   is more specific.
 */
@media (max-width: 1000px) {
  /* Three columns of criteria stop fitting; the picker goes wide with them. */
  .grading:has(#mode-whole-body:checked) .gr-six { grid-template-columns: 1fr 1fr; }
  .grading:has(#mode-whole-body:checked) .gr-six .gr-grid {
    grid-template-columns: repeat(7, 34px);
  }
  .grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:nth-of-type(-n+6) {
    grid-row: 1;
  }
  .grading:has(#mode-whole-body:checked) .gr-six .gr-grid > .gr-chip:nth-of-type(n+7) {
    grid-row: 2;
  }
}

@media (max-width: 760px) {
  /* A reason box needs the whole width before a picker does. */
  .grading:has(#mode-whole-here:checked) .gr-six { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  .grading:has(#mode-whole-body:checked) .gr-six { grid-template-columns: 1fr; }
}

/* --- the article lookup, on this page only ---------------------------- */

.wc-title-lookup { margin: 0; }
.wc-title-results {
  max-width: 520px; margin-top: 4px; border: 1px solid #cfc8bc; border-radius: 4px;
  background: #fff; overflow: hidden;
}
.wc-title-hit {
  display: block; width: 100%; text-align: left; padding: 7px 11px;
  font-family: var(--sans); font-size: 13.5px; color: var(--ink);
  background: none; border: none; border-bottom: 1px solid #ece8e0; cursor: pointer;
}
.wc-title-hit:last-child { border-bottom: none; }
.wc-title-hit:hover, .wc-title-hit:focus-visible { background: #f4f1ea; color: var(--navy); }
.wc-title-status {
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-quiet);
  margin-top: 5px; min-height: 1.2em;
}

/* --- the prepared comment -------------------------------------------- */

.draft-head { display: flex; gap: 8px; align-items: center; margin: 0 0 8px; flex-wrap: wrap; }
.draft-out {
  margin: 0; padding: 14px 16px; background: #fff; border: 1px solid #d8d2c6;
  border-radius: 4px; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px; line-height: 1.65; color: var(--ink);
}
.draft-post { margin: 0 0 14px; }
.draft-post:last-child { margin-bottom: 0; }
.draft-post-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 5px;
  font-family: var(--sans); font-size: 12px; font-weight: 700; color: var(--navy);
}
.draft-count { font-weight: 400; color: var(--ink-quiet); }

.copy-btn, .dl-btn {
  font-family: var(--sans); font-size: 12px; font-weight: 700; line-height: 1;
  padding: 7px 13px; border-radius: 4px; cursor: pointer; text-decoration: none;
  border: 1px solid #cfc8bc; background: #fff; color: var(--navy);
}
.copy-btn:hover, .dl-btn:hover { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.copy-btn:focus-visible, .dl-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.copy-btn.copied { background: var(--green); border-color: var(--green); color: #fff; }
.dl-btn { display: inline-block; }

@media (max-width: 620px) {
  .prep-pick { flex-direction: column; gap: 10px; }
  .pick { padding: 13px 14px; }
  .pick-k { font-size: 19px; }
  .prep-in, .wc-title-results, .prep-go .hint { max-width: none; }
  .gr-modes-row { grid-template-columns: 1fr; }
  /* The two scopes stack rather than squeeze: seven columns of chips is the
     narrowest the picker goes, and two of them abreast is not a phone. */
  .gr-scopes { flex-direction: column; gap: 18px; }
  .gr-grid, .grading:has(#mode-whole-body:checked) .gr-six .gr-grid {
    grid-template-columns: repeat(7, 30px);
  }
  .gr-chip span { padding: 7px 3px; font-size: 12px; }
}

/* --- guidance, which is most of what this form is --------------------- */

/*
 * ‼ A form field with a label and nothing else gets left blank. Every optional
 *   field here changes how a comment is weighted or read, so each carries what
 *   it is asking (`.prep-help`, above the box) and what an answer looks like
 *   (`.prep-eg`, below it, and quieter — an example must never be mistakable for
 *   a value already entered).
 */
/* ‼ The field and its label share one width, so the +/− buttons land at the
   right edge of the BOX rather than at the right edge of the panel — which is
   where they were, a hand's breadth away from the thing they resize. */
.prep-field { margin: 0 0 18px; max-width: 520px; }
.prep-field:last-of-type { margin-bottom: 0; }
.prep-help {
  font-family: var(--sans); font-size: 13px; line-height: 1.55;
  color: var(--ink-quiet); margin: 0 0 6px; max-width: 640px;
}
.prep-eg {
  display: block; margin-top: 4px; max-width: 640px;
  font-family: var(--sans); font-size: 12px; font-style: italic; color: #8a8171;
}
.prep-keep { margin-top: -14px; }
.prep-gloss {
  display: block; font-weight: 400; font-size: 12px; font-style: italic;
  color: var(--ink-quiet); margin-top: 1px;
}
.panel-how ol.prep-steps { margin: 0 0 10px; padding-left: 22px; }
.prep-steps li { font-size: 15px; line-height: 1.6; margin: 0 0 8px; }
.prep-steps li:last-child { margin-bottom: 0; }

/*
 * ‼ `.lit` — the mockups' treatment for a literal you type verbatim: mono, bold,
 *   gold, always shown with its colon. `submit-comment.html` spends this class
 *   for exactly this job, and `/prepare` now quotes that page's instructions, so
 *   the two must look the same. One visual meaning for "type this exactly"; the
 *   block form of it is `.why-quote`.
 */
.lit {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700; color: var(--gold-ink);
}

@media (max-width: 620px) {
  .prep-help, .prep-eg { max-width: none; }
  .prep-steps li { font-size: 14.5px; }
}

/*
 * ‼ TEMPORARY — delete with `app/demo-answers.js`. The testing button on
 *   /prepare. It is not an action anybody visiting the site should want and it
 *   must not read as a second way to submit — but it is going to be here a
 *   while, so it sits on the same baseline and at the same height as the two
 *   real buttons beside it rather than looking like something half-finished.
 *
 * Same 1.2 line-height and vertical padding as `.prep-main`, so all three
 * buttons in the row are the same height without a flex stretch doing it — the
 * stretch disappears the moment the row stacks.
 */
.prep-demo {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--sans); font-size: 13px; font-weight: 700; line-height: 1.2;
  padding: 12px 16px; border-radius: 4px; cursor: pointer;
  background: none; border: 1px dashed #b9b1a2; color: var(--ink-quiet);
}
.prep-demo:hover { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.prep-demo:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* The warning tag, sized as a chip rather than as shouted words in the label. */
.prep-demo span {
  font-size: 9.5px; font-weight: 700; line-height: 1;
  text-transform: uppercase; letter-spacing: .07em;
  color: #fff; background: #a8340f; padding: 4px 6px; border-radius: 3px;
}
@media (max-width: 620px) {
  .prep-demo { display: flex; justify-content: center; margin: 0; width: 100%; }
}

/* --- the trimmed field guidance --------------------------------------- */

/*
 * ‼ ONE LINE UNDER THE LABEL, AND IT OPENS (Larry, 2026-08-10). Six fields each
 *   carrying a paragraph was the wordiness he objected to first; collecting all
 *   seven paragraphs into one block at the top of the panel — headed "What each
 *   of these is for" — was the poor answer he objected to second, because it put
 *   the explanation nowhere near the field it explains.
 *
 *   So the one line under each label IS the summary of that field's own
 *   disclosure. Closed, the panel reads exactly as it did; open, the reader has
 *   the paragraph for the box they are looking at and no others. It has to stay
 *   as quiet as the line it replaces, so it keeps that line's size and colour
 *   and takes the triangle in front of it.
 */
/* The same quiet line where it is NOT a disclosure — a label's subtitle with
   nothing behind it to open. */
.prep-short {
  display: block; margin-top: 2px;
  font-family: var(--sans); font-size: 12.5px; font-weight: 400;
  color: var(--ink-quiet);
}
.prep-why { margin: 2px 0 6px; }
.prep-why > summary {
  font-family: var(--sans); font-size: 12.5px; font-weight: 400; color: var(--ink-quiet);
}
.prep-why > p {
  margin: 6px 0 0; font-family: var(--sans); font-size: 13px; line-height: 1.55;
  color: var(--ink-quiet); max-width: 46em;
}

/* --- the rendered HTML on a prepared comment --------------------------- */

/*
 * ‼ A CHECKBOX, NOT A SCRIPT, and the markup it reveals was built by us. The
 *   source and the rendering are both on the page; `:has()` shows one and hides
 *   the other. What is rendered has been through `sanitiseHtml`, which allows
 *   a handful of tags and no attributes — the second lock on a door `asHtml`
 *   already closed by escaping everything a person typed.
 *
 * ‼ AND THE SELECTOR HANGS OFF `.panel`, NOT `.out-pair`. It was written as
 *   `.out-pair:has(.out-show input:checked)` and matched nothing, ever: the
 *   checkbox lives in `.draft-head`, which is the pair's SIBLING. `:has()` only
 *   looks DOWN from where it is attached, so the common ancestor is the only
 *   place the selector can live — and the button did nothing at all for a day
 *   because a selector that matches nothing fails exactly as quietly as a
 *   selector that is correct.
 */
.out-show { display: flex; align-items: center; gap: 7px; cursor: pointer; }
.out-show input {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}
.out-show span {
  font-family: var(--sans); font-size: 12px; font-weight: 700; line-height: 1;
  padding: 7px 13px; border-radius: 4px;
  border: 1px solid #cfc8bc; background: #fff; color: var(--navy);
}
.out-show:hover span { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.out-show input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }
.out-show input:checked + span { background: var(--navy); border-color: var(--navy); color: #fff; }

.out-rendered { display: none; }
.panel:has(.out-show input:checked) .out-rendered { display: block; }
.panel:has(.out-show input:checked) .out-pair .draft-out { display: none; }
/* The label names the view you are LOOKING AT, so it changes with the state. */
.out-show .show-b { display: none; }
.panel:has(.out-show input:checked) .out-show .show-a { display: none; }
.panel:has(.out-show input:checked) .out-show .show-b { display: inline; }
.out-rendered {
  padding: 16px 18px; background: #fff; border: 1px solid #d8d2c6; border-radius: 4px;
  font-family: var(--serif); font-size: 15px; line-height: 1.65; color: var(--ink);
}
.out-rendered p { margin: 0 0 12px; }
.out-rendered p:last-child { margin-bottom: 0; }

/* --- clearing the form, and getting back to it ------------------------ */

/*
 * ‼ RED, AND NOT BESIDE THE BUTTON IT MUST NOT BE MISTAKEN FOR. `Clear form`
 *   destroys work; `Prepare my review` is what everybody came for. They sit in
 *   the same row, so the difference has to be carried by colour and position
 *   rather than by reading — the destructive one is pushed to the far end.
 */
.prep-clear {
  margin-left: auto; font-family: var(--sans); font-size: 13px; font-weight: 700;
  line-height: 1.2; padding: 12px 18px; border-radius: 4px; cursor: pointer;
  background: #a5402f; border: 1px solid #a5402f; color: #fff;
}
.prep-clear:hover { background: #8c3627; border-color: #8c3627; }
.prep-clear:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/*
 * ‼ THE BUTTON THIS PAGE IS FOR, and it went unstyled for a day. Its rules were
 *   written as `.prep-go button`, which swept up the sample-answers and
 *   Clear-form buttons beside it — an element in the selector scores (0,1,1)
 *   against a bare class's (0,1,0), so both of those were quietly given this
 *   one's 15px type and 26px padding while their own rules were ignored. The
 *   whole block was then lost in a later rewrite of this section, and nothing
 *   said so: an unstyled `<button>` still renders, still submits, and looks
 *   merely plain. A rule that dresses ONE button says which one.
 */
.prep-go { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 22px 0 8px; }
.prep-go .hint { flex-basis: 100%; margin: 4px 0 0; max-width: 620px; }
.prep-main {
  font-family: var(--sans); font-size: 15px; font-weight: 700; line-height: 1.2;
  /* Its own vertical padding: a flex parent that stretches it disappears when
     the row stacks on a phone. */
  padding: 12px 26px; border: 1px solid transparent; border-radius: 4px;
  /* Green: the site's own, and the one button on the page that DOES something
     rather than changing what is shown. */
  background: var(--green); color: #fff; cursor: pointer;
}
.prep-main:hover { background: #3d6949; }
.prep-main:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/*
 * ‼ The deletion notice is a promise with a deadline in it, not a caveat. Its
 *   own panel, gold-edged like every other, and the DATE rather than "in a
 *   week" — a duration has to be counted from something a reader has to
 *   remember.
 */
.panel-gone { border-left-color: #a5402f; }
.panel-gone strong { color: #8c3627; }
.hint-inline {
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-quiet);
}

.draft-back { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.draft-back button { cursor: pointer; font-family: var(--sans); }
.draft-fresh { font-family: var(--sans); font-size: 13px; color: var(--ink-quiet); }

@media (max-width: 620px) {
  .prep-clear { margin-left: 0; width: 100%; }
  .prep-main { width: 100%; }
}

/* --- the little formatting toolbar ------------------------------------ */

/*
 * ‼ Built by `md-editor.js`, so none of this renders if the script does not
 *   run — which is the point. A toolbar that is drawn and inert is worse than
 *   no toolbar, and the textarea below it works either way.
 */
.md-bar {
  display: flex; align-items: center; gap: 4px; margin: 0 0 6px; flex-wrap: wrap;
}
.md-btn {
  min-width: 30px; padding: 5px 8px; cursor: pointer; line-height: 1;
  background: #fff; border: 1px solid #d8d2c6; border-radius: 4px;
  font-family: var(--serif); font-size: 14px; color: var(--navy);
}
.md-bold { font-weight: 700; }
.md-italic { font-style: italic; }
.md-h2 { font-weight: 700; font-size: 15px; }
.md-h3 { font-weight: 700; font-size: 12px; }
.md-btn:hover { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.md-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.md-note {
  margin-left: 6px; font-family: var(--sans); font-size: 12px; color: var(--ink-quiet);
}
@media (max-width: 620px) { .md-note { flex-basis: 100%; margin: 4px 0 0; } }

/* --- growing a writing box -------------------------------------------- */

/*
 * ‼ Built by `textarea-size.js`, so none of this renders if the script does not
 *   run. The buttons sit in the label rather than beside the box: the label is
 *   the one line that is always directly above it, whatever the box's width.
 */
.ta-size { float: right; display: inline-flex; gap: 3px; margin: -2px 0 0 10px; }
.ta-btn {
  width: 22px; height: 20px; padding: 0; line-height: 1; cursor: pointer;
  font-family: var(--sans); font-size: 14px; font-weight: 700;
  color: var(--ink-quiet); background: #fff;
  border: 1px solid #d8d2c6; border-radius: 3px;
}
.ta-btn:hover { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.ta-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* The label carries a float, so it has to contain it or the box rides up. */
.prep-lab { overflow: hidden; }

/* --- the rubric, behind a "?" on each criterion ------------------------ */

/*
 * ‼ THE DESCRIPTORS ARE PARSED FROM `submit-comment.html`, never retyped: they
 *   are the same text the AI is graded against, and a second copy would be the
 *   first thing to rot. `llm/rubric.js` does the reading.
 *
 * ‼ AN OVERLAY, NOT A DISCLOSURE IN THE FLOW. Seven <details> opening inline
 *   would shove the whole grid about every time somebody checked what a B
 *   means. This one is taken out of flow, so it covers its neighbours and puts
 *   them back on close — and it is still a native <details>, needing no script.
 */
.gr-name { position: relative; }
.rub { display: inline; margin: 0; }
.rub > summary {
  display: inline-block; list-style: none; cursor: pointer;
  width: 1.25em; height: 1.25em; line-height: 1.25em; text-align: center;
  border: 1px solid #c9c2b4; border-radius: 50%; color: #6b6355;
  font-family: var(--sans); font-size: 11px; font-weight: 400;
  vertical-align: baseline; margin-left: 4px;
}
.rub > summary::-webkit-details-marker { display: none; }
.rub > summary:hover { border-color: var(--gold); color: var(--gold); }
.rub[open] > summary { background: var(--navy); border-color: var(--navy); color: #fff; }

.rub-pop {
  position: absolute; z-index: 40; top: 1.9em; left: 0;
  width: min(420px, 78vw); max-height: 60vh; overflow-y: auto;
  padding: 14px 16px; text-align: left;
  background: #fff; border: 1px solid #c9c2b4; border-left: 3px solid var(--gold);
  border-radius: 5px; box-shadow: 0 6px 20px rgba(0, 0, 0, .16);
}
.rub-head {
  margin: 0 0 8px; font-family: var(--sans); font-size: 13px; font-weight: 700;
  color: var(--navy);
}
.rub-head span {
  display: block; font-weight: 400; font-style: italic; font-size: 12px;
  color: var(--ink-quiet); margin-top: 1px;
}
.rub-pop dl { display: grid; grid-template-columns: 26px 1fr; gap: 7px 10px; margin: 0; }
.rub-pop dt {
  font-family: var(--sans); font-size: 12px; font-weight: 700; line-height: 1.4;
  text-align: center; color: #fff; border-radius: 3px; height: 20px;
}
.rub-pop dt.g-a { background: #3f7a4e; }
.rub-pop dt.g-b { background: #5c8a4a; }
.rub-pop dt.g-c { background: #b58a2b; }
.rub-pop dt.g-d { background: #b86a2a; }
.rub-pop dt.g-f { background: #a5402f; }
.rub-pop dd {
  margin: 0; font-family: var(--sans); font-size: 12.5px; line-height: 1.5;
  color: var(--ink);
}
@media (max-width: 620px) {
  .rub-pop { left: auto; right: 0; width: min(420px, 88vw); }
}

/*
 * ‼ A ONE-LINE BOX THAT CAN GROW. The reviewer fields are textareas so the +/−
 *   buttons work on them, and are dressed as inputs because that is what they
 *   are: one value, one line in the finished comment. `lines()` folds any
 *   newline out of the value, so what a taller box buys is seeing your own
 *   sentence, not writing a paragraph.
 */
textarea.prep-line {
  min-height: 0; resize: vertical; overflow-y: auto;
  line-height: 1.45; padding-top: 9px; padding-bottom: 9px;
}

/* --- the top of a prepared comment ------------------------------------ */

/*
 * ‼ IT USED TO BE THREE PANELS OF EXPLANATION before the first usable thing on
 *   the page (Larry, 2026-08-10: "People just want to get what they came for,
 *   they don't need a lecture"). One line, a row of formats to jump to, the
 *   deadline beside them, and the argument behind a "?".
 */
.draft-hero { margin-bottom: 14px; }
.draft-why { margin: 0 0 22px; }

.fmt-jump {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 8px; padding: 10px 12px;
  background: var(--paper-lift); border: 1px solid #ddd7cb; border-radius: 6px;
}
.fmt-jump a {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border-radius: 4px; text-decoration: none;
  font-family: var(--sans); font-size: 13px; font-weight: 700; line-height: 1;
  color: var(--navy); background: #fff; border: 1px solid #d8d2c6;
  transition: border-color .1s, background .1s, color .1s;
}
.fmt-jump a:hover { border-color: var(--gold); color: var(--gold-ink); background: #fffdf8; }
.fmt-jump a:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/*
 * ‼ THE DEADLINE IS AN INSTRUCTION, not a status line. It sat at the end of the
 *   format row, greyed, reading "Deleted Aug 17" — the voice of a footnote for
 *   the one thing on this page somebody can lose work by missing. It now says
 *   what to do, then when, in red, directly above the buttons it concerns.
 */
.draft-now {
  margin: 0 0 8px; font-family: var(--sans); font-size: 14px; font-weight: 700;
  color: #a5402f;
}
.draft-now time { white-space: nowrap; }

.draft-steps { margin: 8px 0 10px; padding-left: 22px; }
.draft-steps li {
  font-family: var(--sans); font-size: 13.5px; line-height: 1.6; margin: 0 0 5px;
}

/* A jumped-to panel should not sit flush against the top of the window. */
.panel[id^="f-"] { scroll-margin-top: 60px; }

@media (max-width: 620px) {
  .fmt-jump { gap: 6px; padding: 9px; }
  .fmt-jump a { padding: 7px 10px; font-size: 12.5px; }
}

/*
 * ‼ EVERYTHING INSIDE A DISCLOSURE IS PROSE (Larry, 2026-08-10: "the different
 *   comments have different fonts. I'm surprised this doesn't have a house
 *   style"). There is one — Georgia for prose, the sans stack for UI chrome —
 *   and `.more` had been falling on both sides of it: paragraphs inherited the
 *   serif from the body while every list and hint inside the same block set
 *   itself in sans, so two disclosures a line apart were in different faces.
 *
 *   A disclosure is an argument somebody chose to open. Its summary is chrome —
 *   it is a control — and everything it reveals is prose. That is the rule, and
 *   stating it here is what stops the next component drifting the other way.
 */
.more > summary { font-family: var(--sans); }
.more p,
.more li,
.more dd,
.more dt {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
}
.more dt { font-weight: 700; color: var(--navy); }
.more dd { color: var(--ink-quiet); }
/* A closing aside inside a disclosure is still that disclosure's prose. */
.more .hint { font-family: var(--serif); font-size: 14px; color: var(--ink-quiet); }


/* ---- the standalone build's own chrome ---- */

/*
 * ‼ THE TOP BAR IS `header.js`, the same one every page in `mockups-goal/` uses,
 *   with its menu turned off — so there is nothing here dressing a wordmark of
 *   its own. What this file adds is the container and the closing note; the rest
 *   comes from `chrome.css` and `wikicritic.css` unchanged, which is why the
 *   form looks like the one on the site rather than like a copy of it.
 */
body.standalone { background: var(--paper); color: var(--ink); margin: 0; }

body.standalone main.wrap { max-width: 940px; margin: 0 auto; padding: 28px 24px 60px; }

/* Both kinds are in the document; one is hidden. The block includes the
   heading, which is why it is the block and not the form that is hidden. */
.sa-kind[hidden] { display: none; }

.out-panel { border-left-color: var(--green); }
.out-panel > h2 { font-size: 24px; }

/*
 * ‼ The one thing this page asks for. Gold-edged, like a panel, because it is
 *   an invitation rather than a footnote — and directly under the note that
 *   says nothing here is sent anywhere, which is the sentence it answers.
 */
.sa-ask {
  margin: 18px 0 0; padding: 14px 16px;
  background: var(--paper-lift); border: 1px solid #ddd7cb; border-left: 3px solid var(--gold);
  border-radius: 5px;
  font-family: var(--sans); font-size: 13.5px; line-height: 1.65; color: var(--ink);
}
.sa-ask a { color: var(--gold-ink); font-weight: 700; }

.sa-foot {
  margin: 40px 0 0; padding-top: 18px; border-top: 1px solid #d8d2c6;
  font-family: var(--sans); font-size: 13px; line-height: 1.65; color: var(--ink-quiet);
}

@media (max-width: 620px) {
  .sa-wrap { padding: 11px 14px; }
  body.standalone main.wrap { padding: 18px 14px 44px; }
}
